cargo.eclass: fix cargo_src_install() on prefix
[gentoo.git] / eclass / cargo.eclass
1 # Copyright 1999-2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: cargo.eclass
5 # @MAINTAINER:
6 # rust@gentoo.org
7 # @AUTHOR:
8 # Doug Goldstein <cardoe@gentoo.org>
9 # @SUPPORTED_EAPIS: 6 7
10 # @BLURB: common functions and variables for cargo builds
11
12 if [[ -z ${_CARGO_ECLASS} ]]; then
13 _CARGO_ECLASS=1
14
15 if [[ ${PV} == *9999* ]]; then
16         # we need at least this for cargo vendor subommand
17         CARGO_DEPEND=">=virtual/cargo-1.37.0"
18 else
19         CARGO_DEPEND="virtual/cargo"
20 fi
21
22 case ${EAPI} in
23         6) DEPEND="${CARGO_DEPEND}";;
24         7) BDEPEND="${CARGO_DEPEND}";;
25         *) die "EAPI=${EAPI:-0} is not supported" ;;
26 esac
27
28 inherit multiprocessing
29
30 EXPORT_FUNCTIONS src_unpack src_compile src_install src_test
31
32 IUSE="${IUSE} debug"
33
34 ECARGO_HOME="${WORKDIR}/cargo_home"
35 ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
36
37 # @FUNCTION: cargo_crate_uris
38 # @DESCRIPTION:
39 # Generates the URIs to put in SRC_URI to help fetch dependencies.
40 cargo_crate_uris() {
41         local crate
42         for crate in "$@"; do
43                 local name version url pretag
44                 name="${crate%-*}"
45                 version="${crate##*-}"
46                 pretag="^[a-zA-Z]+"
47                 if [[ $version =~ $pretag ]]; then
48                         version="${name##*-}-${version}"
49                         name="${name%-*}"
50                 fi
51                 url="https://crates.io/api/v1/crates/${name}/${version}/download -> ${crate}.crate"
52                 echo "${url}"
53         done
54 }
55
56 # @FUNCTION: cargo_src_unpack
57 # @DESCRIPTION:
58 # Unpacks the package and the cargo registry
59 cargo_src_unpack() {
60         debug-print-function ${FUNCNAME} "$@"
61
62         mkdir -p "${ECARGO_VENDOR}" || die
63         mkdir -p "${S}" || die
64
65         local archive shasum pkg
66         for archive in ${A}; do
67                 case "${archive}" in
68                         *.crate)
69                                 ebegin "Loading ${archive} into Cargo registry"
70                                 tar -xf "${DISTDIR}"/${archive} -C "${ECARGO_VENDOR}/" || die
71                                 # generate sha256sum of the crate itself as cargo needs this
72                                 shasum=$(sha256sum "${DISTDIR}"/${archive} | cut -d ' ' -f 1)
73                                 pkg=$(basename ${archive} .crate)
74                                 cat <<- EOF > ${ECARGO_VENDOR}/${pkg}/.cargo-checksum.json
75                                 {
76                                         "package": "${shasum}",
77                                         "files": {}
78                                 }
79                                 EOF
80                                 # if this is our target package we need it in ${WORKDIR} too
81                                 # to make ${S} (and handle any revisions too)
82                                 if [[ ${P} == ${pkg}* ]]; then
83                                         tar -xf "${DISTDIR}"/${archive} -C "${WORKDIR}" || die
84                                 fi
85                                 eend $?
86                                 ;;
87                         cargo-snapshot*)
88                                 ebegin "Unpacking ${archive}"
89                                 mkdir -p "${S}"/target/snapshot
90                                 tar -xzf "${DISTDIR}"/${archive} -C "${S}"/target/snapshot --strip-components 2 || die
91                                 # cargo's makefile needs this otherwise it will try to
92                                 # download it
93                                 touch "${S}"/target/snapshot/bin/cargo || die
94                                 eend $?
95                                 ;;
96                         *)
97                                 unpack ${archive}
98                                 ;;
99                 esac
100         done
101
102         cargo_gen_config
103 }
104
105 # @FUNCTION: cargo_live_src_unpack
106 # @DESCRIPTION:
107 # Runs 'cargo fetch' and vendors downloaded crates for offline use, used in live ebuilds
108
109 cargo_live_src_unpack() {
110         debug-print-function ${FUNCNAME} "$@"
111
112         [[ "${PV}" == *9999* ]] || die "${FUNCNAME} only allowed in live/9999 ebuilds"
113         [[ "${EBUILD_PHASE}" == unpack ]] || die "${FUNCNAME} only allowed in src_unpack"
114
115         mkdir -p "${S}" || die
116
117         pushd "${S}" > /dev/null || die
118         CARGO_HOME="${ECARGO_HOME}" cargo fetch || die
119         CARGO_HOME="${ECARGO_HOME}" cargo vendor "${ECARGO_VENDOR}" || die
120         popd > /dev/null || die
121
122         cargo_gen_config
123 }
124
125 # @FUNCTION: cargo_gen_config
126 # @DESCRIPTION:
127 # Generate the $CARGO_HOME/config necessary to use our local registry
128 cargo_gen_config() {
129         debug-print-function ${FUNCNAME} "$@"
130
131         cat <<- EOF > "${ECARGO_HOME}/config"
132         [source.gentoo]
133         directory = "${ECARGO_VENDOR}"
134
135         [source.crates-io]
136         replace-with = "gentoo"
137         local-registry = "/nonexistant"
138         EOF
139 }
140
141 # @FUNCTION: cargo_src_compile
142 # @DESCRIPTION:
143 # Build the package using cargo build
144 cargo_src_compile() {
145         debug-print-function ${FUNCNAME} "$@"
146
147         export CARGO_HOME="${ECARGO_HOME}"
148
149         cargo build -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
150                 || die "cargo build failed"
151 }
152
153 # @FUNCTION: cargo_src_install
154 # @DESCRIPTION:
155 # Installs the binaries generated by cargo
156 cargo_src_install() {
157         debug-print-function ${FUNCNAME} "$@"
158
159         cargo install -j $(makeopts_jobs) --root="${ED}/usr" $(usex debug --debug "") "$@" \
160                 || die "cargo install failed"
161         rm -f "${ED}/usr/.crates.toml"
162
163         [ -d "${S}/man" ] && doman "${S}/man" || return 0
164 }
165
166 # @FUNCTION: cargo_src_test
167 # @DESCRIPTION:
168 # Test the package using cargo test
169 cargo_src_test() {
170         debug-print-function ${FUNCNAME} "$@"
171
172         cargo test -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
173                 || die "cargo test failed"
174 }
175
176 fi