2022-01-12 09:48:49 +01:00
|
|
|
{ lib, stdenv
|
|
|
|
, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI
|
|
|
|
}:
|
|
|
|
|
2018-09-06 15:03:13 +02:00
|
|
|
{ crateName,
|
|
|
|
dependencies,
|
2019-09-08 08:18:09 +02:00
|
|
|
crateFeatures, crateRenames, libName, release, libPath,
|
2018-10-28 01:06:29 +02:00
|
|
|
crateType, metadata, crateBin, hasCrateBin,
|
2019-12-12 13:55:04 +01:00
|
|
|
extraRustcOpts, verbose, colors,
|
2021-10-12 02:25:08 +02:00
|
|
|
buildTests,
|
|
|
|
codegenUnits
|
2019-12-12 13:55:04 +01:00
|
|
|
}:
|
2018-09-06 15:03:13 +02:00
|
|
|
|
|
|
|
let
|
2019-12-12 13:55:04 +01:00
|
|
|
baseRustcOpts =
|
2021-03-25 16:52:17 +01:00
|
|
|
[
|
|
|
|
(if release then "-C opt-level=3" else "-C debuginfo=2")
|
2022-04-30 04:05:17 +02:00
|
|
|
"-C codegen-units=${toString codegenUnits}"
|
2021-03-25 16:52:17 +01:00
|
|
|
"--remap-path-prefix=$NIX_BUILD_TOP=/"
|
|
|
|
(mkRustcDepArgs dependencies crateRenames)
|
|
|
|
(mkRustcFeatureArgs crateFeatures)
|
2021-06-30 17:49:15 +02:00
|
|
|
] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
|
lib.systems: elaborate Rust metadata
We need this stuff to be available in lib so make-derivation.nix can
access it to construct the Meson cross file.
This has a couple of other advantages:
- It makes Rust less special. Now figuring out what Rust calls a
platform is the same as figuring out what Linux or QEMU call it.
- We can unify the schema used to define Rust targets, and the schema
used to access those values later. Just like you can set "config"
or "system" in a platform definition, and then access those same
keys on the elaborated platform, you can now set "rustcTarget" in
your crossSystem, and then access "stdenv.hostPlatform.rustcTarget"
in your code.
"rustcTarget", "rustcTargetSpec", "cargoShortTarget", and
"cargoEnvVarTarget" have the "rustc" and "cargo" prefixes because
these are not exposed to code by the compiler, and are not
standardized. The arch/os/etc. variables are all named to match the
forms in the Rust target spec JSON.
The new rust.target-family only takes a list, since we don't need to
worry about backwards compatibility when that name is used.
The old APIs are all still functional with no warning for now, so that
it's possible for external code to use a single API on both 23.05 and
23.11. We can introduce the warnings once 23.05 is EOL, and make them
hard errors when 23.11 is EOL.
2023-05-09 15:38:32 +02:00
|
|
|
"--target" stdenv.hostPlatform.rust.rustcTargetSpec
|
2022-01-12 09:48:49 +01:00
|
|
|
] ++ lib.optionals (needUnstableCLI dependencies) [
|
|
|
|
"-Z" "unstable-options"
|
2021-03-25 16:52:17 +01:00
|
|
|
] ++ extraRustcOpts
|
2020-03-17 16:33:13 +01:00
|
|
|
# since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
|
|
|
|
# https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022
|
|
|
|
++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro"
|
2019-12-12 13:55:04 +01:00
|
|
|
;
|
2019-02-18 00:10:36 +01:00
|
|
|
rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}";
|
2018-09-06 15:03:13 +02:00
|
|
|
|
|
|
|
|
2019-12-12 13:55:04 +01:00
|
|
|
# build the final rustc arguments that can be different between different
|
|
|
|
# crates
|
|
|
|
libRustcOpts = lib.concatStringsSep " " (
|
|
|
|
baseRustcOpts
|
|
|
|
++ [rustcMeta]
|
|
|
|
++ (map (x: "--crate-type ${x}") crateType)
|
|
|
|
);
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-12 13:55:04 +01:00
|
|
|
binRustcOpts = lib.concatStringsSep " " (
|
build-rust-crate: point rustc to the correct linker
I've been having problems with cross-compiled builds of crate2nix'ed
crates failing at the final link step because rustc defaults to `cc`
(from $PATH) as the linker. This is, of course, the buildPlatform's
linker. See example below.
Let's tell rustc unambiguously to use the target platform linker.
I've added the flag *before* `baseRustcOpts` because that includes
`extraRustcOpts`. This ensures that users of the package can
override this with their own `-C linker` choice.
Unfortunately because build-rust-crate (currently) sets
binary-crate-specific flags when building library crates, this
causes a global rebuild of everything that uses buildRustCrate.
```
rust_html2text> Building html2text (src/main.rs)
rust_html2text> Running rustc --crate-name html2text src/main.rs --crate-type bin -C opt-level=3 -C codegen-units=1 --remap-path-prefix=/build=/ --extern argparse=/nix/store/y4m00swv4aka73vfl9rbb2abq7y1vmg6-rust_argparse-0.2.2-aarch64-unknown-linux-gnu-lib/lib/libargparse-5dc9592bf7.rlib --extern html2text=/nix/store/j3p1pgh3iyjdhp8681zab7yjwpzs4kg2-rust_html2text-0.4.4-aarch64-unknown-linux-gnu-lib/lib/libhtml2text-d6e376dd78.rlib --cfg feature="default" --target aarch64-unknown-linux-gnu --edition 2021 --out-dir target/bin -L dependency=target/deps --cap-lints allow --color always
rust_html2text> error: linking with `cc` failed: exit status: 1
rust_html2text> |
rust_html2text> = note: "cc" "/build/rustcgg6BNC/symbols.o" "target/bin/html2text.html2text.a6551786-cgu.0.rcgu.o" "target/bin/html2text.82b4749yb02lf9k.rcgu.o" "-Wl,--as-needed" "-L" "target/deps" "-L" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/nix/store/j3p1pgh3iyjdhp8681zab7yjwpzs4kg2-rust_html2text-0.4.4-aarch64-unknown-linux-gnu-lib/lib/libhtml2text-d6e376dd78.rlib" "/nix/store/rbal9imr15fb674mwjjhd75p45ajql25-rust_unicode-width-0.1.10-aarch64-unknown-linux-gnu-lib/lib/libunicode_width-a3b8f6ce6d.rlib" "/nix/store/5j6pf8bbk3920klpn2zlv4q6d0bbjk26-rust_html5ever-0.26.0-aarch64-unknown-linux-gnu-lib/lib/libhtml5ever-7c514c0d78.rlib" "/nix/store/2k5ncqkn1ngq1q7mjccsh3di2r9x7b3m-rust_log-0.4.17-aarch64-unknown-linux-gnu-lib/lib/liblog-bbb1d2abad.rlib" "/nix/store/yklfi1k7iaw4khbay1avvgmrrnb3sw8f-rust_markup5ever-0.11.0-aarch64-unknown-linux-gnu-lib/lib/libmarkup5ever-fa92c5d6d6.rlib" "/nix/store/cp0raar4bvl551n7521rrvk8cka9dkcv-rust_string_cache-0.8.4-aarch64-unknown-linux-gnu-lib/lib/libstring_cache-3ae24c7e2e.rlib" "/nix/store/w45v78l58wcpnwrhf83ysix1nb3177d3-rust_precomputed-hash-0.1.1-aarch64-unknown-linux-gnu-lib/lib/libprecomputed_hash-dc2ae88c2c.rlib" "/nix/store/d5gv2frk6aav6y9hwv0w6a8fw3wd2sh3-rust_serde-1.0.152-aarch64-unknown-linux-gnu-lib/lib/libserde-881972cdc0.rlib" "/nix/store/zapn48k4pfma65s304xfpqakprl0lz0n-rust_parking_lot-0.12.1-aarch64-unknown-linux-gnu-lib/lib/libparking_lot-a8eeb0af3b.rlib" "/nix/store/5jjayhj13mcy52ybdagvmdqvp2i2kfc6-rust_parking_lot_core-0.9.5-aarch64-unknown-linux-gnu-lib/lib/libparking_lot_core-7b731df3c6.rlib" "/nix/store/nka1dv01my0ivfpv14jc3969lala9yj0-rust_libc-0.2.139-aarch64-unknown-linux-gnu-lib/lib/liblibc-7a4e291ec8.rlib" "/nix/store/40i3315py200bzjd9nzds6l73drfs5rq-rust_cfg-if-1.0.0-aarch64-unknown-linux-gnu-lib/lib/libcfg_if-36a232ac81.rlib" "/nix/store/mj38xbiskkz39gdwm6sg4xr73k3wiixh-rust_smallvec-1.10.0-aarch64-unknown-linux-gnu-lib/lib/libsmallvec-e668ae4802.rlib" "/nix/store/j15ldgxp88dz06cgfl6ksvbnhk5kg1l7-rust_lock_api-0.4.9-aarch64-unknown-linux-gnu-lib/lib/liblock_api-bd3f4cafbe.rlib" "/nix/store/w7f8q6idl5pl7hssfq0gn2h7nr33556g-rust_scopeguard-1.1.0-aarch64-unknown-linux-gnu-lib/lib/libscopeguard-2ef121592d.rlib" "/nix/store/4vsr3kifpdb1dkac5j2l9rafjsypcdj6-rust_once_cell-1.17.0-aarch64-unknown-linux-gnu-lib/lib/libonce_cell-8a9caa1812.rlib" "/nix/store/sivn38f9bffq7pwiwhrisbpk16slci51-rust_phf-0.10.1-aarch64-unknown-linux-gnu-lib/lib/libphf-c5c68bbc03.rlib" "/nix/store/dfl1c90pddaf9kqpdpmy546s21vmgy90-rust_phf_shared-0.10.0-aarch64-unknown-linux-gnu-lib/lib/libphf_shared-0da64f265f.rlib" "/nix/store/vcq3zp2l7bjldknvg3894nvmafndl4p3-rust_siphasher-0.3.10-aarch64-unknown-linux-gnu-lib/lib/libsiphasher-57560c9ade.rlib" "/nix/store/ysycp6rj77l0ymdrvcndpdykidyhjapd-rust_tendril-0.4.3-aarch64-unknown-linux-gnu-lib/lib/libtendril-c7a013fefe.rlib" "/nix/store/fgc3j0s0rlpmgi4avy0gvkcwx813v74v-rust_utf-8-0.7.6-aarch64-unknown-linux-gnu-lib/lib/libutf8-a31a1dfa96.rlib" "/nix/store/vkqy90dmg0h4qkmcfr8nfa8l8nv3b0wa-rust_futf-0.1.5-aarch64-unknown-linux-gnu-lib/lib/libfutf-74eb51f206.rlib" "/nix/store/lpy11ncw9hjp8514y6qh5dalz73cammg-rust_new_debug_unreachable-1.0.4-aarch64-unknown-linux-gnu-lib/lib/libdebug_unreachable-798bc09edd.rlib" "/nix/store/972pbraa9nx2w2r9rgw9ihxcnnyjj7pq-rust_mac-0.1.1-aarch64-unknown-linux-gnu-lib/lib/libmac-5f22857ac1.rlib" "/nix/store/y4m00swv4aka73vfl9rbb2abq7y1vmg6-rust_argparse-0.2.2-aarch64-unknown-linux-gnu-lib/lib/libargparse-5dc9592bf7.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd-6dfb26da5641245c.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libpanic_unwind-17fe203b55bc0ad4.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libobject-fcd32571c597d1d2.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libmemchr-9bea2c040bb6c3bb.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libaddr2line-50f1168d6595a5a4.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libgimli-ab3cce9cf22eb54e.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_demangle-195cb4e110dfcf64.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd_detect-6e60da103a3086ca.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libhashbrown-1967902c6f47ed4d.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libminiz_oxide-e67a9163a25e7f3e.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libadler-3815f9058309549d.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-761ef9e339906fe9.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libunwind-8882f6e2dc28b312.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcfg_if-50cea0e51cd18705.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/liblibc-da1cdc1aff291994.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/liballoc-7019f3ab0cdf1cfd.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_core-1944b99f47799b69.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcore-06b1d7727c68137a.rlib" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcompiler_builtins-bc101476bec73dcf.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/nix/store/bhx7z81c5w1d7b1qny9s198mkqzj6a1r-rustc-1.67.0/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-o" "target/bin/html2text" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-Wl,-O1" "-nodefaultlibs"
rust_html2text> = note: /nix/store/2arn2lz66q49qhiyldkahiphfmzlixdf-binutils-2.40/bin/ld: target/bin/html2text.html2text.a6551786-cgu.0.rcgu.o: Relocations in generic ELF (EM: 183)
rust_html2text> /nix/store/2arn2lz66q49qhiyldkahiphfmzlixdf-binutils-2.40/bin/ld: target/bin/html2text.html2text.a6551786-cgu.0.rcgu.o: Relocations in generic ELF (EM: 183)
rust_html2text> /nix/store/2arn2lz66q49qhiyldkahiphfmzlixdf-binutils-2.40/bin/ld: target/bin/html2text.html2text.a6551786-cgu.0.rcgu.o: Relocations in generic ELF (EM: 183)
rust_html2text> /nix/store/2arn2lz66q49qhiyldkahiphfmzlixdf-binutils-2.40/bin/ld: target/bin/html2text.html2text.a6551786-cgu.0.rcgu.o: Relocations in generic ELF (EM: 183)
```
2023-03-10 04:38:28 +01:00
|
|
|
[ "-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc" ] ++
|
2019-12-12 13:55:04 +01:00
|
|
|
baseRustcOpts
|
|
|
|
);
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-17 21:15:53 +01:00
|
|
|
build_bin = if buildTests then "build_bin_test" else "build_bin";
|
2019-12-12 13:55:04 +01:00
|
|
|
in ''
|
|
|
|
runHook preBuild
|
2020-08-09 09:47:12 +02:00
|
|
|
|
2019-12-12 13:55:04 +01:00
|
|
|
# configure & source common build functions
|
|
|
|
LIB_RUSTC_OPTS="${libRustcOpts}"
|
|
|
|
BIN_RUSTC_OPTS="${binRustcOpts}"
|
2024-01-04 12:14:17 +01:00
|
|
|
LIB_EXT="${stdenv.hostPlatform.extensions.sharedLibrary or ""}"
|
2019-12-12 13:55:04 +01:00
|
|
|
LIB_PATH="${libPath}"
|
|
|
|
LIB_NAME="${libName}"
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-12 00:06:22 +01:00
|
|
|
CRATE_NAME='${lib.replaceStrings ["-"] ["_"] libName}'
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-12 13:55:04 +01:00
|
|
|
setup_link_paths
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-12 13:55:04 +01:00
|
|
|
if [[ -e "$LIB_PATH" ]]; then
|
2019-12-17 21:15:53 +01:00
|
|
|
build_lib "$LIB_PATH"
|
|
|
|
${lib.optionalString buildTests ''build_lib_test "$LIB_PATH"''}
|
2018-09-06 15:03:13 +02:00
|
|
|
elif [[ -e src/lib.rs ]]; then
|
|
|
|
build_lib src/lib.rs
|
2019-12-17 21:15:53 +01:00
|
|
|
${lib.optionalString buildTests "build_lib_test src/lib.rs"}
|
2018-09-06 15:03:13 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
2019-12-17 21:15:53 +01:00
|
|
|
|
2022-08-23 13:09:33 +02:00
|
|
|
${lib.optionalString (lib.length crateBin > 0) (lib.concatMapStringsSep "\n" (bin:
|
|
|
|
let
|
|
|
|
haveRequiredFeature = if bin ? requiredFeatures then
|
|
|
|
# Check that all element in requiredFeatures are also present in crateFeatures
|
|
|
|
lib.intersectLists bin.requiredFeatures crateFeatures == bin.requiredFeatures
|
|
|
|
else
|
|
|
|
true;
|
|
|
|
in
|
|
|
|
if haveRequiredFeature then ''
|
2019-12-12 00:06:22 +01:00
|
|
|
mkdir -p target/bin
|
|
|
|
BIN_NAME='${bin.name or crateName}'
|
|
|
|
${if !bin ? path then ''
|
2019-12-12 13:55:04 +01:00
|
|
|
BIN_PATH=""
|
|
|
|
search_for_bin_path "$BIN_NAME"
|
2019-12-12 00:06:22 +01:00
|
|
|
'' else ''
|
|
|
|
BIN_PATH='${bin.path}'
|
|
|
|
''}
|
2019-12-17 21:15:53 +01:00
|
|
|
${build_bin} "$BIN_NAME" "$BIN_PATH"
|
2022-08-23 13:09:33 +02:00
|
|
|
'' else ''
|
|
|
|
echo Binary ${bin.name or crateName} not compiled due to not having all of the required features -- ${lib.escapeShellArg (builtins.toJSON bin.requiredFeatures)} -- enabled.
|
2019-12-12 00:06:22 +01:00
|
|
|
'') crateBin)}
|
2018-09-06 15:03:13 +02:00
|
|
|
|
2019-12-17 21:15:53 +01:00
|
|
|
${lib.optionalString buildTests ''
|
|
|
|
# When tests are enabled build all the files in the `tests` directory as
|
|
|
|
# test binaries.
|
|
|
|
if [ -d tests ]; then
|
|
|
|
# find all the .rs files (or symlinks to those) in the tests directory, no subdirectories
|
|
|
|
find tests -maxdepth 1 \( -type f -o -type l \) -a -name '*.rs' -print0 | while IFS= read -r -d ''' file; do
|
|
|
|
mkdir -p target/bin
|
|
|
|
build_bin_test_file "$file"
|
|
|
|
done
|
|
|
|
|
|
|
|
# find all the subdirectories of tests/ that contain a main.rs file as
|
|
|
|
# that is also a test according to cargo
|
|
|
|
find tests/ -mindepth 1 -maxdepth 2 \( -type f -o -type l \) -a -name 'main.rs' -print0 | while IFS= read -r -d ''' file; do
|
|
|
|
mkdir -p target/bin
|
|
|
|
build_bin_test_file "$file"
|
|
|
|
done
|
|
|
|
|
|
|
|
fi
|
|
|
|
''}
|
|
|
|
|
2019-12-12 00:06:22 +01:00
|
|
|
# If crateBin is empty and hasCrateBin is not set then we must try to
|
|
|
|
# detect some kind of bin target based on some files that might exist.
|
|
|
|
${lib.optionalString (lib.length crateBin == 0 && !hasCrateBin) ''
|
2018-09-06 15:03:13 +02:00
|
|
|
if [[ -e src/main.rs ]]; then
|
2018-10-28 01:06:29 +02:00
|
|
|
mkdir -p target/bin
|
2019-12-17 21:15:53 +01:00
|
|
|
${build_bin} ${crateName} src/main.rs
|
2018-09-06 15:03:13 +02:00
|
|
|
fi
|
|
|
|
for i in src/bin/*.rs; do #*/
|
2018-10-28 01:06:29 +02:00
|
|
|
mkdir -p target/bin
|
2019-12-17 21:15:53 +01:00
|
|
|
${build_bin} "$(basename $i .rs)" "$i"
|
2018-09-06 15:03:13 +02:00
|
|
|
done
|
|
|
|
''}
|
|
|
|
# Remove object files to avoid "wrong ELF type"
|
|
|
|
find target -type f -name "*.o" -print0 | xargs -0 rm -f
|
|
|
|
runHook postBuild
|
|
|
|
''
|