From 5d87bc2650221763d5378bd8cdbd6b84a11b2162 Mon Sep 17 00:00:00 2001
From: volth <volth@volth.com>
Date: Sun, 21 Apr 2019 16:13:37 +0000
Subject: [PATCH] fix bootstrap when platform.gcc.arch=="skylake"

---
 pkgs/build-support/cc-wrapper/default.nix     | 25 +++++++++++++++++--
 .../compilers/gcc/common/platform-flags.nix   |  2 +-
 pkgs/stdenv/generic/make-derivation.nix       |  3 +++
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 4d4dbc640b28..91948f415714 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -63,6 +63,25 @@ let
     then import ../expand-response-params { inherit (buildPackages) stdenv; }
     else "";
 
+  # older compilers (for example bootstrap's GCC 5) fail with -march=too-modern-cpu
+  isGccArchSupported = arch:
+    if cc.isGNU or false then
+      { skylake        = versionAtLeast ccVersion "6.0";
+        skylake-avx512 = versionAtLeast ccVersion "6.0";
+        cannonlake     = versionAtLeast ccVersion "8.0";
+        icelake-client = versionAtLeast ccVersion "8.0";
+        icelake-server = versionAtLeast ccVersion "8.0";
+        knm            = versionAtLeast ccVersion "8.0";
+      }.${arch} or true
+    else if cc.isClang or false then
+      { cannonlake     = versionAtLeast ccVersion "5.0";
+        icelake-client = versionAtLeast ccVersion "7.0";
+        icelake-server = versionAtLeast ccVersion "7.0";
+        knm            = versionAtLeast ccVersion "7.0";
+      }.${arch} or true
+    else
+      false;
+
 in
 
 # Ensure bintools matches
@@ -287,7 +306,8 @@ stdenv.mkDerivation {
     # 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) ''
+    + optionalString ((targetPlatform ? platform.gcc.arch || targetPlatform.parsed.cpu ? arch) &&
+                      isGccArchSupported targetPlatform.platform.gcc.arch or targetPlatform.parsed.cpu.arch) ''
       echo "-march=${targetPlatform.platform.gcc.arch or targetPlatform.parsed.cpu.arch}" >> $out/nix-support/cc-cflags-before
     ''
 
@@ -309,7 +329,8 @@ stdenv.mkDerivation {
     + optionalString (targetPlatform ? platform.gcc.mode) ''
       echo "-mmode=${targetPlatform.platform.gcc.mode}" >> $out/nix-support/cc-cflags-before
     ''
-    + optionalString (targetPlatform ? platform.gcc.tune) ''
+    + optionalString (targetPlatform ? platform.gcc.tune &&
+                      isGccArchSupported targetPlatform.platform.gcc.tune) ''
       echo "-mtune=${targetPlatform.platform.gcc.tune}" >> $out/nix-support/cc-cflags-before
     ''
 
diff --git a/pkgs/development/compilers/gcc/common/platform-flags.nix b/pkgs/development/compilers/gcc/common/platform-flags.nix
index ba6d5912fe88..f3cdce411939 100644
--- a/pkgs/development/compilers/gcc/common/platform-flags.nix
+++ b/pkgs/development/compilers/gcc/common/platform-flags.nix
@@ -4,7 +4,7 @@ let
   p =  targetPlatform.platform.gcc or {}
     // targetPlatform.parsed.abi;
 in lib.concatLists [
-  (lib.optional (p ? arch) "--with-arch=${p.arch}")
+  (lib.optional (!targetPlatform.isx86_64 && p ? arch) "--with-arch=${p.arch}") # --with-arch= is unknown flag on x86_64
   (lib.optional (p ? cpu) "--with-cpu=${p.cpu}")
   (lib.optional (p ? abi) "--with-abi=${p.abi}")
   (lib.optional (p ? fpu) "--with-fpu=${p.fpu}")
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index 417c10363b52..cd239638418d 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -253,6 +253,9 @@ in rec {
           enableParallelChecking = attrs.enableParallelChecking or true;
         } // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != []) {
           NIX_HARDENING_ENABLE = enabledHardeningOptions;
+        } // lib.optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform.platform.gcc.arch or stdenv.hostPlatform.parsed.cpu.arch or "x86-64" != "x86-64") {
+          requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.platform.gcc.arch or stdenv.hostPlatform.parsed.cpu.arch}" ];
+          NIX_ENFORCE_NO_NATIVE = true;
         } // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) {
           inherit __darwinAllowLocalNetworking;
           # TODO: remove lib.unique once nix has a list canonicalization primitive