2023-05-18 14:16:24 +02:00
|
|
|
|
# Create a cctools-compatible bintools that uses equivalent tools from LLVM in place of the ones
|
|
|
|
|
# from cctools when possible.
|
|
|
|
|
|
2023-07-08 08:06:47 +02:00
|
|
|
|
{ lib, stdenv, makeWrapper, cctools-port, llvmPackages, enableManpages ? stdenv.targetPlatform == stdenv.hostPlatform }:
|
2023-05-18 14:16:24 +02:00
|
|
|
|
|
|
|
|
|
let
|
2023-07-08 08:06:47 +02:00
|
|
|
|
inherit (stdenv) targetPlatform hostPlatform;
|
|
|
|
|
|
2023-05-18 14:16:24 +02:00
|
|
|
|
cctoolsVersion = lib.getVersion cctools-port;
|
|
|
|
|
llvmVersion = llvmPackages.release_version;
|
|
|
|
|
|
|
|
|
|
# `bitcode_strip` is not available until LLVM 12.
|
|
|
|
|
useLLVMBitcodeStrip = lib.versionAtLeast llvmVersion "12";
|
|
|
|
|
|
|
|
|
|
# A compatible implementation of `otool` was not added until LLVM 13.
|
|
|
|
|
useLLVMOtool = lib.versionAtLeast llvmVersion "13";
|
|
|
|
|
|
|
|
|
|
# Older versions of `strip` cause problems for the version of `codesign_allocate` available in
|
|
|
|
|
# the version of cctools in nixpkgs. The version of `codesign_allocate` in cctools-1005.2 does
|
|
|
|
|
# not appear to have issues, but the source is not available yet (as of June 2023).
|
|
|
|
|
useLLVMStrip = lib.versionAtLeast llvmVersion "15" || lib.versionAtLeast cctoolsVersion "1005.2";
|
|
|
|
|
|
2023-07-08 08:10:34 +02:00
|
|
|
|
# Clang 11 performs an optimization on x86_64 that is sensitive to the presence of debug info.
|
|
|
|
|
# This causes GCC to fail to bootstrap due to object file differences between stages 2 and 3.
|
|
|
|
|
useClangAssembler = lib.versionAtLeast llvmVersion "12" || !stdenv.isx86_64;
|
|
|
|
|
|
2023-05-18 14:16:24 +02:00
|
|
|
|
llvm_bins = [
|
|
|
|
|
"dwarfdump"
|
|
|
|
|
"nm"
|
|
|
|
|
"objdump"
|
|
|
|
|
"size"
|
|
|
|
|
"strings"
|
|
|
|
|
]
|
|
|
|
|
++ lib.optional useLLVMBitcodeStrip "bitcode-strip"
|
|
|
|
|
++ lib.optional useLLVMOtool "otool"
|
|
|
|
|
++ lib.optional useLLVMStrip "strip";
|
|
|
|
|
|
|
|
|
|
# Only include the tools that LLVM doesn’t provide and that are present normally on Darwin.
|
|
|
|
|
# The only exceptions are the following tools, which should be reevaluated when LLVM is bumped.
|
|
|
|
|
# - install_name_tool (llvm-objcopy): unrecognized linker commands when building open source CF;
|
|
|
|
|
# - libtool (llvm-libtool-darwin): not fully compatible when used with xcbuild; and
|
|
|
|
|
# - lipo (llvm-lipo): crashes when running the LLVM test suite.
|
|
|
|
|
cctools_bins = [
|
|
|
|
|
"cmpdylib"
|
|
|
|
|
"codesign_allocate"
|
|
|
|
|
"ctf_insert"
|
|
|
|
|
"install_name_tool"
|
|
|
|
|
"ld"
|
|
|
|
|
"libtool"
|
|
|
|
|
"lipo"
|
|
|
|
|
"nmedit"
|
|
|
|
|
"pagestuff"
|
|
|
|
|
"ranlib"
|
|
|
|
|
"segedit"
|
|
|
|
|
"vtool"
|
|
|
|
|
]
|
|
|
|
|
++ lib.optional (!useLLVMBitcodeStrip) "bitcode_strip"
|
|
|
|
|
++ lib.optional (!useLLVMOtool) "otool"
|
2023-07-08 08:10:34 +02:00
|
|
|
|
++ lib.optional (!useLLVMStrip) "strip"
|
|
|
|
|
++ lib.optional (!useClangAssembler) "as";
|
2023-05-18 14:16:24 +02:00
|
|
|
|
|
2023-07-08 08:06:47 +02:00
|
|
|
|
targetPrefix = lib.optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-";
|
2023-05-18 14:16:24 +02:00
|
|
|
|
|
|
|
|
|
linkManPages = pkg: source: target: lib.optionalString enableManpages ''
|
|
|
|
|
sourcePath=${pkg}/share/man/man1/${source}.1.gz
|
|
|
|
|
targetPath=$man/share/man/man1/${target}.1.gz
|
|
|
|
|
|
|
|
|
|
if [ -f "$sourcePath" ]; then
|
|
|
|
|
mkdir -p "$(dirname "$targetPath")"
|
|
|
|
|
ln -s "$sourcePath" "$targetPath"
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
in
|
|
|
|
|
stdenv.mkDerivation {
|
|
|
|
|
pname = "cctools-llvm";
|
|
|
|
|
version = "${llvmVersion}-${cctoolsVersion}";
|
|
|
|
|
|
|
|
|
|
nativeBuildInputs = [ makeWrapper ];
|
|
|
|
|
|
|
|
|
|
# The `man` output has to be included unconditionally because darwin.binutils expects it.
|
|
|
|
|
outputs = [ "out" "dev" "man" ];
|
|
|
|
|
|
|
|
|
|
buildCommand = ''
|
|
|
|
|
mkdir -p "$out/bin" "$man"
|
|
|
|
|
ln -s ${lib.getDev cctools-port} "$dev"
|
|
|
|
|
|
2023-07-08 08:10:34 +02:00
|
|
|
|
'' + lib.optionalString useClangAssembler ''
|
2023-05-18 14:16:24 +02:00
|
|
|
|
# Use the clang-integrated assembler instead of using `as` from cctools.
|
|
|
|
|
makeWrapper "${lib.getBin llvmPackages.clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
|
|
|
|
|
--add-flags "-x assembler -integrated-as -c"
|
|
|
|
|
|
2023-07-08 08:10:34 +02:00
|
|
|
|
'' + ''
|
2023-07-08 08:06:47 +02:00
|
|
|
|
ln -s "${lib.getBin llvmPackages.bintools-unwrapped}/bin/${targetPrefix}llvm-ar" "$out/bin/${targetPrefix}ar"
|
2023-05-18 14:16:24 +02:00
|
|
|
|
${linkManPages llvmPackages.llvm-manpages "llvm-ar" "ar"}
|
|
|
|
|
|
|
|
|
|
for tool in ${toString llvm_bins}; do
|
|
|
|
|
cctoolsTool=''${tool/-/_}
|
|
|
|
|
ln -s "${lib.getBin llvmPackages.llvm}/bin/llvm-$tool" "$out/bin/${targetPrefix}$cctoolsTool"
|
|
|
|
|
${linkManPages llvmPackages.llvm-manpages "llvm-$tool" "$cctoolsTool"}
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for tool in ${toString cctools_bins}; do
|
|
|
|
|
ln -s "${lib.getBin cctools-port}/bin/${targetPrefix}$tool" "$out/bin/${targetPrefix}$tool"
|
|
|
|
|
${linkManPages (lib.getMan cctools-port) "$tool" "$tool"}
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
${linkManPages (lib.getMan cctools-port) "ld64" "ld64"}
|
|
|
|
|
${lib.optionalString (!useLLVMOtool) # The actual man page for otool in cctools is llvm-otool
|
2023-06-10 02:45:09 +02:00
|
|
|
|
(linkManPages (lib.getMan cctools-port) "llvm-otool" "llvm-otool")}
|
2023-05-18 14:16:24 +02:00
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
passthru = { inherit targetPrefix; };
|
|
|
|
|
}
|