eclass/cargo.eclass: specify --path . to install
[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 # @ECLASS-VARIABLE: CARGO_INSTALL_PATH
38 # @DESCRIPTION:
39 # Allows overriding the default cwd to run cargo install from
40 : ${CARGO_INSTALL_PATH:=.}
41
42 # @FUNCTION: cargo_crate_uris
43 # @DESCRIPTION:
44 # Generates the URIs to put in SRC_URI to help fetch dependencies.
45 cargo_crate_uris() {
46         local crate
47         for crate in "$@"; do
48                 local name version url pretag
49                 name="${crate%-*}"
50                 version="${crate##*-}"
51                 pretag="^[a-zA-Z]+"
52                 if [[ $version =~ $pretag ]]; then
53                         version="${name##*-}-${version}"
54                         name="${name%-*}"
55                 fi
56                 url="https://crates.io/api/v1/crates/${name}/${version}/download -> ${crate}.crate"
57                 echo "${url}"
58         done
59 }
60
61 # @FUNCTION: cargo_src_unpack
62 # @DESCRIPTION:
63 # Unpacks the package and the cargo registry
64 cargo_src_unpack() {
65         debug-print-function ${FUNCNAME} "$@"
66
67         mkdir -p "${ECARGO_VENDOR}" || die
68         mkdir -p "${S}" || die
69
70         local archive shasum pkg
71         for archive in ${A}; do
72                 case "${archive}" in
73                         *.crate)
74                                 ebegin "Loading ${archive} into Cargo registry"
75                                 tar -xf "${DISTDIR}"/${archive} -C "${ECARGO_VENDOR}/" || die
76                                 # generate sha256sum of the crate itself as cargo needs this
77                                 shasum=$(sha256sum "${DISTDIR}"/${archive} | cut -d ' ' -f 1)
78                                 pkg=$(basename ${archive} .crate)
79                                 cat <<- EOF > ${ECARGO_VENDOR}/${pkg}/.cargo-checksum.json
80                                 {
81                                         "package": "${shasum}",
82                                         "files": {}
83                                 }
84                                 EOF
85                                 # if this is our target package we need it in ${WORKDIR} too
86                                 # to make ${S} (and handle any revisions too)
87                                 if [[ ${P} == ${pkg}* ]]; then
88                                         tar -xf "${DISTDIR}"/${archive} -C "${WORKDIR}" || die
89                                 fi
90                                 eend $?
91                                 ;;
92                         cargo-snapshot*)
93                                 ebegin "Unpacking ${archive}"
94                                 mkdir -p "${S}"/target/snapshot
95                                 tar -xzf "${DISTDIR}"/${archive} -C "${S}"/target/snapshot --strip-components 2 || die
96                                 # cargo's makefile needs this otherwise it will try to
97                                 # download it
98                                 touch "${S}"/target/snapshot/bin/cargo || die
99                                 eend $?
100                                 ;;
101                         *)
102                                 unpack ${archive}
103                                 ;;
104                 esac
105         done
106
107         cargo_gen_config
108 }
109
110 # @FUNCTION: cargo_live_src_unpack
111 # @DESCRIPTION:
112 # Runs 'cargo fetch' and vendors downloaded crates for offline use, used in live ebuilds
113
114 cargo_live_src_unpack() {
115         debug-print-function ${FUNCNAME} "$@"
116
117         [[ "${PV}" == *9999* ]] || die "${FUNCNAME} only allowed in live/9999 ebuilds"
118         [[ "${EBUILD_PHASE}" == unpack ]] || die "${FUNCNAME} only allowed in src_unpack"
119
120         mkdir -p "${S}" || die
121
122         pushd "${S}" > /dev/null || die
123         CARGO_HOME="${ECARGO_HOME}" cargo fetch || die
124         CARGO_HOME="${ECARGO_HOME}" cargo vendor "${ECARGO_VENDOR}" || die
125         popd > /dev/null || die
126
127         cargo_gen_config
128 }
129
130 # @FUNCTION: cargo_gen_config
131 # @DESCRIPTION:
132 # Generate the $CARGO_HOME/config necessary to use our local registry
133 cargo_gen_config() {
134         debug-print-function ${FUNCNAME} "$@"
135
136         cat <<- EOF > "${ECARGO_HOME}/config"
137         [source.gentoo]
138         directory = "${ECARGO_VENDOR}"
139
140         [source.crates-io]
141         replace-with = "gentoo"
142         local-registry = "/nonexistant"
143         EOF
144 }
145
146 # @FUNCTION: cargo_src_compile
147 # @DESCRIPTION:
148 # Build the package using cargo build
149 cargo_src_compile() {
150         debug-print-function ${FUNCNAME} "$@"
151
152         export CARGO_HOME="${ECARGO_HOME}"
153
154         cargo build -vv -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
155                 || die "cargo build failed"
156 }
157
158 # @FUNCTION: cargo_src_install
159 # @DESCRIPTION:
160 # Installs the binaries generated by cargo
161 cargo_src_install() {
162         debug-print-function ${FUNCNAME} "$@"
163
164         cargo install -vv -j $(makeopts_jobs) --path ${CARGO_INSTALL_PATH} \
165                 --root="${ED}/usr" $(usex debug --debug "") "$@" \
166                 || die "cargo install failed"
167         rm -f "${ED}/usr/.crates.toml"
168
169         [ -d "${S}/man" ] && doman "${S}/man" || return 0
170 }
171
172 # @FUNCTION: cargo_src_test
173 # @DESCRIPTION:
174 # Test the package using cargo test
175 cargo_src_test() {
176         debug-print-function ${FUNCNAME} "$@"
177
178         cargo test -vv -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
179                 || die "cargo test failed"
180 }
181
182 fi