Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib.systems: add various has* flags useful for embedded systems #352629

Open
wants to merge 1 commit into
base: staging
Choose a base branch
from
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 @@ -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);
kuruczgy marked this conversation as resolved.
Show resolved Hide resolved

# 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 @@ -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
''
)
Expand All @@ -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" ];
}
);
Expand All @@ -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
];
Expand All @@ -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
''
)
Expand All @@ -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" ];
}
);
Expand All @@ -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";
}
);
Expand All @@ -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";
}
);
Expand All @@ -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";
}
);
Expand All @@ -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
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.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 = [
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.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
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.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
Expand Down
Loading