diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 121b50fe0f52..bc7c8fbd46ac 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/build-support/cc-wrapper/add-gnat-extra-flags.sh b/pkgs/build-support/cc-wrapper/add-gnat-extra-flags.sh new file mode 100644 index 000000000000..ceff1e4a4c4a --- /dev/null +++ b/pkgs/build-support/cc-wrapper/add-gnat-extra-flags.sh @@ -0,0 +1,23 @@ +# See add-flags.sh in cc-wrapper for comments. +var_templates_list=( + NIX_GNATMAKE_CARGS +) + +accumulateRoles + +for var in "${var_templates_list[@]}"; do + mangleVarList "$var" ${role_suffixes[@]+"${role_suffixes[@]}"} +done + +# `-B@out@/bin' forces cc to use wrapped as instead of the system one. +NIX_GNATMAKE_CARGS_@suffixSalt@="$NIX_GNATMAKE_CARGS_@suffixSalt@ -B@out@/bin/" + +# Only add darwin min version flag if a default darwin min version is set, +# which is a signal that we're targetting darwin. +if [ "@darwinMinVersion@" ]; then + mangleVarSingle @darwinMinVersionVariable@ ${role_suffixes[@]+"${role_suffixes[@]}"} + + NIX_GNATMAKE_CARGS_@suffixSalt@="-m@darwinPlatformForCC@-version-min=${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@} $NIX_GNATMAKE_CARGS_@suffixSalt@" +fi + +export NIX_GNAT_WRAPPER_EXTRA_FLAGS_SET_@suffixSalt@=1 diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 7b0fbc4ec6db..e0dfeafcf00a 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -237,10 +237,15 @@ stdenv.mkDerivation { fi '' + # No need to wrap gnat, gnatkr, gnatname or gnatprep; we can just symlink them in + optionalString cc.langAda or false '' - wrap ${targetPrefix}gnatmake ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatmake - wrap ${targetPrefix}gnatbind ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatbind - wrap ${targetPrefix}gnatlink ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatlink + for cmd in gnatbind gnatchop gnatclean gnatlink gnatls gnatmake; do + wrap ${targetPrefix}$cmd ${./gnat-wrapper.sh} $ccPath/${targetPrefix}$cmd + done + + for cmd in gnat gnatkr gnatname gnatprep; do + ln -s $ccPath/${targetPrefix}$cmd $out/bin/${targetPrefix}$cmd + done # this symlink points to the unwrapped gnat's output "out". It is used by # our custom gprconfig compiler description to find GNAT's ada runtime. See @@ -521,6 +526,10 @@ stdenv.mkDerivation { substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash '' + + optionalString cc.langAda or false '' + substituteAll ${./add-gnat-extra-flags.sh} $out/nix-support/add-gnat-extra-flags.sh + '' + ## ## General Clang support ## Needs to go after ^ because the for loop eats \n and makes this file an invalid script diff --git a/pkgs/build-support/cc-wrapper/gnat-wrapper.sh b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh index 5714b228c595..e75eb3eb1ebf 100644 --- a/pkgs/build-support/cc-wrapper/gnat-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh @@ -29,6 +29,9 @@ if [ -z "${NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then source @out@/nix-support/add-flags.sh fi +if [ -z "${NIX_GNAT_WRAPPER_EXTRA_FLAGS_SET_@suffixSalt@:-}" ]; then + source @out@/nix-support/add-gnat-extra-flags.sh +fi # Parse command line options and set several variables. # For instance, figure out if linker flags should be passed. @@ -124,20 +127,32 @@ if [ "$NIX_ENFORCE_NO_NATIVE_@suffixSalt@" = 1 ]; then params=(${rest+"${rest[@]}"}) fi -if [ "$(basename $0)x" = "gnatmakex" ]; then - extraBefore=("--GNATBIND=@out@/bin/gnatbind" "--GNATLINK=@out@/bin/gnatlink") - extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@) -fi - -if [ "$(basename $0)x" = "gnatbindx" ]; then - extraBefore=() - extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@) -fi - -if [ "$(basename $0)x" = "gnatlinkx" ]; then - extraBefore=() - extraAfter=("--GCC=@out@/bin/gcc") -fi +case "$(basename $0)x" in + "gnatbindx") + extraBefore=() + extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@) + ;; + "gnatchopx") + extraBefore=("--GCC=@out@/bin/gcc") + extraAfter=() + ;; + "gnatcleanx") + extraBefore=($NIX_GNATFLAGS_COMPILE_@suffixSalt@) + extraAfter=() + ;; + "gnatlinkx") + extraBefore=() + extraAfter=("--GCC=@out@/bin/gcc") + ;; + "gnatlsx") + extraBefore=() + extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@) + ;; + "gnatmakex") + extraBefore=("--GNATBIND=@out@/bin/gnatbind" "--GNATLINK=@out@/bin/gnatlink") + extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@ -cargs $NIX_GNATMAKE_CARGS_@suffixSalt@) + ;; +esac # As a very special hack, if the arguments are just `-v', then don't # add anything. This is to prevent `gcc -v' (which normally prints diff --git a/pkgs/development/compilers/gcc/10/default.nix b/pkgs/development/compilers/gcc/10/default.nix index e4cebab266e8..b2c2ac9875aa 100644 --- a/pkgs/development/compilers/gcc/10/default.nix +++ b/pkgs/development/compilers/gcc/10/default.nix @@ -185,7 +185,7 @@ stdenv.mkDerivation ({ preConfigure = (import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; }) + '' ln -sf ${libxcrypt}/include/crypt.h libsanitizer/sanitizer_common/crypt.h ''; diff --git a/pkgs/development/compilers/gcc/11/default.nix b/pkgs/development/compilers/gcc/11/default.nix index de764b9ccc7c..0724eedc29c8 100644 --- a/pkgs/development/compilers/gcc/11/default.nix +++ b/pkgs/development/compilers/gcc/11/default.nix @@ -189,7 +189,7 @@ stdenv.mkDerivation ({ preConfigure = (import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; }) + '' ln -sf ${libxcrypt}/include/crypt.h libsanitizer/sanitizer_common/crypt.h ''; diff --git a/pkgs/development/compilers/gcc/12/default.nix b/pkgs/development/compilers/gcc/12/default.nix index 3c9362fee1ad..4287e4d67d45 100644 --- a/pkgs/development/compilers/gcc/12/default.nix +++ b/pkgs/development/compilers/gcc/12/default.nix @@ -109,6 +109,12 @@ let majorVersion = "12"; }) ] + # Fix detection of bootstrap compiler Ada support (cctools as) on Nix Darwin + ++ optional (stdenv.isDarwin && langAda) ../ada-cctools-as-detection-configure.patch + + # Use absolute path in GNAT dylib install names on Darwin + ++ optional (stdenv.isDarwin && langAda) ../gnat-darwin-dylib-install-name.patch + # Obtain latest patch with ../update-mcfgthread-patches.sh ++ optional (!crossStageStatic && targetPlatform.isMinGW && threadsCross.model == "mcf") ./Added-mcf-thread-model-support-from-mcfgthread.patch; @@ -227,7 +233,7 @@ stdenv.mkDerivation ({ preConfigure = (import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; }) + '' ln -sf ${libxcrypt}/include/crypt.h libsanitizer/sanitizer_common/crypt.h ''; diff --git a/pkgs/development/compilers/gcc/4.8/default.nix b/pkgs/development/compilers/gcc/4.8/default.nix index ba084af53ee5..e0c30f35a13d 100644 --- a/pkgs/development/compilers/gcc/4.8/default.nix +++ b/pkgs/development/compilers/gcc/4.8/default.nix @@ -192,7 +192,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform langJava langGo crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform langJava langGo crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/4.9/default.nix b/pkgs/development/compilers/gcc/4.9/default.nix index c28ef88ce933..d886cc84ecaf 100644 --- a/pkgs/development/compilers/gcc/4.9/default.nix +++ b/pkgs/development/compilers/gcc/4.9/default.nix @@ -212,7 +212,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform langJava langGo crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform langJava langGo crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix index 8bd9d41f1eae..f82070153b78 100644 --- a/pkgs/development/compilers/gcc/6/default.nix +++ b/pkgs/development/compilers/gcc/6/default.nix @@ -223,7 +223,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform gnatboot langJava langAda langGo crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform gnatboot langJava langAda langGo crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/7/default.nix b/pkgs/development/compilers/gcc/7/default.nix index 637be9fd971c..076eec21a142 100644 --- a/pkgs/development/compilers/gcc/7/default.nix +++ b/pkgs/development/compilers/gcc/7/default.nix @@ -191,7 +191,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform langGo crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform langGo crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/8/default.nix b/pkgs/development/compilers/gcc/8/default.nix index 4eb47d00c5c2..18054c8c19b9 100644 --- a/pkgs/development/compilers/gcc/8/default.nix +++ b/pkgs/development/compilers/gcc/8/default.nix @@ -173,7 +173,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform langGo crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform langGo crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/9/default.nix b/pkgs/development/compilers/gcc/9/default.nix index 4c49cdaa3e25..7cdde48667f6 100644 --- a/pkgs/development/compilers/gcc/9/default.nix +++ b/pkgs/development/compilers/gcc/9/default.nix @@ -186,7 +186,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit lib; - inherit version targetPlatform hostPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; + inherit version targetPlatform hostPlatform buildPlatform gnatboot langAda langGo langJit crossStageStatic enableMultilib; }; dontDisableStatic = true; diff --git a/pkgs/development/compilers/gcc/ada-cctools-as-detection-configure.patch b/pkgs/development/compilers/gcc/ada-cctools-as-detection-configure.patch new file mode 100644 index 000000000000..e6b5b3653322 --- /dev/null +++ b/pkgs/development/compilers/gcc/ada-cctools-as-detection-configure.patch @@ -0,0 +1,33 @@ +As originally implemented, the error message check +described in the configure script +breaks detection of Ada compiler support on x86_64-darwin, +because the assembler in the version of cctools currently used +unconditionally emits a deprecation message to stdout, +with no way to disable it. + +Furthermore, GCC 3.4 was the minimum version needed to build GNAT +as far back as GCC 4.4 (see the GCC git repo, tags/releases/gcc-4.4.0, +gcc/doc/install.texi, lines 2052-2053 [1]); +GCC 3.4 is newer than any of the broken GCC versions +that the configure script works around +(see the part of the comment in the configure script +before the context in the patch below), +and GCC 4.4 is older than any GCC that Nix currently packages (GCC 4.8). + +We therefore choose to not check for error messages, +and just check for an error code. +There's no harm in still checking for an object file being created, though. + +[1]: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/doc/install.texi;h=6bdfbece981f7fb6c26da672d45e5d3ba7879c69;hb=b7fc996728085c0591ea7c5d0e1c84a8f6a29bd8#l2052 +--- a/configure 2022-08-19 18:09:52.000000000 +1000 ++++ b/configure 2022-12-26 17:30:49.000000000 +1100 +@@ -5622,8 +5622,7 @@ + # Other compilers, like HP Tru64 UNIX cc, exit successfully when + # given a .adb file, but produce no object file. So we must check + # if an object file was really produced to guard against this. +-errors=`(${CC} -c conftest.adb) 2>&1 || echo failure` +-if test x"$errors" = x && test -f conftest.$ac_objext; then ++if ${CC} -c conftest.adb && test -f conftest.$ac_objext; then + acx_cv_cc_gcc_supports_ada=yes + fi + rm -f conftest.* diff --git a/pkgs/development/compilers/gcc/common/pre-configure.nix b/pkgs/development/compilers/gcc/common/pre-configure.nix index ae5ffe6ab0d0..e3b38eb74e95 100644 --- a/pkgs/development/compilers/gcc/common/pre-configure.nix +++ b/pkgs/development/compilers/gcc/common/pre-configure.nix @@ -1,4 +1,4 @@ -{ lib, version, hostPlatform, targetPlatform +{ lib, version, buildPlatform, hostPlatform, targetPlatform , gnatboot ? null , langAda ? false , langJava ? false @@ -24,6 +24,31 @@ in lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) '' export PATH=${gnatboot}/bin:$PATH '' +# On x86_64-darwin, the gnatboot bootstrap compiler that we need to build a +# native GCC with Ada support emits assembly that is accepted by the Clang +# integrated assembler, but not by the GNU assembler in cctools-port that Nix +# usually in the x86_64-darwin stdenv. In particular, x86_64-darwin gnatboot +# emits MOVQ as the mnemonic for quadword interunit moves, such as between XMM +# and general registers (e.g "movq %xmm0, %rbp"); the cctools-port assembler, +# however, only recognises MOVD for such moves. +# +# Therefore, for native x86_64-darwin builds that support Ada, we have to use +# the Clang integrated assembler to build (at least stage 1 of) GCC, but have to +# target GCC at the cctools-port GNU assembler. In the wrapped x86_64-darwin +# gnatboot, the former is provided as `as`, while the latter is provided as +# `gas`. +# ++ lib.optionalString ( + langAda + && buildPlatform == hostPlatform + && hostPlatform == targetPlatform + && targetPlatform.isx86_64 + && targetPlatform.isDarwin + ) '' + export AS_FOR_BUILD=${gnatboot}/bin/as + export AS_FOR_TARGET=${gnatboot}/bin/gas +'' + # NOTE 2020/3/18: This environment variable prevents configure scripts from # detecting the presence of aligned_alloc on Darwin. There are many facts that # collectively make this fix necessary: diff --git a/pkgs/development/compilers/gcc/gnat-darwin-dylib-install-name.patch b/pkgs/development/compilers/gcc/gnat-darwin-dylib-install-name.patch new file mode 100644 index 000000000000..01e5de86a438 --- /dev/null +++ b/pkgs/development/compilers/gcc/gnat-darwin-dylib-install-name.patch @@ -0,0 +1,19 @@ +--- a/gcc/ada/gcc-interface/Makefile.in 2022-08-19 18:09:52.000000000 +1000 ++++ b/gcc/ada/gcc-interface/Makefile.in 2023-01-11 01:54:06.000000000 +1100 +@@ -795,14 +795,14 @@ + -o libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \ + $(SO_OPTS) \ +- -Wl,-install_name,@rpath/libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ ++ -Wl,-install_name,$(ADA_RTL_DSO_DIR)/libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(MISCLIB) + cd $(RTSDIR); `echo "$(GCC_FOR_TARGET)" \ + | sed -e 's,\./xgcc,../../xgcc,' -e 's,-B\./,-B../../,'` -dynamiclib $(PICFLAG_FOR_TARGET) \ + -o libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(GNATRTL_TASKING_OBJS) \ + $(SO_OPTS) \ +- -Wl,-install_name,@rpath/libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ ++ -Wl,-install_name,$(ADA_RTL_DSO_DIR)/libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ + $(THREADSLIB) -Wl,libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) + cd $(RTSDIR); $(LN_S) libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ + libgnat$(soext) diff --git a/pkgs/development/compilers/gnatboot/default.nix b/pkgs/development/compilers/gnatboot/default.nix index 65f6269e2f00..7ef2ce03df94 100644 --- a/pkgs/development/compilers/gnatboot/default.nix +++ b/pkgs/development/compilers/gnatboot/default.nix @@ -4,34 +4,53 @@ }: let - versionMap = { + throwUnsupportedSystem = throw "Unsupported system: ${stdenv.hostPlatform.system}"; + + versionMap = rec { "11" = { - version = "11.2.0-4"; - hash = "sha256-8fMBJp6igH+Md5jE4LMubDmC4GLt4A+bZG/Xcz2LAJQ="; - }; + gccVersion = "11.2.0"; + alireRevision = "4"; + } // { + x86_64-darwin = { + hash = "sha256-FmBgD20PPQlX/ddhJliCTb/PRmKxe9z7TFPa2/SK4GY="; + upstreamTriplet = "x86_64-apple-darwin19.6.0"; + }; + x86_64-linux = { + hash = "sha256-8fMBJp6igH+Md5jE4LMubDmC4GLt4A+bZG/Xcz2LAJQ="; + upstreamTriplet = "x86_64-pc-linux-gnu"; + }; + }.${stdenv.hostPlatform.system} or throwUnsupportedSystem; "12" = { - version = "12.1.0-2"; - hash = "sha256-EPDPOOjWJnJsUM7GGxj20/PXumjfLoMIEFX1EDtvWVY="; - }; + gccVersion = "12.1.0"; + alireRevision = "2"; + } // { + x86_64-darwin = { + hash = "sha256-zrcVFvFZMlGUtkG0p1wST6kGInRI64Icdsvkcf25yVs="; + upstreamTriplet = "x86_64-apple-darwin19.6.0"; + }; + x86_64-linux = { + hash = "sha256-EPDPOOjWJnJsUM7GGxj20/PXumjfLoMIEFX1EDtvWVY="; + upstreamTriplet = "x86_64-pc-linux-gnu"; + }; + }.${stdenv.hostPlatform.system} or throwUnsupportedSystem; }; in with versionMap.${majorVersion}; stdenv.mkDerivation rec { pname = "gnatboot"; - inherit version; + inherit gccVersion alireRevision; + + version = "${gccVersion}-${alireRevision}"; src = fetchzip { - url = "https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-${version}/gnat-x86_64-linux-${version}.tar.gz"; + url = "https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-${version}/gnat-${stdenv.hostPlatform.system}-${version}.tar.gz"; inherit hash; }; nativeBuildInputs = [ - autoPatchelfHook dejagnu - elfutils expat - glibc gmp guile libipt @@ -42,11 +61,69 @@ stdenv.mkDerivation rec { sourceHighlight xz zlib + ] ++ lib.optional stdenv.buildPlatform.isLinux [ + autoPatchelfHook + elfutils + glibc ]; + postPatch = lib.optionalString (stdenv.hostPlatform.isDarwin) '' + substituteInPlace lib/gcc/${upstreamTriplet}/${gccVersion}/install-tools/mkheaders.conf \ + --replace "SYSTEM_HEADER_DIR=\"/usr/include\"" "SYSTEM_HEADER_DIR=\"/include\"" + '' + # The included fixincl binary that is called during header fixup has a + # hardcoded execvp("/usr/bin/sed", ...) call, but /usr/bin/sed isn't + # available in the Nix Darwin stdenv. Fortunately, execvp() will search the + # PATH environment variable for the executable if its first argument does not + # contain a slash, so we can just change the string to "sed" and zero the + # other bytes. + + '' + sed -i "s,/usr/bin/sed,sed\x00\x00\x00\x00\x00\x00\x00\x00\x00," libexec/gcc/${upstreamTriplet}/${gccVersion}/install-tools/fixincl + ''; + installPhase = '' mkdir -p $out cp -ar * $out/ + '' + + # So far with the Darwin gnatboot binary packages, there have been two + # types of dylib path references to other dylibs that need fixups: + # + # 1. Dylibs in $out/lib with paths starting with + # /Users/runner/.../gcc/install that refer to other dylibs in $out/lib + # 2. Dylibs in $out/lib/gcc/*/*/adalib with paths starting with + # @rpath that refer to other dylibs in $out/lib/gcc/*/*/adalib + # + # Additionally, per Section 14.4 Fixed Headers in the GCC 12.2.0 manual [2], + # we have to update the fixed header files in current Alire GCC package, since it + # was built against macOS 10.15 (Darwin 19.6.0), but Nix currently + # builds against macOS 10.12, and the two header file structures differ. + # For example, the current Alire GCC package has a fixed + # from macOS 10.15 that contains a #include <_stdio.h>, but neither the Alire + # GCC package nor macOS 10.12 have such a header ( and + # in 10.12 are not equivalent; indeed, 10.15 <_stdio.h> + # says it contains code shared by and ). + # + # [2]: https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Fixed-Headers.html + + + lib.optionalString (stdenv.hostPlatform.isDarwin) '' + upstreamBuildPrefix="/Users/runner/work/GNAT-FSF-builds/GNAT-FSF-builds/sbx/x86_64-darwin/gcc/install" + for i in "$out"/lib/*.dylib "$out"/lib/gcc/*/*/adalib/*.dylib; do + if [[ -f "$i" && ! -h "$i" ]]; then + install_name_tool -id "$i" "$i" || true + for old_path in $(otool -L "$i" | grep "$upstreamBuildPrefix" | awk '{print $1}'); do + new_path=`echo "$old_path" | sed "s,$upstreamBuildPrefix,$out,"` + install_name_tool -change "$old_path" "$new_path" "$i" || true + done + for old_path in $(otool -L "$i" | grep "@rpath" | awk '{print $1}'); do + new_path=$(echo "$old_path" | sed "s,@rpath,$(dirname "$i"),") + install_name_tool -change "$old_path" "$new_path" "$i" || true + done + fi + done + + "$out"/libexec/gcc/${upstreamTriplet}/${gccVersion}/install-tools/mkheaders -v -v \ + "$out" "${stdenv.cc.libc}" ''; passthru = { @@ -54,6 +131,7 @@ stdenv.mkDerivation rec { langCC = false; langFortran = false; langAda = true; + isGNU = true; }; meta = with lib; { @@ -61,6 +139,6 @@ stdenv.mkDerivation rec { homepage = "https://www.gnu.org/software/gnat"; license = licenses.gpl3; maintainers = with maintainers; [ ethindp ]; - platforms = [ "x86_64-linux" ]; + platforms = [ "x86_64-linux" "x86_64-darwin" ]; }; } diff --git a/pkgs/os-specific/darwin/binutils/default.nix b/pkgs/os-specific/darwin/binutils/default.nix index c5bc50cafd71..3b1a26368732 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 3fc02f304cf6..b78cb7e02726 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -14518,11 +14518,22 @@ with pkgs; && stdenv.buildPlatform == stdenv.hostPlatform then buildPackages.gnatboot12 else buildPackages.gnat12; + stdenv = + if stdenv.hostPlatform == stdenv.targetPlatform + && stdenv.buildPlatform == stdenv.hostPlatform + && stdenv.buildPlatform.isDarwin + && stdenv.buildPlatform.isx86_64 + then overrideCC stdenv gnatboot12 + else stdenv; }); gnatboot = gnatboot12; gnatboot11 = wrapCC (callPackage ../development/compilers/gnatboot { majorVersion = "11"; }); - gnatboot12 = wrapCC (callPackage ../development/compilers/gnatboot { majorVersion = "12"; }); + gnatboot12 = wrapCCWith ({ + cc = callPackage ../development/compilers/gnatboot { majorVersion = "12"; }; + } // lib.optionalAttrs (stdenv.hostPlatform.isDarwin) { + bintools = bintoolsDualAs; + }); gnu-smalltalk = callPackage ../development/compilers/gnu-smalltalk { }; @@ -16958,6 +16969,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 2cc74028f62c..ddf0be41a3e1 100644 --- a/pkgs/top-level/darwin-packages.nix +++ b/pkgs/top-level/darwin-packages.nix @@ -81,6 +81,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;