about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-01-11 23:37:02 +0000
committerAlyssa Ross <hi@alyssa.is>2020-01-11 23:41:30 +0000
commit6c557e3f1c28cf87e9fba232811d6875dd1399c1 (patch)
tree035a071d5d8980df6de0fa42e2ef8fc0cce7055e /nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
parentda7500bc026e937ac7fce7b50f67a0e1765737a7 (diff)
parente4134747f5666bcab8680aff67fa3b63384f9a0f (diff)
downloadnixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar.gz
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar.bz2
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar.lz
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar.xz
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.tar.zst
nixlib-6c557e3f1c28cf87e9fba232811d6875dd1399c1.zip
Merge commit 'e4134747f5666bcab8680aff67fa3b63384f9a0f'
Diffstat (limited to 'nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix')
-rw-r--r--nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix214
1 files changed, 77 insertions, 137 deletions
diff --git a/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
index e0a52e62561b..4e2e2af1aa77 100644
--- a/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
+++ b/nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix
@@ -1,169 +1,109 @@
-{ lib, stdenv, echo_build_heading, noisily, makeDeps }:
+{ lib, stdenv, echo_build_heading, noisily, mkRustcDepArgs, rust }:
 { crateName,
   dependencies,
   crateFeatures, crateRenames, libName, release, libPath,
   crateType, metadata, crateBin, hasCrateBin,
-  extraRustcOpts, verbose, colors }:
+  extraRustcOpts, verbose, colors,
+  buildTests
+}:
 
   let
-
-    deps = makeDeps dependencies crateRenames;
-    rustcOpts =
-      lib.lists.foldl' (opts: opt: opts + " " + opt)
-        (if release then "-C opt-level=3" else "-C debuginfo=2")
-        (["-C codegen-units=$NIX_BUILD_CORES"] ++ extraRustcOpts);
+    baseRustcOpts =
+      [(if release then "-C opt-level=3" else "-C debuginfo=2")]
+      ++ ["-C codegen-units=$NIX_BUILD_CORES"]
+      ++ [(mkRustcDepArgs dependencies crateRenames)]
+      ++ [crateFeatures]
+      ++ extraRustcOpts
+      ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc"
+    ;
     rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}";
 
-    # Some platforms have different names for rustc.
-    rustPlatform =
-      with stdenv.hostPlatform.parsed;
-      let cpu_ = if cpu.name == "armv7a" then "armv7"
-                 else cpu.name;
-          vendor_ = vendor.name;
-          kernel_ = kernel.name;
-          abi_ = abi.name;
-      in
-      "${cpu_}-${vendor_}-${kernel_}-${abi_}";
+
+    # build the final rustc arguments that can be different between different
+    # crates
+    libRustcOpts = lib.concatStringsSep " " (
+      baseRustcOpts
+      ++ [rustcMeta]
+      ++ (map (x: "--crate-type ${x}") crateType)
+    );
+
+    binRustcOpts = lib.concatStringsSep " " (
+      baseRustcOpts
+    );
+
+    build_bin = if buildTests then "build_bin_test" else "build_bin";
   in ''
     runHook preBuild
-    norm=""
-    bold=""
-    green=""
-    boldgreen=""
-    if [[ "${colors}" == "always" ]]; then
-      norm="$(printf '\033[0m')" #returns to "normal"
-      bold="$(printf '\033[0;1m')" #set bold
-      green="$(printf '\033[0;32m')" #set green
-      boldgreen="$(printf '\033[0;1;32m')" #set bold, and set green.
-    fi
     ${echo_build_heading colors}
     ${noisily colors verbose}
 
-    build_lib() {
-       lib_src=$1
-       echo_build_heading $lib_src ${libName}
-
-       noisily rustc --crate-name $CRATE_NAME $lib_src \
-         ${lib.strings.concatStrings (map (x: " --crate-type ${x}") crateType)}  \
-         ${rustcOpts} ${rustcMeta} ${crateFeatures} --out-dir target/lib \
-         --emit=dep-info,link -L dependency=target/deps ${deps} --cap-lints allow \
-         $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors}
-
-       EXTRA_LIB=" --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}.rlib"
-       if [ -e target/deps/lib$CRATE_NAME-${metadata}${stdenv.hostPlatform.extensions.sharedLibrary} ]; then
-          EXTRA_LIB="$EXTRA_LIB --extern $CRATE_NAME=target/lib/lib$CRATE_NAME-${metadata}${stdenv.hostPlatform.extensions.sharedLibrary}"
-       fi
-    }
-
-    build_bin() {
-      crate_name=$1
-      crate_name_=$(echo $crate_name | sed -e "s/-/_/g")
-      main_file=""
-      if [[ ! -z $2 ]]; then
-        main_file=$2
-      fi
-      echo_build_heading $@
-      noisily rustc --crate-name $crate_name_ $main_file --crate-type bin ${rustcOpts}\
-        ${crateFeatures} --out-dir target/bin --emit=dep-info,link -L dependency=target/deps \
-        $LINK ${deps}$EXTRA_LIB --cap-lints allow \
-        $BUILD_OUT_DIR $EXTRA_BUILD $EXTRA_FEATURES --color ${colors} \
-        ${if stdenv.hostPlatform != stdenv.buildPlatform then "--target ${rustPlatform} -C linker=${stdenv.hostPlatform.config}-gcc" else ""}
-      if [ "$crate_name_" != "$crate_name" ]; then
-        mv target/bin/$crate_name_ target/bin/$crate_name
-      fi
-    }
+    # configure & source common build functions
+    LIB_RUSTC_OPTS="${libRustcOpts}"
+    BIN_RUSTC_OPTS="${binRustcOpts}"
+    LIB_EXT="${stdenv.hostPlatform.extensions.sharedLibrary}"
+    LIB_PATH="${libPath}"
+    LIB_NAME="${libName}"
+    source ${./lib.sh}
 
+    CRATE_NAME='${lib.replaceStrings ["-"] ["_"] libName}'
 
-    EXTRA_LIB=""
-    CRATE_NAME=$(echo ${libName} | sed -e "s/-/_/g")
+    setup_link_paths
 
-    if [[ -e target/link_ ]]; then
-      EXTRA_BUILD="$(cat target/link_) $EXTRA_BUILD"
-    fi
-
-    if [[ -e "${libPath}" ]]; then
-       build_lib ${libPath}
+    if [[ -e "$LIB_PATH" ]]; then
+       build_lib "$LIB_PATH"
+       ${lib.optionalString buildTests ''build_lib_test "$LIB_PATH"''}
     elif [[ -e src/lib.rs ]]; then
        build_lib src/lib.rs
-    elif [[ -e src/${libName}.rs ]]; then
-       build_lib src/${libName}.rs
+       ${lib.optionalString buildTests "build_lib_test src/lib.rs"}
+    elif [[ -e "src/$LIB_NAME.rs" ]]; then
+       build_lib src/$LIB_NAME.rs
+       ${lib.optionalString buildTests ''build_lib_test "src/$LIB_NAME.rs"''}
     fi
 
-    echo "$EXTRA_LINK_SEARCH" | while read i; do
-       if [[ ! -z "$i" ]]; then
-         for lib in $i; do
-           echo "-L $lib" >> target/link
-           L=$(echo $lib | sed -e "s#$(pwd)/target/build#$out/lib#")
-           echo "-L $L" >> target/link.final
-         done
-       fi
-    done
-    echo "$EXTRA_LINK" | while read i; do
-       if [[ ! -z "$i" ]]; then
-         for lib in $i; do
-           echo "-l $lib" >> target/link
-           echo "-l $lib" >> target/link.final
-         done
-       fi
-    done
-
-    if [[ -e target/link ]]; then
-       sort -u target/link.final > target/link.final.sorted
-       mv target/link.final.sorted target/link.final
-       sort -u target/link > target/link.sorted
-       mv target/link.sorted target/link
-
-       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
+
+
+    ${lib.optionalString (lib.length crateBin > 0) (lib.concatMapStringsSep "\n" (bin: ''
       mkdir -p target/bin
-      # filter empty entries / empty "lines"
-      if [[ -z "$BIN_NAME" ]]; then
-           continue
-      fi
+      BIN_NAME='${bin.name or crateName}'
+      ${if !bin ? path then ''
+        BIN_PATH=""
+        search_for_bin_path "$BIN_NAME"
+      '' else ''
+        BIN_PATH='${bin.path}'
+      ''}
+        ${build_bin} "$BIN_NAME" "$BIN_PATH"
+    '') crateBin)}
+
+    ${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
 
-      if [[ -z "$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 | sed -e 's/-/_/g')
-        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
-          # if this is not a library the following path is also valid
-          FILES=( "src/$BIN_NAME.rs" "src/$BIN_NAME_.rs" "''${FILES[@]}" )
-        fi
-
-        for file in "''${FILES[@]}";
-        do
-          echo "checking file $file"
-          # first file that exists wins
-          if [[ -e "$file" ]]; then
-                  BIN_PATH="$file"
-                  break
-          fi
-        done
-
-        if [[ -z "$BIN_PATH" ]]; then
-          echo "failed to find file for binary target: $BIN_NAME" >&2
-          exit 1
-        fi
-      fi
-      build_bin "$BIN_NAME" "$BIN_PATH"
-    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
     ''}
 
-    ${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
+        ${build_bin} ${crateName} src/main.rs
       fi
       for i in src/bin/*.rs; do #*/
         mkdir -p target/bin
-        build_bin "$(basename $i .rs)" "$i"
+        ${build_bin} "$(basename $i .rs)" "$i"
       done
     ''}
     # Remove object files to avoid "wrong ELF type"