nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 bashNonInteractive,
5 bzip2,
6 coreutils,
7 cpio,
8 curlMinimal,
9 darwin,
10 diffutils,
11 dumpnar,
12 findutils,
13 gawk,
14 gettext,
15 gmpxx,
16 gnugrep,
17 gnumake,
18 gnused,
19 gnutar,
20 gzip,
21 jq,
22 ld64,
23 libffi,
24 libiconv,
25 libxml2,
26 llvmPackages,
27 ncurses,
28 nukeReferences,
29 oniguruma,
30 openssl,
31 patch,
32 pbzx,
33 runCommand,
34 writeText,
35 xarMinimal,
36 xz,
37 zlib,
38}:
39stdenv.mkDerivation (finalAttrs: {
40 name = "stdenv-bootstrap-tools";
41
42 nativeBuildInputs = [
43 dumpnar
44 nukeReferences
45 ];
46
47 buildCommand =
48 let
49 inherit (lib) getBin getDev getLib;
50
51 coreutils_ =
52 (coreutils.override (prevArgs: {
53 # We want coreutils without ACL support.
54 aclSupport = false;
55 # Cannot use a single binary build, or it gets dynamically linked against gmp.
56 singleBinary = false;
57 })).overrideAttrs
58 (prevAttrs: {
59 # Increase header size to be able to inject extra RPATHs. Otherwise
60 # x86_64-darwin build fails as:
61 # https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv
62 NIX_LDFLAGS = (prevAttrs.NIX_LDFLAGS or "") + " -headerpad_max_install_names";
63 });
64
65 # Avoid messing with libkrb5 and libnghttp2.
66 curl_ = curlMinimal.override (prevArgs: {
67 gssSupport = false;
68 http2Support = false;
69 scpSupport = false;
70 });
71
72 unpackScript = writeText "bootstrap-tools-unpack.sh" ''
73 set -euo pipefail
74
75 echo Unpacking the bootstrap tools... >&2
76 mkdir $out
77 tar xf "$1" -C $out
78
79 updateInstallName() {
80 local path="$1"
81
82 cp "$path" "$path.new"
83 install_name_tool -id "$path" "$path.new"
84 codesign -f -i "$(basename "$path")" -s - "$path.new"
85 mv -f "$path.new" "$path"
86 }
87
88 find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do
89 updateInstallName "$lib"
90 done
91
92 # as is a wrapper around clang. need to replace the nuked store paths
93 sed -i 's|/.*/bin/|'"$out"'/bin/|' $out/bin/as
94
95 # Provide a gunzip script.
96 cat > $out/bin/gunzip <<EOF
97 #!$out/bin/sh
98 exec $out/bin/gzip -d "\$@"
99 EOF
100 chmod +x $out/bin/gunzip
101
102 # Provide fgrep/egrep.
103 echo "#! $out/bin/sh" > $out/bin/egrep
104 echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep
105 echo "#! $out/bin/sh" > $out/bin/fgrep
106 echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep
107
108 cat >$out/bin/dsymutil << EOF
109 #!$out/bin/sh
110 EOF
111
112 chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil
113 '';
114
115 in
116 ''
117 mkdir -p $out/bin $out/include $out/lib $out/lib/darwin
118
119 chmod -R u+w $out/include
120 cp -rL ${getDev libiconv}/include/* $out/include
121 cp -rL ${getDev gnugrep.pcre2}/include/* $out/include
122
123 # Copy binutils.
124 for i in as ld ar ranlib nm strip otool install_name_tool lipo codesign_allocate; do
125 cp ${getBin darwin.binutils-unwrapped}/bin/$i $out/bin
126 done
127 cp -d ${getLib ld64}/lib/libcodedirectory*.dylib $out/lib
128
129 # Copy coreutils, bash, etc.
130 cp ${getBin coreutils_}/bin/* $out/bin
131 (cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users)
132
133 cp -d ${getBin bashNonInteractive}/bin/{ba,}sh $out/bin
134 cp -d ${getBin diffutils}/bin/* $out/bin
135 cp ${getBin findutils}/bin/{find,xargs} $out/bin
136 cp -d ${getBin gawk}/bin/{g,}awk $out/bin
137 cp -d ${getBin gnugrep}/bin/grep $out/bin
138 cp -d ${getBin gnumake}/bin/* $out/bin
139 cp -d ${getBin gnused}/bin/* $out/bin
140 cp -d ${getBin patch}/bin/* $out/bin
141
142 cp -d ${getLib gettext}/lib/libintl*.dylib $out/lib
143 cp -d ${getLib gnugrep.pcre2}/lib/libpcre2*.dylib $out/lib
144 cp -d ${getLib libiconv}/lib/lib*.dylib $out/lib
145 cp -d ${getLib libxml2}/lib/libxml2*.dylib $out/lib
146 cp -d ${getLib ncurses}/lib/libncurses*.dylib $out/lib
147
148 # copy package extraction tools
149 cp -d ${getBin bzip2}/bin/b{,un}zip2 $out/bin
150 cp ${getBin cpio}/bin/cpio $out/bin
151 cp ${getBin gnutar}/bin/tar $out/bin
152 cp ${getBin gzip}/bin/.gzip-wrapped $out/bin/gzip
153 cp ${getBin pbzx}/bin/pbzx $out/bin
154 cp ${getBin xz}/bin/xz $out/bin
155 cp -d ${getLib bzip2}/lib/libbz2*.dylib $out/lib
156 cp -d ${getLib gmpxx}/lib/libgmp*.dylib $out/lib
157 cp -d ${getLib xarMinimal}/lib/libxar*.dylib $out/lib
158 cp -d ${getLib xz}/lib/liblzma*.dylib $out/lib
159 cp -d ${getLib zlib}/lib/libz*.dylib $out/lib
160
161 # This used to be in-nixpkgs, but now is in the bundle
162 # because I can't be bothered to make it partially static
163 cp ${getBin curl_}/bin/curl $out/bin
164 cp -d ${getLib curl_}/lib/libcurl*.dylib $out/lib
165 cp -d ${getLib openssl}/lib/*.dylib $out/lib
166
167 # Copy what we need of clang
168 cp -d ${getBin llvmPackages.clang-unwrapped}/bin/clang{,++,-cl,-cpp,-[0-9]*} $out/bin
169 cp -d ${getLib llvmPackages.clang-unwrapped}/lib/libclang-cpp*.dylib $out/lib
170 cp -rd ${getLib llvmPackages.clang-unwrapped}/lib/clang $out/lib
171
172 cp -d ${getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib
173 mkdir -p $out/lib/darwin
174 cp -d ${getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt.{,profile_}osx.a $out/lib/darwin
175 cp -d ${getLib llvmPackages.compiler-rt}/lib/libclang_rt.{,profile_}osx.a $out/lib
176 cp -d ${getLib llvmPackages.llvm}/lib/libLLVM.dylib $out/lib
177 cp -d ${getLib libffi}/lib/libffi*.dylib $out/lib
178
179 cp -rd ${getDev llvmPackages.libcxx}/include/c++ $out/include
180
181 # Copy tools needed to build the SDK
182 cp -d ${getBin jq}/bin/* $out/bin
183 cp -d ${getBin llvmPackages.llvm}/bin/llvm-readtapi $out/bin
184
185 cp -d ${getLib jq}/lib/lib*.dylib $out/lib
186 cp -d ${getLib oniguruma}/lib/lib*.dylib $out/lib
187
188 # copy sigtool
189 cp -d ${getBin darwin.sigtool}/bin/{codesign,sigtool} $out/bin
190
191 # tools needed to unpack bootstrap archive
192 mkdir -p unpack/bin unpack/lib
193 cp -d ${getBin bashNonInteractive}/bin/{ba,}sh unpack/bin
194 cp ${getBin coreutils_}/bin/mkdir unpack/bin
195 cp ${getBin gnutar}/bin/tar unpack/bin
196 cp ${getBin xz}/bin/xz unpack/bin
197 cp -d ${getLib gettext}/lib/libintl*.dylib unpack/lib
198 cp -d ${getLib libiconv}/lib/lib*.dylib unpack/lib
199 cp -d ${getLib xz}/lib/liblzma*.dylib unpack/lib
200 cp ${unpackScript} unpack/bootstrap-tools-unpack.sh
201
202 #
203 # All files copied. Perform processing to update references to point into
204 # the archive
205 #
206
207 chmod -R u+w $out unpack
208
209 # - change nix store library paths to use @rpath/library
210 # - if needed add an rpath containing lib/
211 # - strip executable
212 rpathify() {
213 local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*" || true)
214 local lib rpath
215 for lib in $libs; do
216 ${stdenv.cc.targetPrefix}install_name_tool -change $lib "@rpath/$(basename "$lib")" "$1"
217 done
218
219 case "$(dirname "$1")" in
220 */bin)
221 # Strip executables even further
222 ${stdenv.cc.targetPrefix}strip "$i"
223 rpath='@executable_path/../lib'
224 ;;
225 */lib)
226 # the '/.' suffix is required
227 rpath='@loader_path/.'
228 ;;
229 */lib/darwin)
230 rpath='@loader_path/..'
231 ;;
232 *)
233 echo unkown executable $1 >&2
234 exit 1
235 ;;
236 esac
237
238 # if shared object contains references add an rpath to lib/
239 if ${stdenv.cc.targetPrefix}otool -l "$1"| grep -q '@rpath/'; then
240 ${stdenv.cc.targetPrefix}install_name_tool -add_rpath "$rpath" "$1"
241 fi
242 }
243
244 # check that linked library paths exist in lib
245 # must be run after rpathify is performed
246 checkDeps() {
247 local deps=$(${stdenv.cc.targetPrefix}otool -l "$1"| grep -o '@rpath/[^ ]*' || true)
248 local lib
249 shopt -s extglob
250 for lib in $deps; do
251 local root="''${1/\/@(lib|bin)\/*}"
252 if [[ ! -e $root/''${lib/@rpath/lib} ]]; then
253 echo "error: $1 missing lib for $lib" >&2
254 exit 1
255 fi
256 done
257 shopt -u extglob
258 }
259
260 for i in {unpack,$out}/bin/* {unpack,$out}/lib{,/darwin}/*.dylib; do
261 if [[ ! -L $i ]] && isMachO "$i"; then
262 rpathify "$i"
263 checkDeps "$i"
264 fi
265 done
266
267 nuke-refs {unpack,$out}/bin/*
268 nuke-refs {unpack,$out}/lib/*
269 nuke-refs $out/lib/darwin/*
270
271 mkdir $out/.pack
272 mv $out/* $out/.pack
273 mv $out/.pack $out/pack
274
275 mkdir $out/on-server
276 cp -r unpack $out
277
278 XZ_OPT="-9 -T $NIX_BUILD_CORES" tar cvJf $out/on-server/bootstrap-tools.tar.xz \
279 --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack .
280 dumpnar $out/unpack | xz -9 -T $NIX_BUILD_CORES > $out/on-server/unpack.nar.xz
281 '';
282
283 allowedReferences = [ ];
284
285 passthru = {
286 bootstrapFiles = {
287 bootstrapTools = "${finalAttrs.finalPackage}/on-server/bootstrap-tools.tar.xz";
288 unpack = runCommand "unpack" { allowedReferences = [ ]; } ''
289 cp -r ${finalAttrs.finalPackage}/unpack $out
290 '';
291 };
292 };
293
294 meta = {
295 teams = [ lib.teams.darwin ];
296 };
297})