Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lib/systems/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,34 @@ let
|| isWasm # WASM
) && !isStatic;

# Whether the system provides its own libunwind implementation that we
# should use.
hasSystemLibunwind = final.isFreeBSD || final.isDarwin;
Comment on lines +197 to +199
Copy link
Member

@RossComputerGuy RossComputerGuy Mar 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works since we have multiple unwinder implementations.

  • LLVM libunwind
  • Darwin libunwind
  • non-GNU libunwind
  • GCC's unwinder

Instead, I think treating it like an enum like #365057 does works best imo.


# 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)
Expand Down
100 changes: 67 additions & 33 deletions pkgs/development/compilers/llvm/common/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -768,23 +768,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
''
)
Expand All @@ -798,16 +803,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" ];
}
);
Expand All @@ -820,9 +839,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
];
Expand All @@ -832,14 +849,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
''
)
Expand All @@ -853,16 +883,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" ];
}
);
Expand All @@ -889,7 +923,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";
}
);
Expand All @@ -914,7 +948,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";
}
);
Expand All @@ -935,7 +969,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";
}
);
Expand All @@ -951,7 +985,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
Expand Down
23 changes: 17 additions & 6 deletions pkgs/development/compilers/llvm/common/libcxx/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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.hostPlatform.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.hostPlatform.isWasm) [
"-DLIBCXXABI_USE_COMPILER_RT=ON"
] ++ lib.optionals (!stdenv.hostPlatform.hasThreads) [
"-DLIBCXXABI_ENABLE_THREADS=OFF"
] ++ lib.optionals (!stdenv.hostPlatform.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.hostPlatform.hasLocalization) [
"-DLIBCXX_ENABLE_LOCALIZATION=OFF"
] ++ lib.optionals (!stdenv.hostPlatform.hasMonotonicClock) [
"-DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF"
];

cxxCMakeFlags = [
Expand All @@ -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.hostPlatform.hasThreads) [
"-DLIBCXX_ENABLE_THREADS=OFF"
] ++ lib.optionals (!stdenv.hostPlatform.hasFilesystem) [
"-DLIBCXX_ENABLE_FILESYSTEM=OFF"
] ++ lib.optionals (!stdenv.hostPlatform.hasExceptions) [
"-DLIBCXX_ENABLE_EXCEPTIONS=OFF"
] ++ lib.optionals stdenv.hostPlatform.isWindows [
# https://github.com/llvm/llvm-project/issues/55245
Expand Down Expand Up @@ -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.hostPlatform.hasStackUnwinding && (
!stdenv.hostPlatform.hasSystemLibunwind
# TODO: Why is this needed on Darwin, but not on FreeBSD?
|| stdenv.hostPlatform.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
Expand Down