From 3c0088e8a8f894493e5528e166bc4eb451590ed1 Mon Sep 17 00:00:00 2001 From: Randy Eckenrode Date: Tue, 19 Mar 2024 19:04:55 -0400 Subject: [PATCH] darwin.binutils: properly handle cctools-llvm - Only link `libexec` when using cctools-port. cctools-llvm does not have a `libexec` folder; - Use `as` provided by cctools-llvm, which is already using the clang-integrated assembler on both platforms; and - Clean up inconsistent use of `builtins`. --- pkgs/os-specific/darwin/binutils/default.nix | 85 +++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/pkgs/os-specific/darwin/binutils/default.nix b/pkgs/os-specific/darwin/binutils/default.nix index d7bdac6ceea3..78c510f7da4c 100644 --- a/pkgs/os-specific/darwin/binutils/default.nix +++ b/pkgs/os-specific/darwin/binutils/default.nix @@ -11,6 +11,7 @@ let "ld" "strip" "otool" "lipo" "nm" "strings" "size" "codesign_allocate" ]; + isCCToolsLLVM = lib.getName cctools == "cctools-llvm"; in # TODO: loop over targetPrefixed binaries too @@ -33,7 +34,7 @@ stdenv.mkDerivation { # - strip: the binutils one seems to break mach-o files # - lipo: gcc build assumes it exists # - nm: the gnu one doesn't understand many new load commands - for i in ${lib.concatStringsSep " " (builtins.map (e: targetPrefix + e) cmds)}; do + for i in ${lib.concatStringsSep " " (map (e: targetPrefix + e) cmds)}; do ln -sf "${cctools}/bin/$i" "$out/bin/$i" done @@ -41,51 +42,59 @@ stdenv.mkDerivation { ln -s ${binutils-unwrapped.out}/share $out/share - ln -s ${cctools}/libexec $out/libexec - mkdir -p "$man"/share/man/man{1,5} - for i in ${builtins.concatStringsSep " " cmds}; do + for i in ${lib.concatStringsSep " " cmds}; do for path in "${cctools.man}"/share/man/man?/$i.*; do dest_path="$man''${path#${cctools.man}}" ln -sv "$path" "$dest_path" done done '' - # On aarch64-darwin we must use clang, because "as" from cctools just doesn't - # handle the arch. Proxying calls to clang produces quite a bit of warnings, - # and using clang directly here is a better option than relying on cctools. - # On x86_64-darwin the Clang version is too old to support this mode. - + lib.optionalString stdenv.isAarch64 '' - rm $out/bin/${targetPrefix}as - makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \ - --add-flags "-x assembler -integrated-as -c" - '' - # x86-64 Darwin gnat-bootstrap 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" - ''; + + lib.optionalString (!isCCToolsLLVM) ( + # cctools-port has a `libexec` folder for `as`, but cctools-llvm uses the clang + # assembler on both platforms. Only link it when cctools is cctools-port. + '' + ln -s ${cctools}/libexec $out/libexec + '' + # cctools-llvm uses the LLVM assembler on both architectures, so use the assembler + # from that instead of relinking it. + # + # On aarch64-darwin we must use clang, because "as" from cctools just doesn't + # handle the arch. Proxying calls to clang produces quite a bit of warnings, + # and using clang directly here is a better option than relying on cctools. + # On x86_64-darwin the Clang version is too old to support this mode. + + lib.optionalString stdenv.isAarch64 '' + rm $out/bin/${targetPrefix}as + makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \ + --add-flags "-x assembler -integrated-as -c" + '' + # x86-64 Darwin gnat-bootstrap 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 || dualAs) [ makeWrapper ]; + nativeBuildInputs = lib.optionals (!isCCToolsLLVM && (stdenv.isAarch64 || dualAs)) [ makeWrapper ]; passthru = { inherit targetPrefix;