Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at flake-libs 492 lines 14 kB view raw
1{ 2 lib, 3 stdenv, 4 targetPackages, 5 fetchurl, 6 fetchpatch, 7 noSysDirs, 8 langC ? true, 9 langCC ? true, 10 langFortran ? false, 11 langAda ? false, 12 langObjC ? stdenv.targetPlatform.isDarwin, 13 langObjCpp ? stdenv.targetPlatform.isDarwin, 14 langD ? false, 15 langGo ? false, 16 reproducibleBuild ? true, 17 profiledCompiler ? false, 18 langJit ? false, 19 langRust ? false, 20 cargo, 21 staticCompiler ? false, 22 enableShared ? stdenv.targetPlatform.hasSharedLibraries, 23 enableLTO ? stdenv.hostPlatform.hasSharedLibraries, 24 texinfo ? null, 25 perl ? null, # optional, for texi2pod (then pod2man) 26 gmp, 27 mpfr, 28 libmpc, 29 gettext, 30 which, 31 patchelf, 32 binutils, 33 isl ? null, # optional, for the Graphite optimization framework. 34 zlib ? null, 35 libucontext ? null, 36 gnat-bootstrap ? null, 37 enableMultilib ? false, 38 enablePlugin ? (lib.systems.equals stdenv.hostPlatform stdenv.buildPlatform), # Whether to support user-supplied plug-ins 39 name ? "gcc", 40 libcCross ? null, 41 threadsCross ? null, # for MinGW 42 withoutTargetLibc ? false, 43 flex, 44 gnused ? null, 45 buildPackages, 46 pkgsBuildTarget, 47 libxcrypt, 48 disableGdbPlugin ? 49 !enablePlugin 50 || (stdenv.targetPlatform.isAvr && stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64), 51 nukeReferences, 52 callPackage, 53 majorMinorVersion, 54 apple-sdk, 55 cctools, 56 darwin, 57}: 58 59let 60 inherit (lib) 61 callPackageWith 62 filter 63 getBin 64 maintainers 65 makeLibraryPath 66 makeSearchPathOutput 67 mapAttrs 68 optional 69 optionalAttrs 70 optionals 71 optionalString 72 pipe 73 platforms 74 versionAtLeast 75 versions 76 ; 77 78 gccVersions = import ./versions.nix; 79 version = gccVersions.fromMajorMinor majorMinorVersion; 80 81 majorVersion = versions.major version; 82 atLeast14 = versionAtLeast version "14"; 83 atLeast13 = versionAtLeast version "13"; 84 atLeast12 = versionAtLeast version "12"; 85 atLeast11 = versionAtLeast version "11"; 86 atLeast10 = versionAtLeast version "10"; 87 is14 = majorVersion == "14"; 88 is13 = majorVersion == "13"; 89 is12 = majorVersion == "12"; 90 is11 = majorVersion == "11"; 91 is10 = majorVersion == "10"; 92 is9 = majorVersion == "9"; 93 94 # releases have a form: MAJOR.MINOR.MICRO, like 14.2.1 95 # snapshots have a form like MAJOR.MINOR.MICRO.DATE, like 14.2.1.20250322 96 isSnapshot = lib.length (lib.splitVersion version) == 4; 97 # return snapshot date of gcc's given version: 98 # "14.2.1.20250322" -> "20250322" 99 # "14.2.0" -> "" 100 snapDate = lib.concatStrings (lib.drop 3 (lib.splitVersion version)); 101 # return base version without a snapshot: 102 # "14.2.1.20250322" -> "14.2.1" 103 # "14.2.0" -> "14.2.0" 104 baseVersion = lib.concatStringsSep "." (lib.take 3 (lib.splitVersion version)); 105 106 disableBootstrap = atLeast11 && !stdenv.hostPlatform.isDarwin && (atLeast12 -> !profiledCompiler); 107 108 inherit (stdenv) buildPlatform hostPlatform targetPlatform; 109 targetConfig = 110 if (!lib.systems.equals targetPlatform hostPlatform) then targetPlatform.config else null; 111 112 patches = callFile ./patches { }; 113 114 # Cross-gcc settings (build == host != target) 115 crossMingw = (!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.isMinGW; 116 stageNameAddon = optionalString withoutTargetLibc "-nolibc"; 117 crossNameAddon = optionalString ( 118 !lib.systems.equals targetPlatform hostPlatform 119 ) "${targetPlatform.config}${stageNameAddon}-"; 120 121 callFile = callPackageWith { 122 # lets 123 inherit 124 majorVersion 125 isSnapshot 126 version 127 buildPlatform 128 hostPlatform 129 targetPlatform 130 targetConfig 131 patches 132 crossMingw 133 stageNameAddon 134 crossNameAddon 135 ; 136 # inherit generated with 'nix eval --json --impure --expr "with import ./. {}; lib.attrNames (lib.functionArgs gcc${majorVersion}.cc.override)" | jq '.[]' --raw-output' 137 inherit 138 apple-sdk 139 binutils 140 buildPackages 141 cargo 142 withoutTargetLibc 143 darwin 144 disableBootstrap 145 disableGdbPlugin 146 enableLTO 147 enableMultilib 148 enablePlugin 149 enableShared 150 fetchpatch 151 fetchurl 152 flex 153 gettext 154 gmp 155 gnat-bootstrap 156 gnused 157 isl 158 langAda 159 langC 160 langCC 161 langD 162 langFortran 163 langGo 164 langJit 165 langObjC 166 langObjCpp 167 langRust 168 lib 169 libcCross 170 libmpc 171 libucontext 172 libxcrypt 173 mpfr 174 name 175 noSysDirs 176 nukeReferences 177 patchelf 178 perl 179 pkgsBuildTarget 180 profiledCompiler 181 reproducibleBuild 182 staticCompiler 183 stdenv 184 targetPackages 185 texinfo 186 threadsCross 187 which 188 zlib 189 ; 190 }; 191 192in 193 194# Make sure we get GNU sed. 195assert stdenv.buildPlatform.isDarwin -> gnused != null; 196 197# The go frontend is written in c++ 198assert langGo -> langCC; 199assert langAda -> gnat-bootstrap != null; 200 201# TODO: fixup D bootstrapping, probably by using gdc11 (and maybe other changes). 202# error: GDC is required to build d 203assert atLeast12 -> !langD; 204 205# threadsCross is just for MinGW 206assert threadsCross != { } -> stdenv.targetPlatform.isWindows; 207 208# profiledCompiler builds inject non-determinism in one of the compilation stages. 209# If turned on, we can't provide reproducible builds anymore 210assert reproducibleBuild -> profiledCompiler == false; 211 212pipe 213 ((callFile ./common/builder.nix { }) ( 214 { 215 pname = "${crossNameAddon}${name}"; 216 # retain snapshot date in package version, but not in final version 217 # as the version is frequently used to construct pathnames (at least 218 # in cc-wrapper). 219 name = "${crossNameAddon}${name}-${version}"; 220 version = baseVersion; 221 222 src = fetchurl { 223 url = 224 if isSnapshot then 225 "mirror://gcc/snapshots/${majorVersion}-${snapDate}/gcc-${majorVersion}-${snapDate}.tar.xz" 226 else 227 "mirror://gcc/releases/gcc-${version}/gcc-${version}.tar.xz"; 228 ${if is10 || is11 || is13 then "hash" else "sha256"} = gccVersions.srcHashForVersion version; 229 }; 230 231 inherit patches; 232 233 outputs = [ 234 "out" 235 "man" 236 "info" 237 ] ++ optional (!langJit) "lib"; 238 239 setOutputFlags = false; 240 241 libc_dev = stdenv.cc.libc_dev; 242 243 hardeningDisable = [ 244 "format" 245 "pie" 246 "stackclashprotection" 247 ] ++ optionals (is11 && langAda) [ "fortify3" ]; 248 249 postPatch = 250 '' 251 configureScripts=$(find . -name configure) 252 for configureScript in $configureScripts; do 253 patchShebangs $configureScript 254 done 255 256 # Make sure nixpkgs versioning match upstream one 257 # to ease version-based comparisons. 258 gcc_base_version=$(< gcc/BASE-VER) 259 if [[ ${baseVersion} != $gcc_base_version ]]; then 260 echo "Please update 'version' variable:" 261 echo " Expected: '$gcc_base_version'" 262 echo " Actual: '${version}'" 263 exit 1 264 fi 265 '' 266 # This should kill all the stdinc frameworks that gcc and friends like to 267 # insert into default search paths. 268 + optionalString hostPlatform.isDarwin '' 269 substituteInPlace gcc/config/darwin-c.c${optionalString atLeast12 "c"} \ 270 --replace 'if (stdinc)' 'if (0)' 271 272 substituteInPlace libgcc/config/t-slibgcc-darwin \ 273 --replace "-install_name @shlib_slibdir@/\$(SHLIB_INSTALL_NAME)" "-install_name ''${!outputLib}/lib/\$(SHLIB_INSTALL_NAME)" 274 275 substituteInPlace libgfortran/configure \ 276 --replace "-install_name \\\$rpath/\\\$soname" "-install_name ''${!outputLib}/lib/\\\$soname" 277 '' 278 + (optionalString ((!lib.systems.equals targetPlatform hostPlatform) || stdenv.cc.libc != null) 279 # On NixOS, use the right path to the dynamic linker instead of 280 # `/lib/ld*.so'. 281 ( 282 let 283 libc = if libcCross != null then libcCross else stdenv.cc.libc; 284 in 285 ( 286 '' 287 echo "fixing the {GLIBC,UCLIBC,MUSL}_DYNAMIC_LINKER macros..." 288 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h 289 do 290 grep -q _DYNAMIC_LINKER "$header" || continue 291 echo " fixing $header..." 292 sed -i "$header" \ 293 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc.out}\3"|g' \ 294 -e 's|define[[:blank:]]*MUSL_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define MUSL_DYNAMIC_LINKER\1 "${libc.out}\2"|g' 295 done 296 '' 297 + optionalString (targetPlatform.libc == "musl") '' 298 sed -i gcc/config/linux.h -e '1i#undef LOCAL_INCLUDE_DIR' 299 '' 300 ) 301 ) 302 ) 303 + optionalString targetPlatform.isAvr ('' 304 makeFlagsArray+=( 305 '-s' # workaround for hitting hydra log limit 306 'LIMITS_H_TEST=false' 307 ) 308 ''); 309 310 inherit 311 noSysDirs 312 staticCompiler 313 withoutTargetLibc 314 libcCross 315 crossMingw 316 ; 317 318 inherit (callFile ./common/dependencies.nix { }) 319 depsBuildBuild 320 nativeBuildInputs 321 depsBuildTarget 322 buildInputs 323 depsTargetTarget 324 ; 325 326 preConfigure = 327 (callFile ./common/pre-configure.nix { }) 328 + optionalString atLeast10 '' 329 ln -sf ${libxcrypt}/include/crypt.h libsanitizer/sanitizer_common/crypt.h 330 ''; 331 332 dontDisableStatic = true; 333 334 configurePlatforms = [ 335 "build" 336 "host" 337 "target" 338 ]; 339 340 configureFlags = callFile ./common/configure-flags.nix { }; 341 342 inherit targetConfig; 343 344 buildFlags = 345 # we do not yet have Nix-driven profiling 346 assert atLeast12 -> (profiledCompiler -> !disableBootstrap); 347 if atLeast11 then 348 let 349 target = 350 optionalString (profiledCompiler) "profiled" 351 + optionalString ( 352 (lib.systems.equals targetPlatform hostPlatform) 353 && (lib.systems.equals hostPlatform buildPlatform) 354 && !disableBootstrap 355 ) "bootstrap"; 356 in 357 optional (target != "") target 358 else 359 optional ( 360 (lib.systems.equals targetPlatform hostPlatform) && (lib.systems.equals hostPlatform buildPlatform) 361 ) (if profiledCompiler then "profiledbootstrap" else "bootstrap"); 362 363 inherit (callFile ./common/strip-attributes.nix { }) 364 stripDebugList 365 stripDebugListTarget 366 preFixup 367 ; 368 369 # https://gcc.gnu.org/PR109898 370 enableParallelInstalling = false; 371 372 env = mapAttrs (_: v: toString v) ( 373 { 374 375 NIX_NO_SELF_RPATH = true; 376 377 # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210 378 ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64"; 379 380 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the 381 # library headers and binaries, regardless of the language being compiled. 382 # 383 # The LTO code doesn't find zlib, so we just add it to $CPATH and 384 # $LIBRARY_PATH in this case. 385 # 386 # Cross-compiling, we need gcc not to read ./specs in order to build the g++ 387 # compiler (after the specs for the cross-gcc are created). Having 388 # LIBRARY_PATH= makes gcc read the specs from ., and the build breaks. 389 390 CPATH = optionals (lib.systems.equals targetPlatform hostPlatform) ( 391 makeSearchPathOutput "dev" "include" ([ ] ++ optional (zlib != null) zlib) 392 ); 393 394 LIBRARY_PATH = optionals (lib.systems.equals targetPlatform hostPlatform) ( 395 makeLibraryPath (optional (zlib != null) zlib) 396 ); 397 398 NIX_LDFLAGS = optionalString hostPlatform.isSunOS "-lm"; 399 400 inherit (callFile ./common/extra-target-flags.nix { }) 401 EXTRA_FLAGS_FOR_TARGET 402 EXTRA_LDFLAGS_FOR_TARGET 403 ; 404 } 405 // 406 optionalAttrs (!atLeast12 && stdenv.cc.isClang && (!lib.systems.equals targetPlatform hostPlatform)) 407 { 408 NIX_CFLAGS_COMPILE = "-Wno-register"; 409 } 410 ); 411 412 passthru = { 413 inherit 414 langC 415 langCC 416 langObjC 417 langObjCpp 418 langAda 419 langFortran 420 langGo 421 langD 422 version 423 ; 424 isGNU = true; 425 hardeningUnsupportedFlags = 426 optional (!atLeast11) "zerocallusedregs" 427 ++ optionals (!atLeast12) [ 428 "fortify3" 429 "trivialautovarinit" 430 ] 431 ++ optional ( 432 !(targetPlatform.isLinux && targetPlatform.isx86_64 && targetPlatform.libc == "glibc") 433 ) "shadowstack" 434 ++ optional (!(targetPlatform.isLinux && targetPlatform.isAarch64)) "pacret" 435 ++ optionals (langFortran) [ 436 "fortify" 437 "format" 438 ]; 439 }; 440 441 enableParallelBuilding = true; 442 inherit enableShared enableMultilib; 443 444 meta = 445 { 446 inherit (callFile ./common/meta.nix { }) 447 homepage 448 license 449 description 450 longDescription 451 platforms 452 teams 453 ; 454 } 455 // optionalAttrs (!atLeast11) { 456 badPlatforms = [ "aarch64-darwin" ]; 457 } 458 // optionalAttrs is10 { 459 badPlatforms = 460 if (!lib.systems.equals targetPlatform hostPlatform) then [ "aarch64-darwin" ] else [ ]; 461 }; 462 } 463 // optionalAttrs (!atLeast10 && stdenv.targetPlatform.isDarwin) { 464 # GCC <10 requires default cctools `strip` instead of `llvm-strip` used by Darwin bintools. 465 preBuild = '' 466 makeFlagsArray+=('STRIP=${getBin cctools}/bin/${stdenv.cc.targetPrefix}strip') 467 ''; 468 } 469 // optionalAttrs enableMultilib { 470 dontMoveLib64 = true; 471 } 472 )) 473 ( 474 [ 475 (callPackage ./common/libgcc.nix { 476 inherit 477 version 478 langC 479 langCC 480 langJit 481 targetPlatform 482 hostPlatform 483 withoutTargetLibc 484 enableShared 485 libcCross 486 ; 487 }) 488 ] 489 ++ optionals atLeast11 [ 490 (callPackage ./common/checksum.nix { inherit langC langCC; }) 491 ] 492 )