Skip to content

Commit 6f55ab5

Browse files
committed
Merge bitcoin/bitcoin#24534: contrib: macdeploy: make gen-sdk deterministic
ba30a54 contrib: macdeploy: monkey-patch gen-sdk to be deterministic (Pavol Rusnak) 1868a17 contrib: macdeploy: make gen-sdk deterministic (Pavol Rusnak) Pull request description: This PR attempts to make `contrib/macdeploy/gen-sdk` deterministic Can anyone with the `Xcode_12.2.xip` confirm that `gen-sdk` produces the same hash? => `e7ca56bc8804d16624fad68be2e71647747d6629cacaaa3de5fbfa7f444e9eae ` ACKs for top commit: laanwj: Tested ACK ba30a54 jarolrod: Tested ACK bitcoin/bitcoin@ba30a54 Tree-SHA512: 1638ceaf28e87ef0d21a1a71ef02989f75942b60a12f07236ac709bde96f08f39f816767e35a0fe68c26bf5978e63e74f5385be9d4b8f80a2e89b30f163f4526
2 parents 094d9fd + ba30a54 commit 6f55ab5

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

contrib/macdeploy/README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ When complete, it will have produced `Bitcoin-Core.dmg`.
1515
A free Apple Developer Account is required to proceed.
1616

1717
Our current macOS SDK
18-
(`Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz`) can be
19-
extracted from
18+
(`Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz`)
19+
can be extracted from
2020
[Xcode_12.2.xip](https://download.developer.apple.com/Developer_Tools/Xcode_12.2/Xcode_12.2.xip).
21+
2122
Alternatively, after logging in to your account go to 'Downloads', then 'More'
2223
and search for [`Xcode_12.2`](https://developer.apple.com/download/all/?q=Xcode%2012.2).
24+
2325
An Apple ID and cookies enabled for the hostname are needed to download this.
24-
The `sha256sum` of the archive should be `28d352f8c14a43d9b8a082ac6338dc173cb153f964c6e8fb6ba389e5be528bd0`.
26+
27+
The `sha256sum` of the downloaded XIP archive should be `28d352f8c14a43d9b8a082ac6338dc173cb153f964c6e8fb6ba389e5be528bd0`.
2528

2629
After Xcode version 7.x, Apple started shipping the `Xcode.app` in a `.xip`
2730
archive. This makes the SDK less-trivial to extract on non-macOS machines. One
@@ -55,7 +58,10 @@ previous stage) as the first argument.
5558
./contrib/macdeploy/gen-sdk '/path/to/Xcode.app'
5659
```
5760

61+
The `sha256sum` of the generated TAR.GZ archive should be `e7ca56bc8804d16624fad68be2e71647747d6629cacaaa3de5fbfa7f444e9eae`.
62+
5863
## Deterministic macOS DMG Notes
64+
5965
Working macOS DMGs are created in Linux by combining a recent `clang`, the Apple
6066
`binutils` (`ld`, `ar`, etc) and DMG authoring tools.
6167

contrib/macdeploy/gen-sdk

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ import gzip
88
import os
99
import contextlib
1010

11+
# monkey-patch Python 3.8 and older to fix wrong TAR header handling
12+
# see https://github.com/bitcoin/bitcoin/pull/24534
13+
# and https://github.com/python/cpython/pull/18080 for more info
14+
if sys.version_info < (3, 9):
15+
_old_create_header = tarfile.TarInfo._create_header
16+
def _create_header(info, format, encoding, errors):
17+
buf = _old_create_header(info, format, encoding, errors)
18+
# replace devmajor/devminor with binary zeroes
19+
buf = buf[:329] + bytes(16) + buf[345:]
20+
# recompute checksum
21+
chksum = tarfile.calc_chksums(buf)[0]
22+
buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:]
23+
return buf
24+
tarfile.TarInfo._create_header = staticmethod(_create_header)
25+
1126
@contextlib.contextmanager
1227
def cd(path):
1328
"""Context manager that restores PWD even if an exception was raised."""
@@ -75,14 +90,21 @@ def run():
7590
tarinfo.name = str(pathlib.Path(alt_base_dir, tarinfo.name))
7691
if tarinfo.linkname and tarinfo.linkname.startswith("./"):
7792
tarinfo.linkname = str(pathlib.Path(alt_base_dir, tarinfo.linkname))
93+
# make metadata deterministic
94+
tarinfo.mtime = 0
95+
tarinfo.uid, tarinfo.uname = 0, ''
96+
tarinfo.gid, tarinfo.gname = 0, ''
97+
# don't use isdir() as there are also executable files present
98+
tarinfo.mode = 0o0755 if tarinfo.mode & 0o0100 else 0x0644
7899
return tarinfo
79100
with cd(dir_to_add):
101+
# recursion already adds entries in sorted order
80102
tarfp.add(".", recursive=True, filter=change_tarinfo_base)
81103

82104
print("Creating output .tar.gz file...")
83105
with out_sdktgz_path.open("wb") as fp:
84106
with gzip.GzipFile(fileobj=fp, mode='wb', compresslevel=9, mtime=0) as gzf:
85-
with tarfile.open(mode="w", fileobj=gzf) as tarfp:
107+
with tarfile.open(mode="w", fileobj=gzf, format=tarfile.GNU_FORMAT) as tarfp:
86108
print("Adding MacOSX SDK {} files...".format(sdk_version))
87109
tarfp_add_with_base_change(tarfp, sdk_dir, out_name)
88110
print("Adding libc++ headers...")

0 commit comments

Comments
 (0)