diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 00f7f3523aa48..eca0fc0def858 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -193,6 +193,34 @@ let || isWasm # WASM ) && !isStatic; + # Whether the system provides its own libunwind implementation that we + # should use. + hasSystemLibunwind = final.isFreeBSD || final.isDarwin; + + # Controls whether stack unwinding support is enabled. + hasStackUnwinding = !(final.isWasm || final.isNone); + + # You often don't want exceptions in an embedded setting, disable them by default. + hasExceptions = !(final.isNone || final.isWasm); + + # If there is no kernel (`isNone`) we assume no threads. WASM can + # supposedly support threads in certain cases, so this might change in + # the future. + hasThreads = !(final.isNone || final.isWasm); + + # On bare metal platforms or on WASM there is no "obvious" filesystem to + # access, so disable support by default. (Use-cases like filesystem + # emulation with WASI or accessing an SD card over SPI need more + # configuration than just being able to work "by default".) + hasFilesystem = !(final.isNone || final.isWasm); + + # Wanting localization in embedded settings is probably a rare edge-case, + # so disable it by default. + hasLocalization = !final.isNone; + + # Without a kernel there is no cross-platform way for libc to obtain a clock. + hasMonotonicClock = !final.isNone; + # The difference between `isStatic` and `hasSharedLibraries` is mainly the # addition of the `staticMarker` (see make-derivation.nix). Some # platforms, like embedded machines without a libc (e.g. arm-none-eabi) diff --git a/pkgs/development/compilers/llvm/common/default.nix b/pkgs/development/compilers/llvm/common/default.nix index 102a43161e3d8..24fdb131c0a11 100644 --- a/pkgs/development/compilers/llvm/common/default.nix +++ b/pkgs/development/compilers/llvm/common/default.nix @@ -742,23 +742,28 @@ let bintools = bintools'; extraPackages = [ targetLlvmLibraries.compiler-rt ] - ++ lib.optionals (!stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD) [ - targetLlvmLibraries.libunwind - ]; + ++ lib.optionals + (stdenv.targetPlatform.hasStackUnwinding && !stdenv.targetPlatform.hasSystemLibunwind) + [ + targetLlvmLibraries.libunwind + ]; extraBuildCommands = lib.optionalString (lib.versions.major metadata.release_version == "13") ( '' echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags '' - + lib.optionalString (!stdenv.targetPlatform.isWasm) '' + + lib.optionalString stdenv.targetPlatform.hasStackUnwinding '' echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags echo "-L${targetLlvmLibraries.libunwind}/lib" >> $out/nix-support/cc-ldflags '' - + lib.optionalString (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) '' - echo "-lunwind" >> $out/nix-support/cc-ldflags - '' - + lib.optionalString stdenv.targetPlatform.isWasm '' + + + lib.optionalString + (stdenv.targetPlatform.hasStackUnwinding && stdenv.targetPlatform.useLLVM or false) + '' + echo "-lunwind" >> $out/nix-support/cc-ldflags + '' + + lib.optionalString (!stdenv.targetPlatform.hasExceptions) '' echo "-fno-exceptions" >> $out/nix-support/cc-cflags '' ) @@ -772,16 +777,30 @@ let "-B${targetLlvmLibraries.compiler-rt}/lib" ] ++ lib.optional ( - !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD + stdenv.targetPlatform.hasStackUnwinding + && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this flag needed on Darwin, but not on FreeBSD? + || stdenv.targetPlatform.isDarwin + ) ) "--unwindlib=libunwind" ++ lib.optional ( - !stdenv.targetPlatform.isWasm - && !stdenv.targetPlatform.isFreeBSD + stdenv.targetPlatform.hasStackUnwinding + && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this flag needed on Darwin, but not on FreeBSD? + || stdenv.targetPlatform.isDarwin + ) && stdenv.targetPlatform.useLLVM or false ) "-lunwind" - ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions"; + ++ lib.optional (!stdenv.targetPlatform.hasExceptions) "-fno-exceptions"; nixSupport.cc-ldflags = lib.optionals ( - !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD + stdenv.targetPlatform.hasStackUnwinding + && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this flag needed on Darwin, but not on FreeBSD? + || stdenv.targetPlatform.isDarwin + ) ) [ "-L${targetLlvmLibraries.libunwind}/lib" ]; } ); @@ -794,9 +813,7 @@ let extraPackages = [ targetLlvmLibraries.compiler-rt-no-libc ] ++ lib.optionals - ( - !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin - ) + (stdenv.targetPlatform.hasStackUnwinding && !stdenv.targetPlatform.hasSystemLibunwind) [ targetLlvmLibraries.libunwind ]; @@ -806,14 +823,27 @@ let echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags echo "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" >> $out/nix-support/cc-cflags '' - + lib.optionalString (!stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isDarwin) '' - echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags - echo "-L${targetLlvmLibraries.libunwind}/lib" >> $out/nix-support/cc-ldflags - '' - + lib.optionalString (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) '' - echo "-lunwind" >> $out/nix-support/cc-ldflags - '' - + lib.optionalString stdenv.targetPlatform.isWasm '' + + + lib.optionalString + ( + stdenv.targetPlatform.hasStackUnwinding + && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this flag needed on FreeBSD, but not on Darwin? + || stdenv.targetPlatform.isFreeBSD + ) + ) + '' + echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags + echo "-L${targetLlvmLibraries.libunwind}/lib" >> $out/nix-support/cc-ldflags + '' + + + lib.optionalString + (stdenv.targetPlatform.hasStackUnwinding && stdenv.targetPlatform.useLLVM or false) + '' + echo "-lunwind" >> $out/nix-support/cc-ldflags + '' + + lib.optionalString (!stdenv.targetPlatform.hasExceptions) '' echo "-fno-exceptions" >> $out/nix-support/cc-cflags '' ) @@ -827,16 +857,20 @@ let "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" ] ++ lib.optional ( - !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin + stdenv.targetPlatform.hasStackUnwinding && !stdenv.targetPlatform.hasSystemLibunwind ) "--unwindlib=libunwind" ++ lib.optional ( - !stdenv.targetPlatform.isWasm - && !stdenv.targetPlatform.isFreeBSD + stdenv.targetPlatform.hasStackUnwinding + && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this flag needed on Darwin, but not on FreeBSD? + || stdenv.targetPlatform.isDarwin + ) && stdenv.targetPlatform.useLLVM or false ) "-lunwind" - ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions"; + ++ lib.optional (!stdenv.targetPlatform.hasExceptions) "-fno-exceptions"; nixSupport.cc-ldflags = lib.optionals ( - !stdenv.targetPlatform.isWasm && !stdenv.targetPlatform.isFreeBSD && !stdenv.targetPlatform.isDarwin + stdenv.targetPlatform.hasStackUnwinding && !stdenv.targetPlatform.hasSystemLibunwind ) [ "-L${targetLlvmLibraries.libunwind}/lib" ]; } ); @@ -863,7 +897,7 @@ let "-nostdlib++" ] ++ lib.optional ( - lib.versionAtLeast metadata.release_version "15" && stdenv.targetPlatform.isWasm + lib.versionAtLeast metadata.release_version "15" && !stdenv.targetPlatform.hasExceptions ) "-fno-exceptions"; } ); @@ -888,7 +922,7 @@ let "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" ] ++ lib.optional ( - lib.versionAtLeast metadata.release_version "15" && stdenv.targetPlatform.isWasm + lib.versionAtLeast metadata.release_version "15" && !stdenv.targetPlatform.hasExceptions ) "-fno-exceptions"; } ); @@ -909,7 +943,7 @@ let nixSupport.cc-cflags = [ "-nostartfiles" ] ++ lib.optional ( - lib.versionAtLeast metadata.release_version "15" && stdenv.targetPlatform.isWasm + lib.versionAtLeast metadata.release_version "15" && !stdenv.targetPlatform.hasExceptions ) "-fno-exceptions"; } ); @@ -925,7 +959,7 @@ let extraBuildCommands = mkExtraBuildCommands0 cc; } // lib.optionalAttrs ( - lib.versionAtLeast metadata.release_version "15" && stdenv.targetPlatform.isWasm + lib.versionAtLeast metadata.release_version "15" && !stdenv.targetPlatform.hasExceptions ) { nixSupport.cc-cflags = [ "-fno-exceptions" ]; }; # Aliases diff --git a/pkgs/development/compilers/llvm/common/libcxx/default.nix b/pkgs/development/compilers/llvm/common/libcxx/default.nix index fe9ae5d0d502b..7bda2b974a166 100644 --- a/pkgs/development/compilers/llvm/common/libcxx/default.nix +++ b/pkgs/development/compilers/llvm/common/libcxx/default.nix @@ -54,18 +54,23 @@ let cxxabiCMakeFlags = lib.optionals (lib.versionAtLeast release_version "18") [ "-DLIBCXXABI_USE_LLVM_UNWINDER=OFF" - ] ++ lib.optionals (useLLVM && !stdenv.hostPlatform.isWasm) (if lib.versionAtLeast release_version "18" then [ + ] ++ lib.optionals (useLLVM && stdenv.targetPlatform.hasStackUnwinding) (if lib.versionAtLeast release_version "18" then [ "-DLIBCXXABI_ADDITIONAL_LIBRARIES=unwind" - "-DLIBCXXABI_USE_COMPILER_RT=ON" ] else [ - "-DLIBCXXABI_USE_COMPILER_RT=ON" "-DLIBCXXABI_USE_LLVM_UNWINDER=ON" - ]) ++ lib.optionals stdenv.hostPlatform.isWasm [ + ]) ++ lib.optionals (useLLVM && !stdenv.targetPlatform.isWasm) [ + "-DLIBCXXABI_USE_COMPILER_RT=ON" + ] ++ lib.optionals (!stdenv.targetPlatform.hasThreads) [ "-DLIBCXXABI_ENABLE_THREADS=OFF" + ] ++ lib.optionals (!stdenv.targetPlatform.hasExceptions) [ "-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF" ] ++ lib.optionals (!enableShared || stdenv.hostPlatform.isWindows) [ # Required on Windows due to https://github.com/llvm/llvm-project/issues/55245 "-DLIBCXXABI_ENABLE_SHARED=OFF" + ] ++ lib.optionals (!stdenv.targetPlatform.hasLocalization) [ + "-DLIBCXX_ENABLE_LOCALIZATION=OFF" + ] ++ lib.optionals (!stdenv.targetPlatform.hasMonotonicClock) [ + "-DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF" ]; cxxCMakeFlags = [ @@ -90,9 +95,11 @@ let "-DLIBCXX_USE_COMPILER_RT=ON" ] ++ lib.optionals (useLLVM && !stdenv.hostPlatform.isFreeBSD && lib.versionAtLeast release_version "16") [ "-DLIBCXX_ADDITIONAL_LIBRARIES=unwind" - ] ++ lib.optionals stdenv.hostPlatform.isWasm [ + ] ++ lib.optionals (!stdenv.targetPlatform.hasThreads) [ "-DLIBCXX_ENABLE_THREADS=OFF" + ] ++ lib.optionals (!stdenv.targetPlatform.hasFilesystem) [ "-DLIBCXX_ENABLE_FILESYSTEM=OFF" + ] ++ lib.optionals (!stdenv.targetPlatform.hasExceptions) [ "-DLIBCXX_ENABLE_EXCEPTIONS=OFF" ] ++ lib.optionals stdenv.hostPlatform.isWindows [ # https://github.com/llvm/llvm-project/issues/55245 @@ -135,7 +142,11 @@ stdenv.mkDerivation (rec { ++ lib.optional (cxxabi != null) lndir; buildInputs = [ cxxabi ] - ++ lib.optionals (useLLVM && !stdenv.hostPlatform.isWasm && !stdenv.hostPlatform.isFreeBSD) [ libunwind ]; + ++ lib.optionals (stdenv.targetPlatform.hasStackUnwinding && ( + !stdenv.targetPlatform.hasSystemLibunwind + # TODO: Why is this needed on Darwin, but not on FreeBSD? + || stdenv.targetPlatform.isDarwin + ) && useLLVM) [ libunwind ]; # libc++.so is a linker script which expands to multiple libraries, # libc++.so.1 and libc++abi.so or the external cxxabi. ld-wrapper doesn't