From 6ad22f5b4d98b776ad9c7608fe293d347bb04f56 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Thu, 12 Dec 2019 00:06:22 +0100 Subject: buildRustCrate: use less bash for the build script We can get rid of a bunch of workarounds that were in the build script before by just passing on the `crateBin` attribute. Before we converted the list of attributes to a string only to convert it back in bash during the build phase. We can do the entire looping through builds in Nix and thus need no conversion and parsing of attributes over and over again. The big part that still remains bash is the heuristic that cargo introduced and that we can't do at eval time. --- .../rust/build-rust-crate/build-crate.nix | 28 ++++++++++------------ .../rust/build-rust-crate/default.nix | 22 ++++++++--------- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'pkgs') diff --git a/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/pkgs/build-support/rust/build-rust-crate/build-crate.nix index 067a044eee5..70bd84c8346 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -6,7 +6,6 @@ extraRustcOpts, verbose, colors }: let - deps = mkRustcDepArgs dependencies crateRenames; rustcOpts = lib.foldl' (opts: opt: opts + " " + opt) @@ -54,7 +53,7 @@ EXTRA_LIB="" - CRATE_NAME=$(echo ${libName} | tr '-' '_') + CRATE_NAME='${lib.replaceStrings ["-"] ["_"] libName}' if [[ -e target/link_ ]]; then EXTRA_BUILD="$(cat target/link_) $EXTRA_BUILD" @@ -95,20 +94,16 @@ tr '\n' ' ' < target/link > target/link_ LINK=$(cat target/link_) fi - ${lib.optionalString (crateBin != "") '' - printf "%s\n" "${crateBin}" | head -n1 | tr -s ',' '\n' | while read -r BIN_NAME BIN_PATH; do - mkdir -p target/bin - # filter empty entries / empty "lines" - if [[ -z "$BIN_NAME" ]]; then - continue - fi - if [[ -z "$BIN_PATH" ]]; then + ${lib.optionalString (lib.length crateBin > 0) (lib.concatMapStringsSep "\n" (bin: '' + mkdir -p target/bin + BIN_NAME='${bin.name or crateName}' + ${if !bin ? path then '' # heuristic to "guess" the correct source file as found in cargo: # https://github.com/rust-lang/cargo/blob/90fc9f620190d5fa3c80b0c8c65a1e1361e6b8ae/src/cargo/util/toml/targets.rs#L308-L325 # the first two cases are the "new" default IIRC - BIN_NAME_=$(echo $BIN_NAME | tr '-' '_') + BIN_NAME_='${lib.replaceStrings ["-"] ["_"] bin.name}' FILES=( "src/bin/$BIN_NAME.rs" "src/bin/$BIN_NAME/main.rs" "src/bin/$BIN_NAME_.rs" "src/bin/$BIN_NAME_/main.rs" "src/bin/main.rs" "src/main.rs" ) if ! [ -e "${libPath}" -o -e src/lib.rs -o -e "src/${libName}.rs" ]; then @@ -130,12 +125,15 @@ echo "failed to find file for binary target: $BIN_NAME" >&2 exit 1 fi - fi + '' else '' + BIN_PATH='${bin.path}' + ''} build_bin "$BIN_NAME" "$BIN_PATH" - done - ''} + '') crateBin)} - ${lib.optionalString (crateBin == "" && !hasCrateBin) '' + # 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) '' if [[ -e src/main.rs ]]; then mkdir -p target/bin build_bin ${crateName} src/main.rs diff --git a/pkgs/build-support/rust/build-rust-crate/default.nix b/pkgs/build-support/rust/build-rust-crate/default.nix index c7a5122da98..6b86d632335 100644 --- a/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/default.nix @@ -59,6 +59,15 @@ let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverr extraDerivationAttrs = lib.filterAttrs (n: v: ! lib.elem n processedAttrs) crate; buildInputs_ = buildInputs; extraRustcOpts_ = extraRustcOpts; + + # take a list of crates that we depend on and override them to fit our overrides, rustc, release, … + makeDependencies = map (dep: lib.getLib (dep.override { inherit release verbose crateOverrides; })); + + # crate2nix has a hack for the old bash based build script that did split + # entries at `,`. No we have to work around that hack. + # https://github.com/kolloch/crate2nix/blame/5b19c1b14e1b0e5522c3e44e300d0b332dc939e7/crate2nix/templates/build.nix.tera#L89 + crateBin = lib.filter (bin: !(bin ? name && bin.name == ",")) (crate.crateBin or []); + hasCrateBin = crate ? crateBin; in stdenv.mkDerivation (rec { @@ -102,17 +111,6 @@ stdenv.mkDerivation (rec { (crateName + "-" + crateVersion + "___" + toString crateFeatures + "___" + depsMetadata); in lib.substring 0 10 hashedMetadata; - crateBin = if crate ? crateBin then - lib.foldl' (bins: bin: let - name = if bin ? name then bin.name else crateName; - path = if bin ? path then bin.path else ""; - in - bins + (if bin == "" then "" else ",") + "${name} ${path}" - - ) "" crate.crateBin - else ""; - hasCrateBin = crate ? crateBin; - build = crate.build or ""; workspace_member = crate.workspace_member or "."; crateVersion = crate.version; @@ -140,7 +138,7 @@ stdenv.mkDerivation (rec { buildPhase = buildCrate { inherit crateName dependencies crateFeatures crateRenames libName release libPath crateType - metadata crateBin hasCrateBin verbose colors + metadata hasCrateBin crateBin verbose colors extraRustcOpts; }; installPhase = installCrate crateName metadata; -- cgit 1.4.1