Before this commit, cc-wrapper/default.nix was using
`isGccArchSupported` to validate `-mtune=` values. This has two
problems:
- On x86, `-mtune=` can take the same values as `-march`, plus two
additional values `generic` and `intel` which are not valid for
`-march`.
- On ARM, `-mtune=` does not take the same values as `-march=`;
instead it takes the same values as `-mcpu`.
This commit fixes these two problems by adding a new
`isGccTuneSupported` function. For `isx86` this returns `true` for
the two special values and otherwise defers to `isGccArchSupported`.
This commit also adds support for `-mtune=` on Aarch64.
Unfortunately on Aarch64, Clang does not accept as wide a variety of
`-mtune=` values as Gcc does. In particular, Clang does not tune
for big.LITTLE mixed-model chips like the very popular RK3399, which
is targeted using `-march=cortex-a72.cortex-a53` in gcc.
To address this problem, this commit also adds a function
`findBestTuneApproximation` which can be used to map
clang-unsupported tunings like `cortex-a72.cortex-a53` to
less-precise tunings like `cortex-a53`.
The work which led to this commit arose because we now have
packages, like `crosvm`, which use *both* `clang` *and* `gcc`.
Previously I had been using `overrideAttrs` to set
`NIX_CFLAGS_COMPILE` on a package-by-package basis based on which
compiler that package used. Since we now have packages which use
*both* compilers, this strategy no longer works.
I briefly considered splitting `NIX_CFLAGS_COMPILE` into
`NIX_CFLAGS_COMPILE_GCC` and `NIX_CFLAGS_COMPILE_CLANG`, but since
`NIX_CFLAGS_COMPILE` is sort of a hack to begin with I figured that
adding the logic to `cc-wrapper` would be preferable.
Removed workaround from llvm 16.
Fixes including cxxabi.h on llvm >=15 libcxxStdenv.
```c
int main() {}
```
```
/nix/store/qwnvng0cbyx0bijm654jpmpl0516hfhx-libcxxabi-15.0.7-dev/include/cxxabi.h:20:10: fatal error: '__cxxabi_config.h' file not found
```
Before llvm 15 this used to work because `libcxx` copied the headers
from `cxxabi` to it's own `include`, which was then picked up by the
line above this one
Alternative fix would be to copy all files from `${cxxabi.dev}/include/c++/v1` to `${cxxabi.dev}/include` so the cc-wrapper setup hook would pick them up, but that would depend on in cxxabi being in buildInputs.
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
Without this, pkgsStatic.pkgsLLVM.hello fails with segfaulting binaries
because of the issue described at [0].
In summary, llvm's linker has a different behaviour to GCC's when
supplied with both -static and -Wl,-dynamic-linker=...; GCC copes with
it, but LLVM produces a binary which segfaults on startup. It appears to
be necessary to omit the dynamic linker in this case.
nixpkgs' static adaptor passes -static via NIX_CFLAGS_LINK which was not
accounted for prior to this commit in the checkLinkType logic. For good
measure I put the other NIX_ flags affecting link in the same logic.
Additionally, $NIX_CFLAGS_LINK_@suffixSalt@ is not available until later
than it was originally set, so set $linkType close to its point of use.
I checked for earlier uses by studying the shell trace output and
couldn't find any.
[0] https://github.com/NixOS/nixpkgs/issues/111010#issuecomment-1536424163
Signed-off-by: Peter Waller <p@pwaller.net>
this splits hardeningCFlags into hardeningCFlagsAfter and
hardeningCFlagsBefore (where most flags still remain) to allow
us to *append* `-D_FORTIFY_SOURCE=` values to the command-line,
forcing our choice of fortify level and avoiding potential
redefinition warnings/errors through use of `-U_FORTIFY_SOURCE`
The Darwin stdenv rework conditionally sets `NIX_CC_USE_RESPONSE_FILE`
depending on the `ARG_MAX` of the build system. If it is at least 1 MiB,
the stdenv passes the arguments on the command-line (like Linux).
Otherwise, it falls back to the response file. This was done to prevent
intermitent failures with clang 16 being unable to read the response
file. Unfortunately, this breaks `gccStdenv` on older Darwin platforms.
Note: While the stdenv logic will also be reverted, this change is
needed for compatibility with clang 16.
GCC is capable of using a response file, but it does not work correctly
when the response file is a file descriptor. This can be reproduced
using the following sequence of commands:
$ nix shell nixpkgs#gcc; NIX_CC_USE_RESPONSE_FILE=1 gcc
# Linux
/nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: unrecognized option '-B/nix/store/vnwdak3n1w2jjil119j65k8mw1z23p84-glibc-2.35-224/lib/'
/nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
# Darwin
ld: unknown option: -mmacosx-version-min=11.0
collect2: error: ld returned 1 exit status
Instead of using process substitution, create a temporary file and
remove it in a trap. This should also prevent the intermitent build
failures with clang 16 on older Darwin systems.
Fixes#245167
When a response file is in use, "$*" contains the response file and not
the parameters; both the linker and compiler wrappers are updated to use
the response-expanded params.
The compiler driver likes to pass parameters to the linker via a
response file, including -shared.
LLD rejects the combination of (-shared -pie), whereas other linkers
silently ignore the contradiction:
```
ld.lld: error: -shared and -pie may not be used together
```
This breaks certain configurations using LLD as a linker.
Changing `add-hardening.sh` results in a full rebuild. To avoid the
rebuild, here is a quick test case which shows the new hardening script
allows the link to succeed:
```
{ pkgs ? import <nixpkgs> {} }:
let
# gcc silently accepts -shared -pie together, lld does not.
linker = pkgs.wrapBintoolsWith { bintools = pkgs.llvmPackages.lld; };
patchWrapper = prev: prev.overrideAttrs (final: prev: let
prevScript = builtins.match (".*(/nix/store/[a-z0-9]+-add-hardening.sh).*") prev.postFixup;
in {
postFixup = (builtins.replaceStrings prevScript ["${./new-add-hardening.sh}"] prev.postFixup);
});
in
pkgs.stdenv.mkDerivation {
name = "nixpkgs-hardening-bug";
src = pkgs.writeText "src.c" "int main(int argc, char* argv[]) { return 0; }";
NIX_HARDENING_ENABLE = "pie";
unpackPhase = ":";
buildPhase = ''
$CC -c -o src.o $src
bash -x ${patchWrapper linker}/bin/ld.lld -o $out @${pkgs.writeText "responsefile" "-shared"} src.o
'';
}
```
Fixes: #178162
Signed-off-by: Peter Waller <p@pwaller.net>
Our gcc_multi and glibc_multi expressions merge together a
32-bit-targeted and 64-bit-targeted gcc. However they do not thread
through the passthru.libgcc from these merged gccs.
This commit corrects that.
It also extends passthru.libgcc to allow a *list* rather than just a
single outpath.
Resolves part of #221891 (at least getting it back to the error
message it gave before).
According to <https://gcc.gnu.org/legacy-ml/gcc-patches/2015-08/msg00836.html>,
all code is position-independent on Windows. Some compilers
apparently warn for -fPIC on Windows, and clang errors:
> clang-15: error: unsupported option '-fPIC' for target 'x86_64-pc-windows-msvc'
I'm guessing the check was hostPlatform instead of targetPlatform by mistake.
In https://github.com/NixOS/nixpkgs/pull/209870 I tried to unify the
treatment of clang and gcc in cc-wrapper as much as possible.
However it appears that I went too far.
Clang requires -isystem flags in order to be able to find gcc's
libstdc++. Gcc does not need these flags. If they are added,
gfortran will get confused:
https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903
This commit deunifies the chunk of code that adds the -isystem
flags, and explains why this chunk applies only to clang.