From d180cb98503d2dc1e51d8c14b4a567e1ed3e996d Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Tue, 9 Apr 2019 14:21:54 -0400 Subject: [PATCH] cc-wrapper: make machine configuration configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is useful to make these dynamic and not bake them into gcc. This means we don’t have to rebuild gcc to change these values. Instead, we will pass cflags to gcc based on platform values. This was already done hackily for android gcc (which is multi-target), but not for our own gccs which are single target. To accomplish this, we need to add a few things: - add ‘arch’ to cpu - add NIX_CFLAGS_COMPILE_BEFORE flag (goes before args) - set -march everywhere - set mcpu, mfpu, mmode, and mtune based on targetPlatform.gcc flags cc-wrapper: only set -march when it is in the cpu type Some architectures don’t have a good mapping of -march. For instance POWER architecture doesn’t support the -march flag at all! https://gcc.gnu.org/onlinedocs/gcc/RS_002f6000-and-PowerPC-Options.html#RS_002f6000-and-PowerPC-Options --- lib/systems/parse.nix | 34 ++++++------ pkgs/build-support/cc-wrapper/add-flags.sh | 5 ++ pkgs/build-support/cc-wrapper/cc-wrapper.sh | 2 +- pkgs/build-support/cc-wrapper/default.nix | 53 ++++++++++++++----- .../androidndk-pkgs/androidndk-pkgs.nix | 21 +------- 5 files changed, 64 insertions(+), 51 deletions(-) diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 3e23a721f0d9..cd0a11c058e6 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -69,24 +69,24 @@ rec { cpuTypes = with significantBytes; setTypes types.openCpuType { arm = { bits = 32; significantByte = littleEndian; family = "arm"; }; - armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; }; - armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; }; - armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; }; - armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; - armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; - armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; - armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; - armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; - armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; - armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; - aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; }; - aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; }; + armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; }; + armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; }; + armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6"; }; + armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-a"; }; + armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-r"; }; + armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-m"; }; + armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7"; }; + armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; }; + armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; }; + armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-m"; }; + aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; }; + aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; arch = "armv8-a"; }; - i386 = { bits = 32; significantByte = littleEndian; family = "x86"; }; - i486 = { bits = 32; significantByte = littleEndian; family = "x86"; }; - i586 = { bits = 32; significantByte = littleEndian; family = "x86"; }; - i686 = { bits = 32; significantByte = littleEndian; family = "x86"; }; - x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; }; + i386 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i386"; }; + i486 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i486"; }; + i586 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i586"; }; + i686 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i686"; }; + x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; arch = "x86-64"; }; mips = { bits = 32; significantByte = bigEndian; family = "mips"; }; mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; }; diff --git a/pkgs/build-support/cc-wrapper/add-flags.sh b/pkgs/build-support/cc-wrapper/add-flags.sh index 9762894607ac..1358b167f6ec 100644 --- a/pkgs/build-support/cc-wrapper/add-flags.sh +++ b/pkgs/build-support/cc-wrapper/add-flags.sh @@ -6,6 +6,7 @@ var_templates_list=( NIX+CFLAGS_COMPILE + NIX+CFLAGS_COMPILE_BEFORE NIX+CFLAGS_LINK NIX+CXXSTDLIB_COMPILE NIX+CXXSTDLIB_LINK @@ -43,5 +44,9 @@ if [ -e @out@/nix-support/cc-ldflags ]; then NIX_@infixSalt@_LDFLAGS+=" $(< @out@/nix-support/cc-ldflags)" fi +if [ -e @out@/nix-support/cc-cflags-before ]; then + NIX_@infixSalt@_CFLAGS_COMPILE_BEFORE="$(< @out@/nix-support/cc-cflags-before) $NIX_@infixSalt@_CFLAGS_COMPILE_BEFORE" +fi + # That way forked processes will not extend these environment variables again. export NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET=1 diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh index 8003fe1d8f38..bb7890100087 100644 --- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh @@ -135,7 +135,7 @@ source @out@/nix-support/add-hardening.sh # Add the flags for the C compiler proper. extraAfter=($NIX_@infixSalt@_CFLAGS_COMPILE) -extraBefore=(${hardeningCFlags[@]+"${hardeningCFlags[@]}"}) +extraBefore=(${hardeningCFlags[@]+"${hardeningCFlags[@]}"} $NIX_@infixSalt@_CFLAGS_COMPILE_BEFORE) if [ "$dontLink" != 1 ]; then diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 9569c6e78c8a..4d4dbc640b28 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -279,24 +279,51 @@ stdenv.mkDerivation { export hardening_unsupported_flags="${builtins.concatStringsSep " " (cc.hardeningUnsupportedFlags or [])}" '' + # Machine flags. These are necessary to support + + # TODO: We should make a way to support miscellaneous machine + # flags and other gcc flags as well. + + # Always add -march based on cpu in triple. Sometimes there is a + # discrepency (x86_64 vs. x86-64), so we provide an "arch" arg in + # that case. + + optionalString (targetPlatform ? platform.gcc.arch || targetPlatform.parsed.cpu ? arch) '' + echo "-march=${targetPlatform.platform.gcc.arch or targetPlatform.parsed.cpu.arch}" >> $out/nix-support/cc-cflags-before + '' + + # -mcpu is not very useful. You should use mtune and march + # instead. It’s provided here for backwards compatibility. + + optionalString (targetPlatform ? platform.gcc.cpu) '' + echo "-mcpu=${targetPlatform.platform.gcc.cpu}" >> $out/nix-support/cc-cflags-before + '' + + # -mfloat-abi only matters on arm32 but we set it here + # unconditionally just in case. If the abi specifically sets hard + # vs. soft floats we use it here. + + optionalString (targetPlatform ? platform.gcc.float-abi || targetPlatform.parsed.abi ? float) '' + echo "-mfloat-abi=${targetPlatform.platform.gcc.float-abi or targetPlatform.parsed.abi.float}" >> $out/nix-support/cc-cflags-before + '' + + optionalString (targetPlatform ? platform.gcc.fpu) '' + echo "-mfpu=${targetPlatform.platform.gcc.fpu}" >> $out/nix-support/cc-cflags-before + '' + + optionalString (targetPlatform ? platform.gcc.mode) '' + echo "-mmode=${targetPlatform.platform.gcc.mode}" >> $out/nix-support/cc-cflags-before + '' + + optionalString (targetPlatform ? platform.gcc.tune) '' + echo "-mtune=${targetPlatform.platform.gcc.tune}" >> $out/nix-support/cc-cflags-before + '' + + # TODO: categorize these and figure out a better place for them + optionalString hostPlatform.isCygwin '' hardening_unsupported_flags+=" pic" - '' - - + optionalString targetPlatform.isMinGW '' + '' + optionalString targetPlatform.isMinGW '' hardening_unsupported_flags+=" stackprotector" - '' - - + optionalString targetPlatform.isAvr '' + '' + optionalString targetPlatform.isAvr '' hardening_unsupported_flags+=" stackprotector pic" - '' - - + optionalString targetPlatform.isNetBSD '' - hardening_unsupported_flags+=" stackprotector fortify" - '' - - + optionalString (targetPlatform.libc == "newlib") '' + '' + optionalString (targetPlatform.libc == "newlib") '' hardening_unsupported_flags+=" stackprotector fortify pie pic" + '' + optionalString targetPlatform.isNetBSD '' + hardening_unsupported_flags+=" stackprotector fortify" '' + optionalString (libc != null && targetPlatform.isAvr) '' diff --git a/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix b/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix index b62dc2def7f1..cca0f0d4adbc 100644 --- a/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix +++ b/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix @@ -90,26 +90,7 @@ rec { echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags echo "-resource-dir=$(echo ${androidndk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/${hostInfo.double}/lib*/clang/*)" >> $out/nix-support/cc-cflags echo "--gcc-toolchain=${androidndk}/libexec/android-sdk/ndk-bundle/toolchains/${targetInfo.toolchain}-${targetInfo.gccVer}/prebuilt/${hostInfo.double}" >> $out/nix-support/cc-cflags - '' - + lib.optionalString stdenv.targetPlatform.isAarch32 (let - p = stdenv.targetPlatform.platform.gcc or {} - // stdenv.targetPlatform.parsed.abi; - flags = lib.concatLists [ - (lib.optional (p ? arch) "-march=${p.arch}") - (lib.optional (p ? cpu) "-mcpu=${p.cpu}") - (lib.optional (p ? abi) "-mabi=${p.abi}") - (lib.optional (p ? fpu) "-mfpu=${p.fpu}") - (lib.optional (p ? float-abi) "-mfloat-abi=${p.float-abi}") - (lib.optional (p ? mode) "-mmode=${p.mode}") - ]; - in '' - sed -E -i \ - $out/bin/${stdenv.targetPlatform.config}-cc \ - $out/bin/${stdenv.targetPlatform.config}-c++ \ - $out/bin/${stdenv.targetPlatform.config}-clang \ - $out/bin/${stdenv.targetPlatform.config}-clang++ \ - -e 's|^(extraBefore=)\((.*)\)$|\1(\2 -Wl,--fix-cortex-a8 ${builtins.toString flags})|' - ''); + ''; }; # Bionic lib C and other libraries.