nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 161 lines 4.9 kB view raw
1{ 2 lib, 3 stdenv, 4 mkRustcDepArgs, 5 mkRustcFeatureArgs, 6 needUnstableCLI, 7 rustc, 8}: 9 10{ 11 crateName, 12 dependencies, 13 crateFeatures, 14 crateRenames, 15 libName, 16 release, 17 libPath, 18 crateType, 19 metadata, 20 crateBin, 21 hasCrateBin, 22 extraRustcOpts, 23 verbose, 24 colors, 25 buildTests, 26 codegenUnits, 27}: 28 29let 30 baseRustcOpts = [ 31 (if release then "-C opt-level=3" else "-C debuginfo=2") 32 "-C codegen-units=${toString codegenUnits}" 33 "--remap-path-prefix=$NIX_BUILD_TOP=/" 34 (mkRustcDepArgs dependencies crateRenames) 35 (mkRustcFeatureArgs crateFeatures) 36 ] 37 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 38 "--target" 39 stdenv.hostPlatform.rust.rustcTargetSpec 40 ] 41 ++ lib.optionals (needUnstableCLI dependencies) [ 42 "-Z" 43 "unstable-options" 44 ] 45 ++ extraRustcOpts 46 # since rustc 1.42 the "proc_macro" crate is part of the default crate prelude 47 # https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022 48 ++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro" 49 ++ 50 lib.optional (stdenv.hostPlatform.linker == "lld" && rustc ? llvmPackages.lld) # Needed when building for targets that use lld. e.g. 'wasm32-unknown-unknown' 51 "-C linker=${rustc.llvmPackages.lld}/bin/lld" 52 ++ lib.optional ( 53 stdenv.hasCC && stdenv.hostPlatform.linker != "lld" 54 ) "-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"; 55 rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}"; 56 57 # build the final rustc arguments that can be different between different 58 # crates 59 libRustcOpts = lib.concatStringsSep " " ( 60 baseRustcOpts ++ [ rustcMeta ] ++ (map (x: "--crate-type ${x}") crateType) 61 ); 62 63 binRustcOpts = lib.concatStringsSep " " baseRustcOpts; 64 65 build_bin = if buildTests then "build_bin_test" else "build_bin"; 66in 67'' 68 runHook preBuild 69 70 # configure & source common build functions 71 LIB_RUSTC_OPTS="${libRustcOpts}" 72 BIN_RUSTC_OPTS="${binRustcOpts}" 73 LIB_EXT="${stdenv.hostPlatform.extensions.library}" 74 LIB_PATH="${libPath}" 75 LIB_NAME="${libName}" 76 77 CRATE_NAME='${lib.replaceStrings [ "-" ] [ "_" ] libName}' 78 79 setup_link_paths 80 81 if [[ -e "$LIB_PATH" ]]; then 82 build_lib "$LIB_PATH" 83 ${lib.optionalString buildTests ''build_lib_test "$LIB_PATH"''} 84 elif [[ -e src/lib.rs ]]; then 85 build_lib src/lib.rs 86 ${lib.optionalString buildTests "build_lib_test src/lib.rs"} 87 fi 88 89 90 91 ${lib.optionalString (lib.length crateBin > 0) ( 92 lib.concatMapStringsSep "\n" ( 93 bin: 94 let 95 haveRequiredFeature = 96 if bin ? requiredFeatures then 97 # Check that all element in requiredFeatures are also present in crateFeatures 98 lib.intersectLists bin.requiredFeatures crateFeatures == bin.requiredFeatures 99 else 100 true; 101 in 102 if haveRequiredFeature then 103 '' 104 mkdir -p target/bin 105 BIN_NAME='${bin.name or crateName}' 106 ${ 107 if !bin ? path then 108 '' 109 BIN_PATH="" 110 search_for_bin_path "$BIN_NAME" 111 '' 112 else 113 '' 114 BIN_PATH='${bin.path}' 115 '' 116 } 117 ${build_bin} "$BIN_NAME" "$BIN_PATH" 118 '' 119 else 120 '' 121 echo Binary ${bin.name or crateName} not compiled due to not having all of the required features -- ${lib.escapeShellArg (builtins.toJSON bin.requiredFeatures)} -- enabled. 122 '' 123 ) crateBin 124 )} 125 126 ${lib.optionalString buildTests '' 127 # When tests are enabled build all the files in the `tests` directory as 128 # test binaries. 129 if [ -d tests ]; then 130 # find all the .rs files (or symlinks to those) in the tests directory, no subdirectories 131 find tests -maxdepth 1 \( -type f -o -type l \) -a -name '*.rs' -print0 | while IFS= read -r -d ''' file; do 132 mkdir -p target/bin 133 build_bin_test_file "$file" 134 done 135 136 # find all the subdirectories of tests/ that contain a main.rs file as 137 # that is also a test according to cargo 138 find tests/ -mindepth 1 -maxdepth 2 \( -type f -o -type l \) -a -name 'main.rs' -print0 | while IFS= read -r -d ''' file; do 139 mkdir -p target/bin 140 build_bin_test_file "$file" 141 done 142 143 fi 144 ''} 145 146 # If crateBin is empty and hasCrateBin is not set then we must try to 147 # detect some kind of bin target based on some files that might exist. 148 ${lib.optionalString (lib.length crateBin == 0 && !hasCrateBin) '' 149 if [[ -e src/main.rs ]]; then 150 mkdir -p target/bin 151 ${build_bin} ${crateName} src/main.rs 152 fi 153 for i in src/bin/*.rs; do #*/ 154 mkdir -p target/bin 155 ${build_bin} "$(basename $i .rs)" "$i" 156 done 157 ''} 158 # Remove object files to avoid "wrong ELF type" 159 find target -type f -name "*.o" -print0 | xargs -0 rm -f 160 runHook postBuild 161''