Skip to content

Commit

Permalink
lib.systems: add various has* flags useful for embedded systems
Browse files Browse the repository at this point in the history
  • Loading branch information
kuruczgy committed Dec 7, 2024
1 parent 2b4c300 commit e76ac5d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 39 deletions.
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);

# 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

0 comments on commit e76ac5d

Please sign in to comment.