From 7a90ea48980f38f5bb26a7d1141188e01a21ddc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= <viric@viric.name>
Date: Fri, 20 Dec 2024 20:03:54 +0100
Subject: [PATCH] Finally gcc_offload built

But it cannot target gfx1103 - that probably requires the
rocmPackages.llvm that is broken.
---
 pkgs/build-support/cc-wrapper/default.nix     |  8 ++++++-
 .../compilers/gcc/common/builder.nix          | 12 +++++++++-
 .../compilers/gcc/common/configure-flags.nix  | 22 +++++++++++++------
 .../compilers/gcc/common/dependencies.nix     | 14 +++++++++++-
 .../gcc/common/extra-target-flags.nix         |  2 +-
 .../compilers/gcc/common/strip-attributes.nix |  2 +-
 pkgs/development/compilers/gcc/default.nix    |  2 +-
 pkgs/top-level/all-packages.nix               | 22 ++++++++++++++-----
 8 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 001123fe3d857..06227ce354ab8 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -21,6 +21,7 @@
 , gnugrep ? null
 , expand-response-params
 , libcxx ? null
+, extraCompilerB ? []
 
 # Whether or not to add `-B` and `-L` to `nix-support/cc-{c,ld}flags`
 , useCcForLibs ?
@@ -614,7 +615,12 @@ stdenvNoCC.mkDerivation {
       ccLDFlags+=" -L${cc_solib}/lib"
       ccCFlags+=" -B${cc_solib}/lib"
 
-    '' + optionalString (cc.langAda or false && !isArocc) ''
+    '' + (concatMapStrings (p: ''
+        ccCFlags+=" -B${p}/libexec/gcc/${stdenvNoCC.buildPlatform.config}/${p.version}"
+        ccCFlags+=" -B${p}/bin"
+        ccCFlags+=" -foffload-options=-Wl,-L${p}/${p.stdenv.targetPlatform.config}/lib"
+      '') extraCompilerB)
+    + optionalString (cc.langAda or false && !isArocc) ''
       touch "$out/nix-support/gnat-cflags"
       touch "$out/nix-support/gnat-ldflags"
       basePath=$(echo $cc/lib/*/*/*)
diff --git a/pkgs/development/compilers/gcc/common/builder.nix b/pkgs/development/compilers/gcc/common/builder.nix
index 1b3754dad6bd7..44925dc030279 100644
--- a/pkgs/development/compilers/gcc/common/builder.nix
+++ b/pkgs/development/compilers/gcc/common/builder.nix
@@ -3,6 +3,7 @@
   stdenv,
   enableMultilib,
   targetConfig,
+  version,
 }:
 
 let
@@ -169,6 +170,10 @@ originalAttrs:
       fi
 
       eval "$oldOpts"
+    '' +  lib.optionalString (targetConfig == "amdgcn-amdhsa") ''
+      makeFlagsArray=''${makeFlagsArray[@]/CFLAGS_FOR_TARGET=*}
+      makeFlagsArray=''${makeFlagsArray[@]/CXXFLAGS_FOR_TARGET=*}
+      makeFlagsArray=''${makeFlagsArray[@]/FLAGS_FOR_TARGET=*}
     '';
 
     preConfigure =
@@ -219,7 +224,7 @@ originalAttrs:
         # symlink), this ensures that in every case we can assume that
         # $lib/lib contains the .so files
         lib.optionalString (with stdenv; targetPlatform.config != hostPlatform.config) ''
-          ln -Ts "''${!outputLib}/''${targetConfig}/lib" $lib/lib
+          ln -Ts "''${!outputLib}/''${targetConfig}/lib" "''${!outputLib}/lib"
         ''
       +
         # Make `lib64` symlinks to `lib`.
@@ -312,6 +317,11 @@ originalAttrs:
               ln -sf "$man_prefix"gcc.1 "$i"
           fi
       done
+    '' + lib.optionalString (targetConfig == "amdgcn-amdhsa") ''
+      for a in ld as ar nm runlib; do
+        ln -s $(type -P amdgcn-amdhsa-$a) \
+           $out/lib/gcc/x86_64-unknown-linux-gnu/${version}/accel/amdgcn-amdhsa/$a
+      done
     '';
   }
 ))
diff --git a/pkgs/development/compilers/gcc/common/configure-flags.nix b/pkgs/development/compilers/gcc/common/configure-flags.nix
index f686d2880a51d..703d971492c30 100644
--- a/pkgs/development/compilers/gcc/common/configure-flags.nix
+++ b/pkgs/development/compilers/gcc/common/configure-flags.nix
@@ -85,9 +85,11 @@ let
       # See Note [Windows Exception Handling]
       "--enable-sjlj-exceptions"
       "--with-dwarf2"
-    ] else [
-      (if crossDarwin then "--with-sysroot=${lib.getLib libcCross}/share/sysroot"
-       else                "--with-headers=${lib.getDev libcCross}${libcCross.incdir or "/include"}")
+    ] else (
+      lib.optional crossDarwin "--with-sysroot=${lib.getLib libcCross}/share/sysroot"
+      ++ lib.optional (!crossDarwin && targetPlatform.config != "amdgcn-amdhsa")
+        "--with-sysroot=${lib.getLib libcCross}/share/sysroot"
+      ++ [
       "--enable-__cxa_atexit"
       "--enable-long-long"
       "--enable-threads=${if targetPlatform.isUnix then "posix"
@@ -98,9 +100,10 @@ let
       # libsanitizer requires netrom/netrom.h which is not
       # available in uclibc.
       "--disable-libsanitizer"
-    ] ++ lib.optional (targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") "--with-newlib"
+    ] ++ lib.optional ((targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") &&
+            targetPlatform.config != "amdgcn-amdhsa") "--with-newlib"
       ++ lib.optional (targetPlatform.libc == "avrlibc") "--with-avrlibc"
-    );
+    ));
 
   configureFlags =
     # Basic dependencies
@@ -111,7 +114,7 @@ let
       "--with-mpfr-lib=${mpfr.out}/lib"
       "--with-mpc=${libmpc}"
     ]
-    ++ lib.optionals (!withoutTargetLibc) [
+    ++ lib.optionals (!withoutTargetLibc && targetPlatform.config != "amdgcn-amdhsa") [
       (if libcCross == null
        then (
         # GCC will search for the headers relative to SDKROOT on Darwin, so it will find them in the store.
@@ -161,7 +164,12 @@ let
       "--disable-libstdcxx-pch"
       "--without-included-gettext"
       "--with-system-zlib"
+    ] ++ lib.optionals (targetPlatform.config != "amdgcn-amdhsa") [
       "--enable-static"
+    ] ++ lib.optionals (targetPlatform.config == "amdgcn-amdhsa") [
+      "--disable-sjlj-exceptions"
+      "--disable-libquadmath"
+    ] ++ [
       "--enable-languages=${
         lib.concatStringsSep ","
           (  lib.optional langC        "c"
@@ -210,7 +218,7 @@ let
     ++ lib.optionals (targetPlatform != hostPlatform) crossConfigureFlags
     ++ lib.optional disableBootstrap' "--disable-bootstrap"
     ++ lib.optionals (targetPlatform.config == "amdgcn-amdhsa") [
-      "--target=amdgcn--amdhsa" "--enable-as-accelerator-for=x86_64-pc-linux-gnu"
+      "--target=amdgcn-amdhsa" "--enable-as-accelerator-for=x86_64-unknown-linux-gnu"
     ]
     # Platform-specific flags
     ++ lib.optional (targetPlatform == hostPlatform && targetPlatform.isx86_32) "--with-arch=${stdenv.hostPlatform.parsed.cpu.name}"
diff --git a/pkgs/development/compilers/gcc/common/dependencies.nix b/pkgs/development/compilers/gcc/common/dependencies.nix
index d3726cc43cca5..f679ca35064c8 100644
--- a/pkgs/development/compilers/gcc/common/dependencies.nix
+++ b/pkgs/development/compilers/gcc/common/dependencies.nix
@@ -31,11 +31,23 @@
 let
   inherit (lib) optionals;
   inherit (stdenv) buildPlatform hostPlatform targetPlatform;
+
+  ## llvm18 fails with gcc <14
+  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114419
+  llvmAmd = buildPackages.runCommand "${buildPackages.llvm.name}-wrapper" {} ''
+    mkdir -p $out/bin
+    for a in ar nm ranlib; do
+      ln -s ${buildPackages.llvmPackages.llvm}/bin/llvm-$a $out/bin/amdgcn-amdhsa-$a
+    done
+    ln -s ${buildPackages.llvmPackages.llvm}/bin/llvm-mc $out/bin/amdgcn-amdhsa-as
+    ln -s ${buildPackages.llvmPackages.lld}/bin/lld $out/bin/amdgcn-amdhsa-ld
+  '';
 in
 
 {
   # same for all gcc's
-  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  depsBuildBuild = [ buildPackages.stdenv.cc ] ++
+      lib.optional (targetPlatform.config == "amdgcn-amdhsa") llvmAmd;
 
   nativeBuildInputs =
     [
diff --git a/pkgs/development/compilers/gcc/common/extra-target-flags.nix b/pkgs/development/compilers/gcc/common/extra-target-flags.nix
index de1f35f7f0fec..d709f7e281cd4 100644
--- a/pkgs/development/compilers/gcc/common/extra-target-flags.nix
+++ b/pkgs/development/compilers/gcc/common/extra-target-flags.nix
@@ -23,7 +23,7 @@ in
           [
             "-O2 -idirafter ${lib.getDev dep}${dep.incdir or "/include"}"
           ]
-          ++ lib.optionals (!withoutTargetLibc) [
+          ++ lib.optionals (!withoutTargetLibc && targetPlatform.config != "amdgcn-amdhsa") [
             "-B${lib.getLib dep}${dep.libdir or "/lib"}"
           ]
         );
diff --git a/pkgs/development/compilers/gcc/common/strip-attributes.nix b/pkgs/development/compilers/gcc/common/strip-attributes.nix
index 3871d84664959..88150c324918d 100644
--- a/pkgs/development/compilers/gcc/common/strip-attributes.nix
+++ b/pkgs/development/compilers/gcc/common/strip-attributes.nix
@@ -57,7 +57,7 @@
         )
         popd
     ''
-    + lib.optionalString (!langJit) ''
+    + lib.optionalString (!langJit && stdenv.targetPlatform.config != "amdgcn-amdhsa") ''
       ${
         # keep indentation
         ""
diff --git a/pkgs/development/compilers/gcc/default.nix b/pkgs/development/compilers/gcc/default.nix
index e28473d02ebb6..5b3ca99cd9160 100644
--- a/pkgs/development/compilers/gcc/default.nix
+++ b/pkgs/development/compilers/gcc/default.nix
@@ -194,7 +194,7 @@ pipe ((callFile ./common/builder.nix {}) ({
 
   inherit patches;
 
-  outputs = [ "out" "man" "info" ] ++ optional (!langJit) "lib";
+  outputs = [ "out" "man" "info" ] ++ optional (!langJit && targetPlatform.config != "amdgcn-amdhsa") "lib";
 
   setOutputFlags = false;
 
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 2d9c9abe2461d..05de591f256b4 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -6211,6 +6211,17 @@ with pkgs;
 
   gccCrossLibcStdenv = overrideCC stdenvNoCC buildPackages.gccWithoutTargetLibc;
 
+  amdgcc = pkgsCross.amdgcn.buildPackages.gcc_latest.cc.override {
+    langCC = true;
+    # enableLTO = false;
+    # enableMultilib = true;
+    withoutTargetLibc = false;
+    enableShared = false;
+    noSysDirs = false;
+    libcCross = binutilsNoLibc.libc;
+    targetPackages.stdenv.cc.bintools = binutilsNoLibc;
+  };
+
   # The GCC used to build libc for the target platform. Normal gccs will be
   # built with, and use, that cross-compiled libc.
   gccWithoutTargetLibc = assert stdenv.targetPlatform != stdenv.hostPlatform; let
@@ -6249,11 +6260,12 @@ with pkgs;
 
   gcc_latest = gcc14;
 
-  gcc_offload = wrapCC (gcc.cc.override {
-    enableOffload = true;
-  });
-
-  amdgcc = pkgsCross.amdgcn.buildPackages.gcc;
+  gcc_offload = wrapCCWith {
+    cc = gcc_latest.cc.override {
+      enableOffload = true;
+    };
+    extraCompilerB = [ amdgcc ];
+  };
 
   libgccjit = gcc.cc.override {
     name = "libgccjit";