about summary refs log tree commit diff
path: root/pkgs/by-name/cc
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/cc')
-rw-r--r--pkgs/by-name/cc/ccache/package.nix6
-rw-r--r--pkgs/by-name/cc/cctools/0001-Fix-build-issues-with-misc-redo_prebinding.c.patch53
-rw-r--r--pkgs/by-name/cc/cctools/0002-Rely-on-libcd_is_blob_a_linker_signature.patch25
-rw-r--r--pkgs/by-name/cc/cctools/0003-Fix-utimensat-compatability-with-the-10.12-SDK.patch50
-rw-r--r--pkgs/by-name/cc/cctools/0004-Use-nixpkgs-clang-with-the-assembler-driver.patch57
-rw-r--r--pkgs/by-name/cc/cctools/0005-Find-ld64-in-the-store.patch28
-rw-r--r--pkgs/by-name/cc/cctools/0006-Support-target-prefixes-in-ranlib-detection.patch30
-rw-r--r--pkgs/by-name/cc/cctools/meson.build657
-rw-r--r--pkgs/by-name/cc/cctools/meson.options6
-rw-r--r--pkgs/by-name/cc/cctools/package.nix175
10 files changed, 1084 insertions, 3 deletions
diff --git a/pkgs/by-name/cc/ccache/package.nix b/pkgs/by-name/cc/ccache/package.nix
index f4e2bceeaefe8..9984771b7ce9e 100644
--- a/pkgs/by-name/cc/ccache/package.nix
+++ b/pkgs/by-name/cc/ccache/package.nix
@@ -20,7 +20,7 @@
 
 stdenv.mkDerivation (finalAttrs: {
   pname = "ccache";
-  version = "4.10";
+  version = "4.10.2";
 
   src = fetchFromGitHub {
     owner = "ccache";
@@ -39,7 +39,7 @@ stdenv.mkDerivation (finalAttrs: {
         exit 1
       fi
     '';
-    hash = "sha256-YHSr2pnk17QEdrIHInXX2eBFN9OGjdleaB41VLaqlnA=";
+    hash = "sha256-j7Cjr5R/fN/1C6hR9400Y/hwgG++qjPvo9PYyetzrx0=";
   };
 
   outputs = [
@@ -177,11 +177,11 @@ stdenv.mkDerivation (finalAttrs: {
       builtins.replaceStrings [ "." ] [ "_" ] finalAttrs.version
     }";
     license = licenses.gpl3Plus;
-    mainProgram = "ccache";
     maintainers = with maintainers; [
       kira-bruneau
       r-burns
     ];
     platforms = platforms.unix;
+    mainProgram = "ccache";
   };
 })
diff --git a/pkgs/by-name/cc/cctools/0001-Fix-build-issues-with-misc-redo_prebinding.c.patch b/pkgs/by-name/cc/cctools/0001-Fix-build-issues-with-misc-redo_prebinding.c.patch
new file mode 100644
index 0000000000000..5908d030dbfd2
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0001-Fix-build-issues-with-misc-redo_prebinding.c.patch
@@ -0,0 +1,53 @@
+From 55b2a5fcc38eb62f53e155bd8c741481690f1c73 Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Wed, 10 Apr 2024 19:08:39 -0400
+Subject: [PATCH 1/6] Fix build issues with misc/redo_prebinding.c
+
+- Add missing headers; and
+- Add missing arguments to `writeout`.
+---
+ misc/redo_prebinding.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/misc/redo_prebinding.c b/misc/redo_prebinding.c
+index a5a3c81..9d0f4c8 100644
+--- a/misc/redo_prebinding.c
++++ b/misc/redo_prebinding.c
+@@ -83,6 +83,7 @@
+ #include <mach-o/redo_prebinding.h>
+ #endif /* defined(LIBRARY_API) */
+ 
++#import <stdint.h>
+ #import <stdio.h>
+ #import <stdlib.h>
+ #import <string.h>
+@@ -106,7 +107,7 @@
+ #import <stuff/hppa.h>
+ #import <stuff/execute.h>
+ #import <stuff/guess_short_name.h>
+-//#import <stuff/seg_addr_table.h>
++#import <stuff/seg_addr_table.h>
+ #import <stuff/macosx_deployment_target.h>
+ 
+ #include <mach-o/dyld.h>
+@@ -918,7 +919,7 @@ char *envp[])
+                 if(write_to_stdout)
+                     output_file = NULL;
+ 		writeout(archs, narchs, output_file, mode, TRUE, FALSE, FALSE,
+-		         FALSE, NULL);
++		         FALSE, FALSE, NULL);
+ 		if(errors){
+                     if(write_to_stdout == FALSE)
+                         unlink(output_file);
+@@ -928,7 +929,7 @@ char *envp[])
+ 	    else{
+ 		output_file = makestr(input_file, ".redo_prebinding", NULL);
+ 		writeout(archs, narchs, output_file, mode, TRUE, FALSE, FALSE,
+-			 FALSE, NULL);
++			 FALSE, FALSE, NULL);
+ 		if(errors){
+ 		    unlink(output_file);
+ 		    return(2);
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/0002-Rely-on-libcd_is_blob_a_linker_signature.patch b/pkgs/by-name/cc/cctools/0002-Rely-on-libcd_is_blob_a_linker_signature.patch
new file mode 100644
index 0000000000000..014281039ae87
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0002-Rely-on-libcd_is_blob_a_linker_signature.patch
@@ -0,0 +1,25 @@
+From 419c469634891d09f6688d56da9e26431018f342 Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Wed, 10 Apr 2024 20:36:53 -0400
+Subject: [PATCH 2/6] Rely on libcd_is_blob_a_linker_signature
+
+---
+ libstuff/code_directory.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libstuff/code_directory.c b/libstuff/code_directory.c
+index 7c158fa..3b8eb77 100644
+--- a/libstuff/code_directory.c
++++ b/libstuff/code_directory.c
+@@ -146,7 +146,7 @@ static const char* format_version_xyz(uint32_t version)
+  */
+ int codedir_is_linker_signed(const char* data, uint32_t size)
+ {
+-#if 1
++#if 0
+     // HACK: libcodedirectory.h is in both the macOS SDK in /usr/local/include, and in the tool chain at /usr/include.
+     // but there is no way to control clang's search path to look in the toolchain first.
+     // So, declare newer API locally. Once this new header is in all SDKs we can remove this.
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/0003-Fix-utimensat-compatability-with-the-10.12-SDK.patch b/pkgs/by-name/cc/cctools/0003-Fix-utimensat-compatability-with-the-10.12-SDK.patch
new file mode 100644
index 0000000000000..4abe9ee863aa7
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0003-Fix-utimensat-compatability-with-the-10.12-SDK.patch
@@ -0,0 +1,50 @@
+From 989ba5e30cefa0dd8990da158661713c4a21c0fe Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Thu, 11 Apr 2024 18:05:34 -0400
+Subject: [PATCH 3/6] Fix utimensat compatability with the 10.12 SDK
+
+---
+ include/compat.h    | 3 +++
+ libstuff/writeout.c | 2 +-
+ misc/lipo.c         | 2 +-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+ create mode 100644 include/compat.h
+
+diff --git a/include/compat.h b/include/compat.h
+new file mode 100644
+index 0000000..8b1b866
+--- /dev/null
++++ b/include/compat.h
+@@ -0,0 +1,3 @@
++#pragma once
++#include <time.h>
++extern int utimensat(int dirfd, const char* pathname, const struct timespec times[_Nullable 2], int flags);
+diff --git a/libstuff/writeout.c b/libstuff/writeout.c
+index f904caa..03fa535 100644
+--- a/libstuff/writeout.c
++++ b/libstuff/writeout.c
+@@ -297,7 +297,7 @@ no_throttle:
+ 	     * have been zeroed out when the library was created. writeout
+ 	     * will not zero out the modification time in the filesystem.
+ 	     */
+-	    if (__builtin_available(macOS 10.12, *)) {
++	    if (__builtin_available(macOS 10.13, *)) {
+ 		struct timespec times[2] = {0};
+ 		memcpy(&times[0], &toc_timespec, sizeof(struct timespec));
+ 		memcpy(&times[1], &toc_timespec, sizeof(struct timespec));
+diff --git a/misc/lipo.c b/misc/lipo.c
+index 04a3eca..887c049 100644
+--- a/misc/lipo.c
++++ b/misc/lipo.c
+@@ -607,7 +607,7 @@ unknown_flag:
+ 		    if(close(fd) == -1)
+ 			system_fatal("can't close output file: %s",output_file);
+ #ifndef __OPENSTEP__
+-		    if (__builtin_available(macOS 10.12, *)) {
++		    if (__builtin_available(macOS 10.13, *)) {
+ 			time_result = utimensat(AT_FDCWD, output_file,
+ 						output_times, 0);
+ 		    }
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/0004-Use-nixpkgs-clang-with-the-assembler-driver.patch b/pkgs/by-name/cc/cctools/0004-Use-nixpkgs-clang-with-the-assembler-driver.patch
new file mode 100644
index 0000000000000..058cfcdf0c490
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0004-Use-nixpkgs-clang-with-the-assembler-driver.patch
@@ -0,0 +1,57 @@
+From 86b5ad551ef0ffc7ca4da24b7619937bec738522 Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Mon, 15 Apr 2024 20:47:59 -0400
+Subject: [PATCH 4/6] Use nixpkgs clang with the assembler driver
+
+---
+ as/driver.c | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+diff --git a/as/driver.c b/as/driver.c
+index a0d49ad..c15dcbf 100644
+--- a/as/driver.c
++++ b/as/driver.c
+@@ -36,7 +36,7 @@ char **envp)
+     char *p, c, *arch_name, *as, *as_local;
+     char **new_argv;
+     const char *CLANG = "clang";
+-    char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX];
++    char *prefix = "@clang-unwrapped@/bin/";
+     uint32_t bufsize;
+     struct arch_flag arch_flag;
+     const struct arch_flag *arch_flags, *family_arch_flag;
+@@ -50,22 +50,6 @@ char **envp)
+ 	qflag = FALSE;
+ 	Qflag = FALSE;
+ 	some_input_files = FALSE;
+-	/*
+-	 * Construct the prefix to the assembler driver.
+-	 */
+-	bufsize = MAXPATHLEN;
+-	p = buf;
+-	i = _NSGetExecutablePath(p, &bufsize);
+-	if(i == -1){
+-	    p = allocate(bufsize);
+-	    _NSGetExecutablePath(p, &bufsize);
+-	}
+-	prefix = realpath(p, resolved_name);
+-	if(prefix == NULL)
+-	    system_fatal("realpath(3) for %s failed", p);
+-	p = rindex(prefix, '/');
+-	if(p != NULL)
+-	    p[1] = '\0';
+ 	/*
+ 	 * Process the assembler flags exactly like the assembler would (except
+ 	 * let the assembler complain about multiple flags, bad combinations of
+@@ -362,6 +346,8 @@ char **envp)
+ 		exit(1);
+ 	}
+ 
++	prefix = "@gas@/bin/"; /* `libexec` is found relative to the assembler driver’s path. */
++
+ 	/*
+ 	 * If this assembler exist try to run it else print an error message.
+ 	 */
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/0005-Find-ld64-in-the-store.patch b/pkgs/by-name/cc/cctools/0005-Find-ld64-in-the-store.patch
new file mode 100644
index 0000000000000..8f51b38a9ca63
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0005-Find-ld64-in-the-store.patch
@@ -0,0 +1,28 @@
+From e62f7d75380540937f24f896c82736a1e653cc75 Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Mon, 22 Apr 2024 18:15:53 -0400
+Subject: [PATCH 5/6] Find ld64 in the store
+
+---
+ libstuff/execute.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libstuff/execute.c b/libstuff/execute.c
+index 8526ab7..abbbf1b 100644
+--- a/libstuff/execute.c
++++ b/libstuff/execute.c
+@@ -149,6 +149,11 @@ char *
+ cmd_with_prefix(
+ char *str)
+ {
++	// Return the path to ld64 in the store.
++	if (strcmp(str, "ld") == 0) {
++	    return "@ld64_path@";
++	}
++
+ 	int i;
+ 	char *p;
+ 	char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX];
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/0006-Support-target-prefixes-in-ranlib-detection.patch b/pkgs/by-name/cc/cctools/0006-Support-target-prefixes-in-ranlib-detection.patch
new file mode 100644
index 0000000000000..1189d20749844
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/0006-Support-target-prefixes-in-ranlib-detection.patch
@@ -0,0 +1,30 @@
+From e25de788260051892b9e34177ea957cbafe6c415 Mon Sep 17 00:00:00 2001
+From: Randy Eckenrode <randy@largeandhighquality.com>
+Date: Thu, 2 May 2024 07:55:05 -0400
+Subject: [PATCH 6/6] Support target prefixes in ranlib detection
+
+---
+ misc/libtool.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/misc/libtool.c b/misc/libtool.c
+index 289ec4d..8265d53 100644
+--- a/misc/libtool.c
++++ b/misc/libtool.c
+@@ -426,11 +426,11 @@ char **envp)
+ 	    p++;
+ 	else
+ 	    p = argv[0];
+-	if(strncmp(p, "ranlib", sizeof("ranlib") - 1) == 0) {
++	if(strncmp(p, "@targetPrefix@ranlib", sizeof("@targetPrefix@ranlib") - 1) == 0) {
+ 	    cmd_flags.ranlib = TRUE;
+ 	}
+ 	else if (getenv("LIBTOOL_FORCE_RANLIB")) {
+-	    progname = "ranlib";
++	    progname = "@targetPrefix@ranlib";
+ 	    cmd_flags.ranlib = TRUE;
+ 	}
+ 
+-- 
+2.45.2
+
diff --git a/pkgs/by-name/cc/cctools/meson.build b/pkgs/by-name/cc/cctools/meson.build
new file mode 100644
index 0000000000000..c2261d98c958a
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/meson.build
@@ -0,0 +1,657 @@
+# Build settings based on the upstream Xcode project.
+# See: https://github.com/apple-oss-distributions/cctools/blob/main/cctools.xcodeproj/project.pbxproj
+
+# Project settings
+project(
+    'cctools',
+    'c',
+    version : '@version@',
+    default_options : {
+        'c_args': [
+            '-DCCTB_MACOS=YES',
+            '-DCCTB_PROJECT=cctools',
+            '-DCCTB_PROJVERS=cctools-@version@',
+            '-DCCTB_VERSION=@version@',
+            '-DCURRENT_PROJECT_VERSION="@version@"',
+            '-DCODEDIRECTORY_SUPPORT',
+            '-DLTO_SUPPORT',
+        ],
+    },
+)
+
+fs = import('fs')
+
+# Options
+target_prefix = get_option('target_prefix')
+
+
+# Dependencies
+cc = meson.get_compiler('c')
+
+libcodedirectory = cc.find_library('codedirectory')
+libprunetrie = cc.find_library('prunetrie')
+
+
+# Feature tests
+# Add compatibility header for Darwin SDKs that don’t define `utimensat`.
+utimensat_test = '''
+#include <fcntl.h>
+#include <sys/stat.h>
+int main(int argc, char* argv[]) {
+    utimensat(AT_FDCWD, NULL, NULL, 0);
+    return 0;
+}
+'''
+if host_machine.system() == 'darwin' and not cc.compiles(utimensat_test, name : 'supports utimensat')
+    add_project_arguments('-include', 'compat.h', language : 'c')
+    add_project_link_arguments('-undefined', 'dynamic_lookup', language : 'c')
+endif
+
+
+incdirs = include_directories('include')
+
+# Static libraries
+libstuff = static_library(
+    'stuff',
+    c_args : [
+        '-DCPU_TYPE_RISCV32=24', # Per src/abstraction/MachOFileAbstraction.hpp from ld64
+    ],
+    include_directories : [incdirs, 'include/stuff'],
+    sources : [
+        'libstuff/SymLoc.c',
+        'libstuff/align.c',
+        'libstuff/allocate.c',
+        'libstuff/apple_version.c',
+        'libstuff/arch.c',
+        'libstuff/arch_usage.c',
+        'libstuff/args.c',
+        'libstuff/best_arch.c',
+        'libstuff/breakout.c',
+        'libstuff/bytesex.c',
+        'libstuff/checkout.c',
+        'libstuff/code_directory.c',
+        'libstuff/coff_bytesex.c',
+        'libstuff/crc32.c',
+        'libstuff/depinfo.c',
+        'libstuff/diagnostics.c',
+        'libstuff/dylib_roots.c',
+        'libstuff/dylib_table.c',
+        'libstuff/errors.c',
+        'libstuff/execute.c',
+        'libstuff/fatal_arch.c',
+        'libstuff/fatals.c',
+        'libstuff/get_arch_from_host.c',
+        'libstuff/get_toc_byte_sex.c',
+        'libstuff/guess_short_name.c',
+        'libstuff/hash_string.c',
+        'libstuff/hppa.c',
+        'libstuff/llvm.c',
+        'libstuff/lto.c',
+        'libstuff/macosx_deployment_target.c',
+        'libstuff/ofile.c',
+        'libstuff/ofile_error.c',
+        'libstuff/ofile_get_word.c',
+        'libstuff/print.c',
+        'libstuff/reloc.c',
+        'libstuff/rnd.c',
+        'libstuff/seg_addr_table.c',
+        'libstuff/set_arch_flag_name.c',
+        'libstuff/swap_headers.c',
+        'libstuff/symbol_list.c',
+        'libstuff/unix_standard_mode.c',
+        'libstuff/version_number.c',
+        'libstuff/vm_flush_cache.c',
+        'libstuff/write64.c',
+        'libstuff/writeout.c',
+        'libstuff/xcode.c',
+    ],
+)
+
+libstuff_otool = static_library(
+    'stuff_otool',
+    c_args : [
+        '-DCPU_TYPE_RISCV32=24', # Per src/abstraction/MachOFileAbstraction.hpp from ld64
+    ],
+    include_directories : [incdirs, 'include/stuff', 'otool'],
+    sources : [
+        'libstuff/SymLoc.c',
+        'libstuff/align.c',
+        'libstuff/allocate.c',
+        'libstuff/apple_version.c',
+        'libstuff/arch.c',
+        'libstuff/arch_usage.c',
+        'libstuff/args.c',
+        'libstuff/best_arch.c',
+        'libstuff/breakout.c',
+        'libstuff/bytesex.c',
+        'libstuff/checkout.c',
+        'libstuff/code_directory.c',
+        'libstuff/coff_bytesex.c',
+        'libstuff/crc32.c',
+        'libstuff/depinfo.c',
+        'libstuff/diagnostics.c',
+        'libstuff/dylib_roots.c',
+        'libstuff/dylib_table.c',
+        'libstuff/errors.c',
+        'libstuff/execute.c',
+        'libstuff/fatal_arch.c',
+        'libstuff/fatals.c',
+        'libstuff/get_arch_from_host.c',
+        'libstuff/get_toc_byte_sex.c',
+        'libstuff/guess_short_name.c',
+        'libstuff/hash_string.c',
+        'libstuff/hppa.c',
+        'libstuff/llvm.c',
+        'libstuff/lto.c',
+        'libstuff/macosx_deployment_target.c',
+        'libstuff/ofile.c',
+        'libstuff/ofile_error.c',
+        'libstuff/ofile_get_word.c',
+        'libstuff/print.c',
+        'libstuff/reloc.c',
+        'libstuff/rnd.c',
+        'libstuff/seg_addr_table.c',
+        'libstuff/set_arch_flag_name.c',
+        'libstuff/swap_headers.c',
+        'libstuff/symbol_list.c',
+        'libstuff/unix_standard_mode.c',
+        'libstuff/version_number.c',
+        'libstuff/vm_flush_cache.c',
+        'libstuff/write64.c',
+        'libstuff/writeout.c',
+        'libstuff/xcode.c',
+    ],
+)
+
+
+# Binaries
+ar = executable(
+    f'@target_prefix@ar',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : [
+        'ar/append.c',
+        'ar/ar.c',
+        'ar/archive.c',
+        'ar/contents.c',
+        'ar/delete.c',
+        'ar/extract.c',
+        'ar/misc.c',
+        'ar/move.c',
+        'ar/print.c',
+        'ar/replace.c',
+    ],
+)
+install_man(
+    'ar/ar.1',
+    'ar/ar.5',
+)
+
+as = executable(
+    f'@target_prefix@gas',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['as/driver.c'],
+)
+
+as_common = files(
+    'as/app.c',
+    'as/as.c',
+    'as/atof-generic.c',
+    'as/atof-ieee.c',
+    'as/dwarf2dbg.c',
+    'as/expr.c',
+    'as/fixes.c',
+    'as/flonum-const.c',
+    'as/flonum-copy.c',
+    'as/flonum-mult.c',
+    'as/frags.c',
+    'as/hash.c',
+    'as/hex-value.c',
+    'as/input-file.c',
+    'as/input-scrub.c',
+    'as/layout.c',
+    'as/messages.c',
+    'as/obstack.c',
+    'as/read.c',
+    'as/sections.c',
+    'as/symbols.c',
+    'as/write_object.c',
+    'as/xmalloc.c',
+)
+
+as_arm = executable(
+    'as-arm',
+    c_args : [
+        '-DARM',
+        '-DNeXT_MOD',
+    ],
+    include_directories : [
+        incdirs,
+        'as',
+        'include/gnu',
+    ],
+    install : true,
+    install_dir : 'libexec/as/arm',
+    link_with : [libstuff],
+    sources : [as_common, 'as/arm.c'],
+)
+
+as_i386 = executable(
+    'as-i386',
+    c_args : [
+        '-DI386',
+        '-Di486',
+        '-Di586',
+        '-Di686',
+        '-DNeXT_MOD',
+    ],
+    include_directories : [
+        incdirs,
+        'as',
+        'include/gnu',
+    ],
+    install : true,
+    install_dir : 'libexec/as/i386',
+    link_with : [libstuff],
+    sources : [as_common, 'as/i386.c'],
+)
+
+as_x86_64 = executable(
+    'as-x86_64',
+    c_args : [
+        '-DI386',
+        '-Di486',
+        '-Di586',
+        '-Di686',
+        '-DARCH64',
+        '-DNeXT_MOD',
+    ],
+    include_directories : [
+        incdirs,
+        'as',
+        'include/gnu'
+    ],
+    install : true,
+    install_dir : 'libexec/as/x86_64',
+    link_with : [libstuff],
+    sources : [as_common, 'as/i386.c'],
+)
+
+# # ld # excluded because ld64 is built separately
+
+bitcode_strip = executable(
+    f'@target_prefix@bitcode_strip',
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/bitcode_strip.c'],
+)
+install_man('man/bitcode_strip.1')
+
+check_dylib = executable(
+    f'@target_prefix@check_dylib',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/check_dylib.c'],
+)
+install_man('man/check_dylib.1')
+
+checksyms = executable(
+    f'@target_prefix@checksyms',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/checksyms.c'],
+)
+install_man('man/checksyms.1')
+
+cmpdylib = executable(
+    f'@target_prefix@cmpdylib',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/cmpdylib.c'],
+)
+install_man('man/cmpdylib.1')
+
+codesign_allocate = executable(
+    f'@target_prefix@codesign_allocate',
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/codesign_allocate.c'],
+)
+install_man('man/codesign_allocate.1')
+
+ctf_insert = executable(
+    f'@target_prefix@ctf_insert',
+    dependencies : [libcodedirectory],
+    include_directories : [incdirs, 'include/stuff'],
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/ctf_insert.c'],
+)
+install_man('man/ctf_insert.1')
+
+depinfo = executable(
+    f'@target_prefix@depinfo',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/depinfo.c'],
+)
+install_man('man/depinfo.1')
+
+diagtest = executable(
+    f'@target_prefix@diagtest',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/diagtest.c'],
+)
+install_man('man/diagtest.1')
+
+gprof = executable(
+    f'@target_prefix@gprof',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : [
+        'gprof/arcs.c',
+        'gprof/calls.c',
+        'gprof/dfn.c',
+        'gprof/getnfile.c',
+        'gprof/gprof.c',
+        'gprof/hertz.c',
+        'gprof/lookup.c',
+        'gprof/printgprof.c',
+        'gprof/printlist.c',
+        'gprof/scatter.c',
+    ],
+)
+install_man('man/gprof.1')
+
+# Not supported on 64-bit architectures
+# indr = executable(
+#     f'@target_prefix@indr',
+#     include_directories : incdirs,
+#     sources : ['misc/indr.c'],
+# )
+# install_man('man/indr.1')
+
+install_name_tool = executable(
+    f'@target_prefix@install_name_tool',
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/install_name_tool.c'],
+)
+install_man('man/install_name_tool.1')
+
+libtool = executable(
+    f'@target_prefix@libtool',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/libtool.c'],
+)
+install_man('man/libtool.1')
+
+lipo = executable(
+    f'@target_prefix@lipo',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/lipo.c'],
+)
+install_man('man/lipo.1')
+
+mtoc = executable(
+    f'@target_prefix@mtoc',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['efitools/mtoc.c'],
+)
+install_man('man/mtoc.1')
+
+mtor = executable(
+    f'@target_prefix@mtor',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['efitools/mtor.c'],
+)
+install_man('man/mtor.1')
+
+nm = executable(
+    f'@target_prefix@nm',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/nm.c'],
+)
+install_man('man/nm-classic.1')
+
+nmedit = executable(
+    f'@target_prefix@nmedit',
+    c_args : ['-DNMEDIT'],
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/strip.c'],
+)
+install_man('man/nmedit.1')
+
+otool = executable(
+    f'@target_prefix@otool',
+    c_args : ['-DEFI_SUPPORT'],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : [
+        'otool/arm64_disasm.c',
+        'otool/arm_disasm.c',
+        'otool/coff_print.c',
+        'otool/dyld_bind_info.c',
+        'otool/hppa_disasm.c',
+        'otool/i386_disasm.c',
+        'otool/i860_disasm.c',
+        'otool/m68k_disasm.c',
+        'otool/m88k_disasm.c',
+        'otool/main.c',
+        'otool/ofile_print.c',
+        'otool/ppc_disasm.c',
+        'otool/print_bitcode.c',
+        'otool/print_objc.c',
+        'otool/print_objc2_32bit.c',
+        'otool/print_objc2_64bit.c',
+        'otool/print_objc2_util.c',
+        'otool/sparc_disasm.c',
+    ],
+)
+install_man('man/otool-classic.1')
+
+pagestuff = executable(
+    f'@target_prefix@pagestuff',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/pagestuff.c'],
+)
+install_man('man/pagestuff.1')
+
+# ranlib is a symlink to libtool
+install_man(
+    'man/ranlib.1',
+    'man/ranlib.5',
+)
+
+redo_prebinding = executable(
+    f'@target_prefix@redo_prebinding',
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/redo_prebinding.c'],
+)
+install_man('man/redo_prebinding.1')
+
+seg_addr_table = executable(
+    f'@target_prefix@seg_addr_table',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/seg_addr_table.c'],
+)
+install_man('man/seg_addr_table.1')
+
+seg_hack = executable(
+    f'@target_prefix@seg_hack',
+    dependencies : [libcodedirectory],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/seg_hack.c'],
+)
+
+segedit = executable(
+    f'@target_prefix@segedit',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/segedit.c'],
+)
+install_man('man/segedit.1',)
+
+size = executable(
+    f'@target_prefix@size',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/size.c'],
+)
+install_man('man/size-classic.1')
+
+strings = executable(
+    f'@target_prefix@strings',
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/strings.c'],
+)
+install_man('man/strings.1')
+
+strip = executable(
+    f'@target_prefix@strip',
+    c_args : ['-DTRIE_SUPPORT'],
+    dependencies : [libcodedirectory, libprunetrie],
+    include_directories : incdirs,
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/strip.c'],
+)
+install_man('man/strip.1')
+
+vtool = executable(
+    f'@target_prefix@vtool',
+    dependencies : [libcodedirectory],
+    include_directories : [incdirs, 'include/stuff'],
+    install : true,
+    link_with : [libstuff],
+    sources : ['misc/vtool.c'],
+)
+install_man('man/vtool.1')
+
+
+# Development files
+# Static libraries
+libmacho = static_library(
+    'macho',
+    include_directories : incdirs,
+    sources : [
+        'libmacho/arch.c',
+        'libmacho/get_end.c',
+        'libmacho/getsecbyname.c',
+        'libmacho/getsegbyname.c',
+        'libmacho/hppa_swap.c',
+        'libmacho/i386_swap.c',
+        'libmacho/i860_swap.c',
+        'libmacho/m68k_swap.c',
+        'libmacho/m88k_swap.c',
+        'libmacho/ppc_swap.c',
+        'libmacho/slot_name.c',
+        'libmacho/sparc_swap.c',
+        'libmacho/swap.c',
+    ],
+)
+
+libredo_prebinding = static_library(
+    'redo_prebinding',
+    c_args : ['-DLIBRARY_API'],
+    include_directories : incdirs,
+    sources : ['misc/redo_prebinding.c'],
+)
+install_man('man/redo_prebinding.3')
+
+
+# Development files
+# Based on the contents of the upstream SDK.
+install_headers(
+    'include/mach-o/arch.h',
+    'include/mach-o/fat.h',
+    'include/mach-o/getsect.h',
+    'include/mach-o/ldsyms.h',
+    'include/mach-o/loader.h',
+    'include/mach-o/nlist.h',
+    'include/mach-o/ranlib.h',
+    'include/mach-o/reloc.h',
+    'include/mach-o/stab.h',
+    'include/mach-o/swap.h',
+    subdir : 'mach-o',
+)
+
+# Some of these architectures are irrelevant, but the Libsystem derivation expects their headers to be present.
+# Not every arch has both headers, so tailor the lists for each that does.
+foreach arch : ['arm', 'arm64', 'hppa', 'i860', 'm88k', 'ppc', 'sparc', 'x86_64']
+    install_headers(
+        f'include/mach-o/@arch@/reloc.h',
+        subdir : f'mach-o/@arch@',
+    )
+endforeach
+foreach arch : ['hppa', 'i386', 'i860', 'm68k', 'm88k', 'ppc', 'sparc']
+    install_headers(
+        f'include/mach-o/@arch@/swap.h',
+        subdir : f'mach-o/@arch@',
+    )
+endforeach
+
+install_data(
+    'include/modules/mach-o.modulemap',
+    install_dir : get_option('includedir'),
+    rename : 'mach-o/module.map',
+)
+install_man(
+    'man/Mach-O.5',
+    'man/NSModule.3',
+    'man/NSObjectFileImage.3',
+    'man/NSObjectFileImage_priv.3',
+    'man/arch.3',
+    'man/dyld.3',
+    'man/end.3',
+    'man/get_end.3',
+    'man/getsectbyname.3',
+    'man/getsectbynamefromheader.3',
+    'man/getsectdata.3',
+    'man/getsectdatafromheader.3',
+    'man/getsegbyname.3',
+    'man/stab.5',
+)
diff --git a/pkgs/by-name/cc/cctools/meson.options b/pkgs/by-name/cc/cctools/meson.options
new file mode 100644
index 0000000000000..2417b81f0401e
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/meson.options
@@ -0,0 +1,6 @@
+option(
+    'target_prefix',
+    type : 'string',
+    value : '',
+    description: 'Specifies the prefix to use when building for cross-compilation (e.g., `aarch64-apple-darwin`)'
+)
diff --git a/pkgs/by-name/cc/cctools/package.nix b/pkgs/by-name/cc/cctools/package.nix
new file mode 100644
index 0000000000000..2ab074def6740
--- /dev/null
+++ b/pkgs/by-name/cc/cctools/package.nix
@@ -0,0 +1,175 @@
+{
+  lib,
+  stdenv,
+  fetchFromGitHub,
+  buildPackages,
+  darwin,
+  ld64,
+  llvm,
+  memstreamHook,
+  meson,
+  ninja,
+  openssl,
+  xar,
+  gitUpdater,
+}:
+
+let
+  # The targetPrefix is prepended to binary names to allow multiple binuntils on the PATH to both be usable.
+  targetPrefix = lib.optionalString (
+    stdenv.targetPlatform != stdenv.hostPlatform
+  ) "${stdenv.targetPlatform.config}-";
+
+  # First version with all the required files
+  xnu = fetchFromGitHub {
+    name = "xnu-src";
+    owner = "apple-oss-distributions";
+    repo = "xnu";
+    rev = "xnu-7195.50.7.100.1";
+    hash = "sha256-uHmAOm6k9ZXWfyqHiDSpm+tZqUbERlr6rXSJ4xNACkM=";
+  };
+in
+stdenv.mkDerivation (finalAttrs: {
+  pname = "${targetPrefix}cctools";
+  version = "1010.6";
+
+  outputs = [
+    "out"
+    "dev"
+    "man"
+    "gas"
+  ];
+
+  src = fetchFromGitHub {
+    owner = "apple-oss-distributions";
+    repo = "cctools";
+    rev = "cctools-${finalAttrs.version}";
+    hash = "sha256-JiKCP6U+xxR4mk4TXWv/mEo9Idg+QQqUYmB/EeRksCE=";
+  };
+
+  xcodeHash = "sha256-5RBbGrz1UKV0wt2Uk7RIHdfgWH8sgw/jy7hfTVrtVuM=";
+
+  postUnpack = ''
+    unpackFile '${xnu}'
+
+    # Verify that the Xcode project has not changed unexpectedly.
+    hashType=$(echo $xcodeHash | cut -d- -f1)
+    expectedHash=$(echo $xcodeHash | cut -d- -f2)
+    hash=$(openssl "$hashType" -binary "$sourceRoot/cctools.xcodeproj/project.pbxproj" | base64)
+
+    if [ "$hash" != "$expectedHash" ]; then
+      echo 'error: hash mismatch in cctools.xcodeproj/project.pbxproj'
+      echo "        specified: $xcodeHash"
+      echo "           got:    $hashType-$hash"
+      echo
+      echo 'Upstream Xcode project has changed. Update `meson.build` with any changes, then update `xcodeHash`.'
+      echo 'Use `nix-hash --flat --sri --type sha256 cctools.xcodeproj/project.pbxproj` to regenerate it.'
+      exit 1
+    fi
+  '';
+
+  patches = [
+    # Fix compile errors in redo_prebinding.c
+    ./0001-Fix-build-issues-with-misc-redo_prebinding.c.patch
+    # Use libcd_is_blob_a_linker_signature as defined in the libcodedirectory.h header
+    ./0002-Rely-on-libcd_is_blob_a_linker_signature.patch
+    # cctools uses availability checks for `utimensat`, but it checks the wrong version.
+    # Also, provide a definition to avoid implicit function definition errors.
+    ./0003-Fix-utimensat-compatability-with-the-10.12-SDK.patch
+    # Use the nixpkgs clang’s path as the prefix.
+    ./0004-Use-nixpkgs-clang-with-the-assembler-driver.patch
+    # Make sure cctools can find ld64 in the store
+    ./0005-Find-ld64-in-the-store.patch
+    # `ranlib` is a symlink to `libtool`. Make sure its detection works when it is used in cross-compilation.
+    ./0006-Support-target-prefixes-in-ranlib-detection.patch
+  ];
+
+  postPatch = ''
+    substitute ${./meson.build} meson.build \
+      --subst-var version
+    cp ${./meson.options} meson.options
+
+    # Make sure as’s clang driver uses clang from nixpkgs and finds the drivers in the store.
+    substituteInPlace as/driver.c \
+      --subst-var-by clang-unwrapped '${lib.getBin buildPackages.clang.cc}' \
+      --subst-var-by gas '${placeholder "gas"}'
+
+    # Need to set the path to make sure cctools can find ld64 in the store.
+    substituteInPlace libstuff/execute.c \
+      --subst-var-by ld64_path '${lib.getBin ld64}/bin/ld'
+
+    # Set the target prefix for `ranlib`
+    substituteInPlace misc/libtool.c \
+      --subst-var-by targetPrefix '${targetPrefix}'
+
+    # The version of this file distributed with cctools defines several CPU types missing from the 10.12 SDK.
+    ln -s machine-cctools.h include/mach/machine.h
+
+    # Use libxar from nixpkgs
+    for cctool_src in misc/nm.c otool/print_bitcode.c; do
+      substituteInPlace $cctool_src \
+        --replace-fail 'makestr(prefix, "../lib/libxar.dylib", NULL)' '"${lib.getLib xar}/lib/libxar.dylib"' \
+        --replace-fail '/usr/lib/libxar.dylib' '${lib.getLib xar}/lib/libxar.dylib'
+    done
+
+    # Use libLTO.dylib from nixpkgs LLVM
+    substituteInPlace libstuff/llvm.c \
+      --replace-fail 'getenv("LIBLTO_PATH")' '"${lib.getLib llvm}/lib/libLTO.dylib"'
+
+    cp ../xnu-src/EXTERNAL_HEADERS/mach-o/fixup-chains.h include/mach-o/fixup-chains.h
+  '';
+
+  strictDeps = true;
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    openssl
+  ];
+
+  buildInputs =
+    [
+      ld64
+      llvm
+    ]
+    ++ lib.optionals stdenv.isDarwin [ darwin.objc4 ]
+    ++ lib.optionals (stdenv.isDarwin && stdenv.isx86_64) [ memstreamHook ];
+
+  mesonBuildType = "release";
+
+  mesonFlags = [
+    (lib.mesonOption "b_ndebug" "if-release")
+  ] ++ lib.optionals (targetPrefix != "") [ (lib.mesonOption "target_prefix" targetPrefix) ];
+
+  postInstall = ''
+    ln -s ${targetPrefix}libtool "$out/bin/${targetPrefix}ranlib"
+    ln -s nm-classic.1 "''${!outputMan}/share/man/man1/nm.1"
+    ln -s otool-classic.1 "''${!outputMan}/share/man/man1/otool.1"
+    ln -s size-classic.1 "''${!outputMan}/share/man/man1/size.1"
+
+    # Move GNU as to its own output to prevent it from being used accidentally.
+    moveToOutput bin/gas "$gas"
+    moveToOutput libexec "$gas"
+    for arch in arm i386 x86_64; do
+      mv "$gas/libexec/as/$arch/as-$arch" "$gas/libexec/as/$arch/as"
+    done
+  '';
+
+  __structuredAttrs = true;
+
+  passthru = {
+    inherit targetPrefix;
+    updateScript = gitUpdater { rev-prefix = "cctools-"; };
+  };
+
+  meta = {
+    description = "The classic linker for Darwin";
+    homepage = "https://opensource.apple.com/releases/";
+    license = with lib.licenses; [
+      apple-psl20
+      gpl2 # GNU as
+    ];
+    maintainers = with lib.maintainers; [ reckenrode ];
+    platforms = lib.platforms.darwin;
+  };
+})