cc-wrapper: fix -mtune= validation, add ARM, add fallbacks
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.
This commit is contained in:
parent
0f9bb8236a
commit
0b2036cad0
@ -110,7 +110,20 @@ let
|
||||
gccForLibs_solib = getLib gccForLibs
|
||||
+ optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}";
|
||||
|
||||
# older compilers (for example bootstrap's GCC 5) fail with -march=too-modern-cpu
|
||||
# The following two functions, `isGccArchSupported` and
|
||||
# `isGccTuneSupported`, only handle those situations where a flag
|
||||
# (`-march` or `-mtune`) is accepted by one compiler but rejected
|
||||
# by another, and both compilers are relevant to nixpkgs. We are
|
||||
# not trying to maintain a complete list of all flags accepted by
|
||||
# all versions of all compilers ever in nixpkgs.
|
||||
#
|
||||
# The two main cases of interest are:
|
||||
#
|
||||
# - One compiler is gcc and the other is clang
|
||||
# - One compiler is pkgs.gcc and the other is bootstrap-files.gcc
|
||||
# -- older compilers (for example bootstrap's GCC 5) fail with
|
||||
# -march=too-modern-cpu
|
||||
|
||||
isGccArchSupported = arch:
|
||||
if targetPlatform.isPower then false else # powerpc does not allow -march=
|
||||
if isGNU then
|
||||
@ -159,6 +172,51 @@ let
|
||||
else
|
||||
false;
|
||||
|
||||
isGccTuneSupported = tune:
|
||||
# for x86 -mtune= takes the same values as -march, plus two more:
|
||||
if targetPlatform.isx86 then
|
||||
{
|
||||
generic = true;
|
||||
intel = true;
|
||||
}.${tune} or (isGccArchSupported tune)
|
||||
# on arm64, the -mtune= values are specific processors
|
||||
else if targetPlatform.isAarch64 then
|
||||
(if isGNU then
|
||||
{
|
||||
cortex-a53 = versionAtLeast ccVersion "4.8"; # gcc 8c075f
|
||||
cortex-a72 = versionAtLeast ccVersion "5.1"; # gcc d8f70d
|
||||
"cortex-a72.cortex-a53" = versionAtLeast ccVersion "5.1"; # gcc d8f70d
|
||||
}.${tune} or false
|
||||
else if isClang then
|
||||
{
|
||||
cortex-a53 = versionAtLeast ccVersion "3.9"; # llvm dfc5d1
|
||||
}.${tune} or false
|
||||
else false)
|
||||
else if targetPlatform.isPower then
|
||||
# powerpc does not support -march
|
||||
true
|
||||
else if targetPlatform.isMips then
|
||||
# for mips -mtune= takes the same values as -march
|
||||
isGccArchSupported tune
|
||||
else
|
||||
false;
|
||||
|
||||
# Clang does not support as many `-mtune=` values as gcc does;
|
||||
# this function will return the best possible approximation of the
|
||||
# provided `-mtune=` value, or `null` if none exists.
|
||||
#
|
||||
# Note: this function can make use of ccVersion; for example, `if
|
||||
# versionOlder ccVersion "12" then ...`
|
||||
findBestTuneApproximation = tune:
|
||||
let guess = if isClang
|
||||
then {
|
||||
# clang does not tune for big.LITTLE chips
|
||||
"cortex-a72.cortex-a53" = "cortex-a72";
|
||||
}.${tune} or tune
|
||||
else tune;
|
||||
in if isGccTuneSupported guess
|
||||
then guess
|
||||
else null;
|
||||
|
||||
darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin (
|
||||
if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx"
|
||||
@ -559,10 +617,12 @@ stdenv.mkDerivation {
|
||||
+ optionalString (targetPlatform ? gcc.thumb) ''
|
||||
echo "-m${if targetPlatform.gcc.thumb then "thumb" else "arm"}" >> $out/nix-support/cc-cflags-before
|
||||
''
|
||||
+ optionalString (targetPlatform ? gcc.tune &&
|
||||
isGccArchSupported targetPlatform.gcc.tune) ''
|
||||
echo "-mtune=${targetPlatform.gcc.tune}" >> $out/nix-support/cc-cflags-before
|
||||
''
|
||||
+ (let tune = if targetPlatform ? gcc.tune
|
||||
then findBestTuneApproximation targetPlatform.gcc.tune
|
||||
else null;
|
||||
in optionalString (tune != null) ''
|
||||
echo "-mtune=${tune}" >> $out/nix-support/cc-cflags-before
|
||||
'')
|
||||
|
||||
# TODO: categorize these and figure out a better place for them
|
||||
+ optionalString targetPlatform.isWindows ''
|
||||
|
Loading…
Reference in New Issue
Block a user