Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at flake-libs 428 lines 16 kB view raw
1{ 2 lib, 3 stdenv, 4 removeReferencesTo, 5 pkgsBuildBuild, 6 pkgsBuildHost, 7 pkgsBuildTarget, 8 targetPackages, 9 llvmShared, 10 llvmSharedForBuild, 11 llvmSharedForHost, 12 llvmSharedForTarget, 13 llvmPackages, 14 runCommandLocal, 15 fetchurl, 16 file, 17 python3, 18 cargo, 19 cmake, 20 rustc, 21 rustfmt, 22 pkg-config, 23 openssl, 24 xz, 25 zlib, 26 bintools, 27 libiconv, 28 which, 29 libffi, 30 withBundledLLVM ? false, 31 enableRustcDev ? true, 32 version, 33 sha256, 34 patches ? [ ], 35 fd, 36 ripgrep, 37 wezterm, 38 firefox, 39 thunderbird, 40 # This only builds std for target and reuses the rustc from build. 41 fastCross, 42 lndir, 43 makeWrapper, 44}: 45 46let 47 inherit (lib) 48 optionals 49 optional 50 optionalString 51 concatStringsSep 52 ; 53 useLLVM = stdenv.targetPlatform.useLLVM or false; 54in 55stdenv.mkDerivation (finalAttrs: { 56 pname = "${targetPackages.stdenv.cc.targetPrefix}rustc"; 57 inherit version; 58 59 src = fetchurl { 60 url = "https://static.rust-lang.org/dist/rustc-${version}-src.tar.gz"; 61 inherit sha256; 62 # See https://nixos.org/manual/nixpkgs/stable/#using-git-bisect-on-the-rust-compiler 63 passthru.isReleaseTarball = true; 64 }; 65 66 hardeningDisable = optionals stdenv.cc.isClang [ 67 # remove once https://github.com/NixOS/nixpkgs/issues/318674 is 68 # addressed properly 69 "zerocallusedregs" 70 ]; 71 72 __darwinAllowLocalNetworking = true; 73 74 # rustc complains about modified source files otherwise 75 dontUpdateAutotoolsGnuConfigScripts = true; 76 77 # Running the default `strip -S` command on Darwin corrupts the 78 # .rlib files in "lib/". 79 # 80 # See https://github.com/NixOS/nixpkgs/pull/34227 81 # 82 # Running `strip -S` when cross compiling can harm the cross rlibs. 83 # See: https://github.com/NixOS/nixpkgs/pull/56540#issuecomment-471624656 84 stripDebugList = [ "bin" ]; 85 86 # The Rust pkg-config crate does not support prefixed pkg-config executables[1], 87 # but it does support checking these idiosyncratic PKG_CONFIG_${TRIPLE} 88 # environment variables. 89 # [1]: https://github.com/rust-lang/pkg-config-rs/issues/53 90 "PKG_CONFIG_${builtins.replaceStrings [ "-" ] [ "_" ] stdenv.buildPlatform.rust.rustcTarget}" = 91 "${pkgsBuildHost.stdenv.cc.targetPrefix}pkg-config"; 92 93 NIX_LDFLAGS = toString ( 94 # when linking stage1 libstd: cc: undefined reference to `__cxa_begin_catch' 95 # This doesn't apply to cross-building for FreeBSD because the host 96 # uses libstdc++, but the target (used for building std) uses libc++ 97 optional ( 98 stdenv.hostPlatform.isLinux && !withBundledLLVM && !stdenv.targetPlatform.isFreeBSD && !useLLVM 99 ) "--push-state --as-needed -lstdc++ --pop-state" 100 ++ 101 optional 102 (stdenv.hostPlatform.isLinux && !withBundledLLVM && !stdenv.targetPlatform.isFreeBSD && useLLVM) 103 "--push-state --as-needed -L${llvmPackages.libcxx}/lib -lc++ -lc++abi -lLLVM-${lib.versions.major llvmPackages.llvm.version} --pop-state" 104 ++ optional (stdenv.hostPlatform.isDarwin && !withBundledLLVM) "-lc++ -lc++abi" 105 ++ optional stdenv.hostPlatform.isFreeBSD "-rpath ${llvmPackages.libunwind}/lib" 106 ++ optional stdenv.hostPlatform.isDarwin "-rpath ${llvmSharedForHost.lib}/lib" 107 ); 108 109 # Increase codegen units to introduce parallelism within the compiler. 110 RUSTFLAGS = "-Ccodegen-units=10"; 111 RUSTDOCFLAGS = "-A rustdoc::broken-intra-doc-links"; 112 113 # We need rust to build rust. If we don't provide it, configure will try to download it. 114 # Reference: https://github.com/rust-lang/rust/blob/master/src/bootstrap/configure.py 115 configureFlags = 116 let 117 prefixForStdenv = stdenv: "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}"; 118 ccPrefixForStdenv = 119 stdenv: "${prefixForStdenv stdenv}${if (stdenv.cc.isClang or false) then "clang" else "cc"}"; 120 cxxPrefixForStdenv = 121 stdenv: "${prefixForStdenv stdenv}${if (stdenv.cc.isClang or false) then "clang++" else "c++"}"; 122 setBuild = "--set=target.${stdenv.buildPlatform.rust.rustcTarget}"; 123 setHost = "--set=target.${stdenv.hostPlatform.rust.rustcTarget}"; 124 setTarget = "--set=target.${stdenv.targetPlatform.rust.rustcTarget}"; 125 ccForBuild = ccPrefixForStdenv pkgsBuildBuild.targetPackages.stdenv; 126 cxxForBuild = cxxPrefixForStdenv pkgsBuildBuild.targetPackages.stdenv; 127 ccForHost = ccPrefixForStdenv pkgsBuildHost.targetPackages.stdenv; 128 cxxForHost = cxxPrefixForStdenv pkgsBuildHost.targetPackages.stdenv; 129 ccForTarget = ccPrefixForStdenv pkgsBuildTarget.targetPackages.stdenv; 130 cxxForTarget = cxxPrefixForStdenv pkgsBuildTarget.targetPackages.stdenv; 131 in 132 [ 133 "--sysconfdir=${placeholder "out"}/etc" 134 "--release-channel=stable" 135 "--set=build.rustc=${rustc}/bin/rustc" 136 "--set=build.cargo=${cargo}/bin/cargo" 137 ] 138 ++ lib.optionals (!(finalAttrs.src.passthru.isReleaseTarball or false)) [ 139 # release tarballs vendor the rustfmt source; when 140 # git-bisect'ing from upstream's git repo we must prevent 141 # attempts to download the missing source tarball 142 "--set=build.rustfmt=${rustfmt}/bin/rustfmt" 143 ] 144 ++ [ 145 "--tools=rustc,rustdoc,rust-analyzer-proc-macro-srv" 146 "--enable-rpath" 147 "--enable-vendor" 148 # For Nixpkgs it makes more sense to use stdenv's linker than 149 # letting rustc build its own. 150 "--disable-lld" 151 "--build=${stdenv.buildPlatform.rust.rustcTargetSpec}" 152 "--host=${stdenv.hostPlatform.rust.rustcTargetSpec}" 153 # std is built for all platforms in --target. 154 "--target=${ 155 concatStringsSep "," ( 156 [ 157 stdenv.targetPlatform.rust.rustcTargetSpec 158 ] 159 # Other targets that don't need any extra dependencies to build. 160 ++ optionals (!fastCross) [ 161 "wasm32-unknown-unknown" 162 "wasm32v1-none" 163 "bpfel-unknown-none" 164 "bpfeb-unknown-none" 165 ] 166 # (build!=target): When cross-building a compiler we need to add 167 # the build platform as well so rustc can compile build.rs 168 # scripts. 169 ++ optionals (stdenv.buildPlatform != stdenv.targetPlatform && !fastCross) [ 170 stdenv.buildPlatform.rust.rustcTargetSpec 171 ] 172 # (host!=target): When building a cross-targeting compiler we 173 # need to add the host platform as well so rustc can compile 174 # build.rs scripts. 175 ++ optionals (stdenv.hostPlatform != stdenv.targetPlatform && !fastCross) [ 176 stdenv.hostPlatform.rust.rustcTargetSpec 177 ] 178 ) 179 }" 180 181 "${setBuild}.cc=${ccForBuild}" 182 "${setHost}.cc=${ccForHost}" 183 "${setTarget}.cc=${ccForTarget}" 184 185 "${setBuild}.linker=${ccForBuild}" 186 "${setHost}.linker=${ccForHost}" 187 "${setTarget}.linker=${ccForTarget}" 188 189 "${setBuild}.cxx=${cxxForBuild}" 190 "${setHost}.cxx=${cxxForHost}" 191 "${setTarget}.cxx=${cxxForTarget}" 192 193 "${setBuild}.crt-static=${lib.boolToString stdenv.buildPlatform.isStatic}" 194 "${setHost}.crt-static=${lib.boolToString stdenv.hostPlatform.isStatic}" 195 "${setTarget}.crt-static=${lib.boolToString stdenv.targetPlatform.isStatic}" 196 ] 197 ++ optionals (!withBundledLLVM) [ 198 "--enable-llvm-link-shared" 199 "${setBuild}.llvm-config=${llvmSharedForBuild.dev}/bin/llvm-config" 200 "${setHost}.llvm-config=${llvmSharedForHost.dev}/bin/llvm-config" 201 "${setTarget}.llvm-config=${llvmSharedForTarget.dev}/bin/llvm-config" 202 ] 203 ++ optionals fastCross [ 204 # Since fastCross only builds std, it doesn't make sense (and 205 # doesn't work) to build a linker. 206 "--disable-llvm-bitcode-linker" 207 ] 208 ++ optionals (stdenv.targetPlatform.isLinux && !(stdenv.targetPlatform.useLLVM or false)) [ 209 "--enable-profiler" # build libprofiler_builtins 210 ] 211 ++ optionals stdenv.buildPlatform.isMusl [ 212 "${setBuild}.musl-root=${pkgsBuildBuild.targetPackages.stdenv.cc.libc}" 213 ] 214 ++ optionals stdenv.hostPlatform.isMusl [ 215 "${setHost}.musl-root=${pkgsBuildHost.targetPackages.stdenv.cc.libc}" 216 ] 217 ++ optionals stdenv.targetPlatform.isMusl [ 218 "${setTarget}.musl-root=${pkgsBuildTarget.targetPackages.stdenv.cc.libc}" 219 ] 220 ++ optionals stdenv.targetPlatform.rust.isNoStdTarget [ 221 "--disable-docs" 222 ] 223 ++ optionals (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isx86_64) [ 224 # https://github.com/rust-lang/rust/issues/92173 225 "--set rust.jemalloc" 226 ] 227 ++ optionals (useLLVM && !stdenv.targetPlatform.isFreeBSD) [ 228 # https://github.com/NixOS/nixpkgs/issues/311930 229 "--llvm-libunwind=${if withBundledLLVM then "in-tree" else "system"}" 230 "--enable-use-libcxx" 231 ]; 232 233 # if we already have a rust compiler for build just compile the target std 234 # library and reuse compiler 235 buildPhase = 236 if fastCross then 237 '' 238 runHook preBuild 239 240 mkdir -p build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-{std,rustc}/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/ 241 ln -s ${rustc.unwrapped}/lib/rustlib/${stdenv.hostPlatform.rust.rustcTargetSpec}/libstd-*.so build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-std/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/libstd.so 242 ln -s ${rustc.unwrapped}/lib/rustlib/${stdenv.hostPlatform.rust.rustcTargetSpec}/librustc_driver-*.so build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-rustc/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/librustc.so 243 ln -s ${rustc.unwrapped}/bin/rustc build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-rustc/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/rustc-main 244 touch build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-std/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/.libstd-stamp 245 touch build/${stdenv.hostPlatform.rust.rustcTargetSpec}/stage0-rustc/${stdenv.hostPlatform.rust.rustcTargetSpec}/release/.librustc-stamp 246 python ./x.py --keep-stage=0 --stage=1 build library 247 248 runHook postBuild 249 '' 250 else 251 null; 252 253 installPhase = 254 if fastCross then 255 '' 256 runHook preInstall 257 258 python ./x.py --keep-stage=0 --stage=1 install library/std 259 mkdir -v $out/bin $doc $man 260 ln -s ${rustc.unwrapped}/bin/{rustc,rustdoc} $out/bin 261 rm -rf -v $out/lib/rustlib/{manifest-rust-std-,}${stdenv.hostPlatform.rust.rustcTargetSpec} 262 ln -s ${rustc.unwrapped}/lib/rustlib/{manifest-rust-std-,}${stdenv.hostPlatform.rust.rustcTargetSpec} $out/lib/rustlib/ 263 echo rust-std-${stdenv.hostPlatform.rust.rustcTargetSpec} >> $out/lib/rustlib/components 264 lndir ${rustc.doc} $doc 265 lndir ${rustc.man} $man 266 267 runHook postInstall 268 '' 269 else 270 null; 271 272 # the rust build system complains that nix alters the checksums 273 dontFixLibtool = true; 274 275 inherit patches; 276 277 postPatch = 278 '' 279 patchShebangs src/etc 280 281 # rust-lld is the name rustup uses for its bundled lld, so that it 282 # doesn't conflict with any system lld. This is not an 283 # appropriate default for Nixpkgs, where there is no rust-lld. 284 substituteInPlace compiler/rustc_target/src/spec/*/*.rs \ 285 --replace-quiet '"rust-lld"' '"lld"' 286 287 ${optionalString (!withBundledLLVM) "rm -rf src/llvm"} 288 289 # Useful debugging parameter 290 # export VERBOSE=1 291 '' 292 + lib.optionalString (stdenv.hostPlatform.isDarwin || stdenv.targetPlatform.isDarwin) '' 293 # Replace hardcoded path to strip with llvm-strip 294 # https://github.com/NixOS/nixpkgs/issues/299606 295 substituteInPlace compiler/rustc_codegen_ssa/src/back/link.rs \ 296 --replace-fail "/usr/bin/strip" "${lib.getExe' llvmShared "llvm-strip"}" 297 '' 298 + lib.optionalString (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isx86_64) '' 299 # See https://github.com/jemalloc/jemalloc/issues/1997 300 # Using a value of 48 should work on both emulated and native x86_64-darwin. 301 export JEMALLOC_SYS_WITH_LG_VADDR=48 302 '' 303 + lib.optionalString (!(finalAttrs.src.passthru.isReleaseTarball or false)) '' 304 mkdir .cargo 305 cat > .cargo/config.toml <<\EOF 306 [source.crates-io] 307 replace-with = "vendored-sources" 308 [source.vendored-sources] 309 directory = "vendor" 310 EOF 311 '' 312 + lib.optionalString (stdenv.hostPlatform.isFreeBSD) '' 313 # lzma-sys bundles an old version of xz that doesn't build 314 # on modern FreeBSD, use the system one instead 315 substituteInPlace src/bootstrap/src/core/build_steps/tool.rs \ 316 --replace 'cargo.env("LZMA_API_STATIC", "1");' ' ' 317 ''; 318 319 # rustc unfortunately needs cmake to compile llvm-rt but doesn't 320 # use it for the normal build. This disables cmake in Nix. 321 dontUseCmakeConfigure = true; 322 323 depsBuildBuild = [ 324 pkgsBuildHost.stdenv.cc 325 pkg-config 326 ]; 327 depsBuildTarget = lib.optionals stdenv.targetPlatform.isMinGW [ bintools ]; 328 329 nativeBuildInputs = 330 [ 331 file 332 python3 333 rustc 334 cmake 335 which 336 libffi 337 removeReferencesTo 338 pkg-config 339 xz 340 ] 341 ++ optionals fastCross [ 342 lndir 343 makeWrapper 344 ]; 345 346 buildInputs = 347 [ openssl ] 348 ++ optionals stdenv.hostPlatform.isDarwin [ 349 libiconv 350 zlib 351 ] 352 ++ optional (!withBundledLLVM) llvmShared.lib 353 ++ optional (useLLVM && !withBundledLLVM && !stdenv.targetPlatform.isFreeBSD) [ 354 llvmPackages.libunwind 355 # Hack which is used upstream https://github.com/gentoo/gentoo/blob/master/dev-lang/rust/rust-1.78.0.ebuild#L284 356 (runCommandLocal "libunwind-libgcc" { } '' 357 mkdir -p $out/lib 358 ln -s ${llvmPackages.libunwind}/lib/libunwind.so $out/lib/libgcc_s.so 359 ln -s ${llvmPackages.libunwind}/lib/libunwind.so $out/lib/libgcc_s.so.1 360 '') 361 ]; 362 363 outputs = [ 364 "out" 365 "man" 366 "doc" 367 ]; 368 setOutputFlags = false; 369 370 postInstall = 371 lib.optionalString (enableRustcDev && !fastCross) '' 372 # install rustc-dev components. Necessary to build rls, clippy... 373 python x.py dist rustc-dev 374 tar xf build/dist/rustc-dev*tar.gz 375 cp -r rustc-dev*/rustc-dev*/lib/* $out/lib/ 376 rm $out/lib/rustlib/install.log 377 for m in $out/lib/rustlib/manifest-rust* 378 do 379 sort --output=$m < $m 380 done 381 382 '' 383 + '' 384 # remove references to llvm-config in lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so 385 # and thus a transitive dependency on ncurses 386 find $out/lib -name "*.so" -type f -exec remove-references-to -t ${llvmShared} '{}' '+' 387 388 # remove uninstall script that doesn't really make sense for Nix. 389 rm $out/lib/rustlib/uninstall.sh 390 ''; 391 392 configurePlatforms = [ ]; 393 394 enableParallelBuilding = true; 395 396 setupHooks = ./setup-hook.sh; 397 398 requiredSystemFeatures = [ "big-parallel" ]; 399 400 passthru = { 401 llvm = llvmShared; 402 inherit llvmPackages; 403 inherit (rustc) tier1TargetPlatforms targetPlatforms badTargetPlatforms; 404 tests = { 405 inherit fd ripgrep wezterm; 406 } // lib.optionalAttrs stdenv.hostPlatform.isLinux { inherit firefox thunderbird; }; 407 }; 408 409 meta = with lib; { 410 homepage = "https://www.rust-lang.org/"; 411 description = "Safe, concurrent, practical language"; 412 maintainers = with maintainers; [ havvy ]; 413 teams = [ teams.rust ]; 414 license = [ 415 licenses.mit 416 licenses.asl20 417 ]; 418 platforms = rustc.tier1TargetPlatforms; 419 # If rustc can't target a platform, we also can't build rustc for 420 # that platform. 421 badPlatforms = rustc.badTargetPlatforms; 422 # Builds, but can't actually compile anything 423 # https://github.com/NixOS/nixpkgs/issues/311930 424 # https://github.com/rust-lang/rust/issues/55120 425 # https://github.com/rust-lang/rust/issues/82521 426 broken = stdenv.hostPlatform.useLLVM; 427 }; 428})