diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-01-11 23:37:02 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2020-01-11 23:41:30 +0000 |
commit | 6c557e3f1c28cf87e9fba232811d6875dd1399c1 (patch) | |
tree | 035a071d5d8980df6de0fa42e2ef8fc0cce7055e /nixpkgs/pkgs/build-support/rust/build-rust-crate/build-crate.nix | |
parent | da7500bc026e937ac7fce7b50f67a0e1765737a7 (diff) | |
parent | e4134747f5666bcab8680aff67fa3b63384f9a0f (diff) | |
download | nixlib-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.nix | 214 |
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" |