summary refs log tree commit diff
diff options
context:
space:
mode:
authorBoey Maun Suang <account-at-github@boeyms.info>2022-12-26 23:16:17 +1100
committerBoey Maun Suang <account-at-github@boeyms.info>2023-01-07 18:32:12 +1100
commit82b88d2db629a06443a6d7befb8518dbb785d183 (patch)
treed044a70eb6327142cf0227c0ff273fbdfbc50c6a
parent006a1d0a45d45273588bf85ef127e1140d506ac5 (diff)
downloadnixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar.gz
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar.bz2
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar.lz
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar.xz
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.tar.zst
nixpkgs-82b88d2db629a06443a6d7befb8518dbb785d183.zip
bintoolsDualAs: Add package
For reasons explained in the commit contents, in order to build the
native gnat package for x86_64-darwin, the native gnatboot package for
x86_64-darwin must have access to both the Clang integrated assembler
and the cctools GNU assembler for that platform.  This commit creates a
package with both of those assemblers that x86_64-darwin gnatboot can
then be wrapped with.
-rw-r--r--pkgs/build-support/bintools-wrapper/default.nix13
-rw-r--r--pkgs/os-specific/darwin/binutils/default.nix30
-rw-r--r--pkgs/top-level/all-packages.nix5
-rw-r--r--pkgs/top-level/darwin-packages.nix14
4 files changed, 59 insertions, 3 deletions
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix
index 121b50fe0f5..bc7c8fbd46a 100644
--- a/pkgs/build-support/bintools-wrapper/default.nix
+++ b/pkgs/build-support/bintools-wrapper/default.nix
@@ -28,6 +28,7 @@
 , buildPackages ? {}
 , targetPackages ? {}
 , useMacosReexportHack ? false
+, wrapGas ? false
 
 # Darwin code signing support utilities
 , postLinkSignHook ? null, signingUtils ? null
@@ -165,6 +166,18 @@ stdenv.mkDerivation {
       wrap ld-solaris ${./ld-solaris-wrapper.sh}
     '')
 
+    # If we are asked to wrap `gas` and this bintools has it,
+    # then symlink it (`as` will be symlinked next).
+    # This is mainly for the wrapped gnatboot on x86-64 Darwin,
+    # as it must have both the GNU assembler from cctools (installed as `gas`)
+    # and the Clang integrated assembler (installed as `as`).
+    # See pkgs/os-specific/darwin/binutils/default.nix for details.
+    + lib.optionalString wrapGas ''
+      if [ -e $ldPath/${targetPrefix}gas ]; then
+        ln -s $ldPath/${targetPrefix}gas $out/bin/${targetPrefix}gas
+      fi
+    ''
+
     # Create symlinks for rest of the binaries.
     + ''
       for binary in objdump objcopy size strings as ar nm gprof dwp c++filt addr2line \
diff --git a/pkgs/os-specific/darwin/binutils/default.nix b/pkgs/os-specific/darwin/binutils/default.nix
index c5bc50cafd7..3b1a2636873 100644
--- a/pkgs/os-specific/darwin/binutils/default.nix
+++ b/pkgs/os-specific/darwin/binutils/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, makeWrapper, binutils-unwrapped, cctools, llvm, clang-unwrapped }:
+{ lib, stdenv, makeWrapper, binutils-unwrapped, cctools, llvm, clang-unwrapped, dualAs ? false }:
 
 # Make sure both underlying packages claim to have prepended their binaries
 # with the same targetPrefix.
@@ -15,7 +15,7 @@ in
 
 # TODO: loop over targetPrefixed binaries too
 stdenv.mkDerivation {
-  pname = "${targetPrefix}cctools-binutils-darwin";
+  pname = "${targetPrefix}cctools-binutils-darwin" + lib.optionalString dualAs "-dualas";
   inherit (cctools) version;
   outputs = [ "out" "man" ];
   buildCommand = ''
@@ -59,9 +59,33 @@ stdenv.mkDerivation {
     rm $out/bin/${targetPrefix}as
     makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
       --add-flags "-x assembler -integrated-as -c"
+  ''
+  # x86-64 Darwin gnatboot emits assembly
+  # with MOVQ as the mnemonic for quadword interunit moves
+  # such as `movq %rbp, %xmm0`.
+  # The clang integrated assembler recognises this as valid,
+  # but unfortunately the cctools-port GNU assembler does not;
+  # it instead uses MOVD as the mnemonic.
+  # The assembly that a GCC build emits is determined at build time
+  # and cannot be changed afterwards.
+  #
+  # To build GNAT on x86-64 Darwin, therefore,
+  # we need both the clang _and_ the cctools-port assemblers to be available:
+  # the former to build at least the stage1 compiler,
+  # and the latter at least to be detectable
+  # as the target for the final compiler.
+  #
+  # We choose to match the Aarch64 case above,
+  # wrapping the clang integrated assembler as `as`.
+  # It then seems sensible to wrap the cctools GNU assembler as `gas`.
+  #
+  + lib.optionalString (stdenv.isx86_64 && dualAs) ''
+    mv $out/bin/${targetPrefix}as $out/bin/${targetPrefix}gas
+    makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
+      --add-flags "-x assembler -integrated-as -c"
   '';
 
-  nativeBuildInputs = lib.optionals stdenv.isAarch64 [ makeWrapper ];
+  nativeBuildInputs = lib.optionals (stdenv.isAarch64 || dualAs) [ makeWrapper ];
 
   passthru = {
     inherit targetPrefix;
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 44e4475033d..0a3066f5a4d 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -16919,6 +16919,11 @@ with pkgs;
     bintools = bintools-unwrapped;
   };
 
+  bintoolsDualAs = wrapBintoolsWith {
+    bintools = darwin.binutilsDualAs-unwrapped;
+    wrapGas = true;
+  };
+
   bison = callPackage ../development/tools/parsing/bison { };
 
   bisoncpp = callPackage ../development/tools/parsing/bisonc++ { };
diff --git a/pkgs/top-level/darwin-packages.nix b/pkgs/top-level/darwin-packages.nix
index c270dd2220d..1026733e5d3 100644
--- a/pkgs/top-level/darwin-packages.nix
+++ b/pkgs/top-level/darwin-packages.nix
@@ -89,6 +89,20 @@ impure-cmds // appleSourcePackages // chooseLibs // {
     bintools = self.binutils-unwrapped;
   };
 
+  binutilsDualAs-unwrapped = callPackage ../os-specific/darwin/binutils {
+    inherit (pkgs) binutils-unwrapped;
+    inherit (pkgs.llvmPackages) llvm clang-unwrapped;
+    dualAs = true;
+  };
+
+  binutilsDualAs = pkgs.wrapBintoolsWith {
+    libc =
+      if stdenv.targetPlatform != stdenv.hostPlatform
+      then pkgs.libcCross
+      else pkgs.stdenv.cc.libc;
+    bintools = self.binutilsDualAs-unwrapped;
+  };
+
   binutilsNoLibc = pkgs.wrapBintoolsWith {
     libc = preLibcCrossHeaders;
     bintools = self.binutils-unwrapped;