Skip to content

Commit c8ce263

Browse files
committed
Merge #16392: build: macOS toolchain update
7e21044 build: use macOS 10.14 SDK (fanquake) ca5055a depends: native_cctools 921, ld64 409.12, libtapi 1000.10.8 (fanquake) 1de8c06 depends: clang 6.0.1 (fanquake) Pull request description: TLDR: This updates our macOS toolchain to use a newer version of Clang, cctools (including new [dependency on libtapi](https://github.com/tpoechtrager/cctools-port/tree/master#dependencies)), LD64 and the macOS SDK. I've been testing depends builds (`HOST=x86_64-apple-darwin16`) inside a Debian Buster [Docker container](https://github.com/fanquake/core-review/blob/master/docker/debian.dockerfile), and running the resultant `bitcoind` and `bitcoin-qt` binaries on a macOS `10.14.4` system. The `.dmg` generated by a `make deploy` also mounts correctly on the same macOS system. #### Clang Upgraded from `3.7.1` to [`6.0.1`](https://releases.llvm.org/6.0.1/docs/ReleaseNotes.html) #### cctools * cctools `877.8` -> [`921`](https://opensource.apple.com/tarballs/cctools/) * LD64 `253.9` -> [`409.12`](https://opensource.apple.com/source/ld64/) * TAPI [`1000.10.8`](https://opensource.apple.com/tarballs/tapi/) See [tpoechtrager/cctools-port](https://github.com/tpoechtrager/cctools-port/) and [tpoechtrager/apple-libtapi](https://github.com/tpoechtrager/apple-libtapi/). #### macOS SDK Upgraded from building against the macOS `10.11` SDK to the macOS `10.14` SDK. #### TODO - [x] Make the `10.14` SDK available to Travis. Fixes: #16052 Closes: #14797 ACKs for top commit: Sjors: re-ACK 7e21044 (rebased from 248526e) dongcarl: ACK 7e21044 Tree-SHA512: fd36a33dbfb98c144240f8c69b77343e3f5bc18d8cf7d40fff61f51ad48925ec1872e6daba34c4045b18b4c2c84c22c744ebf4cba11061a0305eed13975ceefe
2 parents 0166883 + 7e21044 commit c8ce263

File tree

9 files changed

+166
-128
lines changed

9 files changed

+166
-128
lines changed

ci/test/00_setup_env_mac.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8
88

99
export HOST=x86_64-apple-darwin16
1010
export PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools"
11-
export OSX_SDK=10.11
11+
export OSX_SDK=10.14
1212
export RUN_UNIT_TESTS=false
1313
export RUN_FUNCTIONAL_TESTS=false
1414
export GOAL="deploy"

contrib/gitian-build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def main():
209209
args.macos = 'm' in args.os
210210

211211
# Disable for MacOS if no SDK found
212-
if args.macos and not os.path.isfile('gitian-builder/inputs/MacOSX10.11.sdk.tar.gz'):
212+
if args.macos and not os.path.isfile('gitian-builder/inputs/MacOSX10.14.sdk.tar.gz'):
213213
print('Cannot build for MacOS, SDK does not exist. Will build for other OSes')
214214
args.macos = False
215215

contrib/gitian-descriptors/gitian-osx.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ remotes:
3232
- "url": "https://github.com/bitcoin/bitcoin.git"
3333
"dir": "bitcoin"
3434
files:
35-
- "MacOSX10.11.sdk.tar.gz"
35+
- "MacOSX10.14.sdk.tar.gz"
3636
script: |
3737
set -e -o pipefail
3838
@@ -90,7 +90,7 @@ script: |
9090
BASEPREFIX="${PWD}/depends"
9191
9292
mkdir -p ${BASEPREFIX}/SDKs
93-
tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz
93+
tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.14.sdk.tar.gz
9494
9595
# Build dependencies for each host
9696
for i in $HOSTS; do

contrib/macdeploy/README.md

Lines changed: 128 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,135 @@
1-
### MacDeploy ###
1+
# MacOS Deployment
22

3-
For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package:
3+
The `macdeployqtplus` script should not be run manually. Instead, after building as usual:
44

5-
sudo easy_install argparse
5+
```bash
6+
make deploy
7+
```
68

7-
This script should not be run manually, instead, after building as usual:
9+
During the deployment process, the disk image window will pop up briefly
10+
when the fancy settings are applied. This is normal, please do not interfere,
11+
the process will unmount the DMG and cleanup before finishing.
812

9-
make deploy
13+
When complete, it will have produced `Bitcoin-Qt.dmg`.
1014

11-
During the process, the disk image window will pop up briefly where the fancy
12-
settings are applied. This is normal, please do not interfere.
15+
## SDK Extraction
1316

14-
When finished, it will produce `Bitcoin-Qt.dmg`.
17+
`Xcode.app` is packaged in a `.xip` archive.
18+
This makes the SDK less-trivial to extract on non-macOS machines.
19+
One approach (tested on Debian Buster) is outlined below:
1520

21+
```bash
22+
23+
apt install clang cpio git liblzma-dev libxml2-dev libssl-dev make
24+
25+
git clone https://github.com/tpoechtrager/xar
26+
pushd xar/xar
27+
./configure
28+
make
29+
make install
30+
popd
31+
32+
git clone https://github.com/NiklasRosenstein/pbzx
33+
pushd pbzx
34+
clang -llzma -lxar pbzx.c -o pbzx -Wl,-rpath=/usr/local/lib
35+
popd
36+
37+
xar -xf Xcode_10.2.1.xip -C .
38+
39+
./pbzx/pbzx -n Content | cpio -i
40+
41+
find Xcode.app -type d -name MacOSX.sdk -execdir sh -c 'tar -c MacOSX.sdk/ | gzip -9n > /MacOSX10.14.sdk.tar.gz' \;
42+
```
43+
44+
on macOS the process is more straightforward:
45+
46+
```bash
47+
xip -x Xcode_10.2.1.xip
48+
tar -C Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.14.sdk.tar.gz MacOSX.sdk
49+
```
50+
51+
Our previously used macOS SDK (`MacOSX10.11.sdk`) can be extracted from
52+
[Xcode 7.3.1 dmg](https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_7.3.1/Xcode_7.3.1.dmg).
53+
The script [`extract-osx-sdk.sh`](./extract-osx-sdk.sh) automates this. First
54+
ensure the DMG file is in the current directory, and then run the script. You
55+
may wish to delete the `intermediate 5.hfs` file and `MacOSX10.11.sdk` (the
56+
directory) when you've confirmed the extraction succeeded.
57+
58+
```bash
59+
apt-get install p7zip-full sleuthkit
60+
contrib/macdeploy/extract-osx-sdk.sh
61+
rm -rf 5.hfs MacOSX10.11.sdk
62+
```
63+
64+
## Deterministic macOS DMG Notes
65+
Working macOS DMGs are created in Linux by combining a recent `clang`, the Apple
66+
`binutils` (`ld`, `ar`, etc) and DMG authoring tools.
67+
68+
Apple uses `clang` extensively for development and has upstreamed the necessary
69+
functionality so that a vanilla clang can take advantage. It supports the use of `-F`,
70+
`-target`, `-mmacosx-version-min`, and `--sysroot`, which are all necessary when
71+
building for macOS.
72+
73+
Apple's version of `binutils` (called `cctools`) contains lots of functionality missing in the
74+
FSF's `binutils`. In addition to extra linker options for frameworks and sysroots, several
75+
other tools are needed as well such as `install_name_tool`, `lipo`, and `nmedit`. These
76+
do not build under Linux, so they have been patched to do so. The work here was used as
77+
a starting point: [mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4).
78+
79+
In order to build a working toolchain, the following source packages are needed from
80+
Apple: `cctools`, `dyld`, and `ld64`.
81+
82+
These tools inject timestamps by default, which produce non-deterministic binaries. The
83+
`ZERO_AR_DATE` environment variable is used to disable that.
84+
85+
This version of `cctools` has been patched to use the current version of `clang`'s headers
86+
and its `libLTO.so` rather than those from `llvmgcc`, as it was originally done in `toolchain4`.
87+
88+
To complicate things further, all builds must target an Apple SDK. These SDKs are free to
89+
download, but not redistributable. To obtain it, register for an Apple Developer Account,
90+
then download [Xcode 10.2.1](https://download.developer.apple.com/Developer_Tools/Xcode_10.2.1/Xcode_10.2.1.xip).
91+
92+
This file is many gigabytes in size, but most (but not all) of what we need is
93+
contained only in a single directory:
94+
95+
```bash
96+
Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
97+
```
98+
99+
See the SDK Extraction notes above for how to obtain it.
100+
101+
The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries which are
102+
created using these tools. The build process has been designed to avoid including the
103+
SDK's files in Gitian's outputs. All interim tarballs are fully deterministic and may be freely
104+
redistributed.
105+
106+
`genisoimage` is used to create the initial DMG. It is not deterministic as-is, so it has been
107+
patched. A system `genisoimage` will work fine, but it will not be deterministic because
108+
the file-order will change between invocations. The patch can be seen here: [cdrkit-deterministic.patch](https://github.com/bitcoin/bitcoin/blob/master/depends/patches/native_cdrkit/cdrkit-deterministic.patch).
109+
No effort was made to fix this cleanly, so it likely leaks memory badly, however it's only used for
110+
a single invocation, so that's no real concern.
111+
112+
`genisoimage` cannot compress DMGs, so afterwards, the DMG tool from the
113+
`libdmg-hfsplus` project is used to compress it. There are several bugs in this tool and its
114+
maintainer has seemingly abandoned the project.
115+
116+
The DMG tool has the ability to create DMGs from scratch as well, but this functionality is
117+
broken. Only the compression feature is currently used. Ideally, the creation could be fixed
118+
and `genisoimage` would no longer be necessary.
119+
120+
Background images and other features can be added to DMG files by inserting a
121+
`.DS_Store` before creation. This is generated by the script `contrib/macdeploy/custom_dsstore.py`.
122+
123+
As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in
124+
order to satisfy the new Gatekeeper requirements. Because this private key cannot be
125+
shared, we'll have to be a bit creative in order for the build process to remain somewhat
126+
deterministic. Here's how it works:
127+
128+
- Builders use Gitian to create an unsigned release. This outputs an unsigned DMG which
129+
users may choose to bless and run. It also outputs an unsigned app structure in the form
130+
of a tarball, which also contains all of the tools that have been previously (deterministically)
131+
built in order to create a final DMG.
132+
- The Apple keyholder uses this unsigned app to create a detached signature, using the
133+
script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs).
134+
- Builders feed the unsigned app + detached signature back into Gitian. It uses the
135+
pre-built tools to recombine the pieces into a deterministic DMG.

depends/hosts/darwin.mk

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
OSX_MIN_VERSION=10.12
2-
OSX_SDK_VERSION=10.11
2+
OSX_SDK_VERSION=10.14
33
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
4-
LD64_VERSION=253.9
5-
darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
6-
darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++
4+
darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
5+
darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++
76

87
darwin_CFLAGS=-pipe
98
darwin_CXXFLAGS=$(darwin_CFLAGS)

depends/packages/native_cctools.mk

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
11
package=native_cctools
2-
$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6
3-
$(package)_download_path=https://github.com/theuni/cctools-port/archive
2+
$(package)_version=3764b223c011574971ee3ae09ce968ba5dc2f00f
3+
$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive
44
$(package)_file_name=$($(package)_version).tar.gz
5-
$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a
5+
$(package)_sha256_hash=3e35907bf376269a844df08e03cbb43e345c88125374f2228e03724b5f9a2a04
66
$(package)_build_subdir=cctools
7-
$(package)_clang_version=3.7.1
8-
$(package)_clang_download_path=https://llvm.org/releases/$($(package)_clang_version)
7+
$(package)_clang_version=6.0.1
8+
$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version)
99
$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz
1010
$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz
11-
$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9
11+
$(package)_clang_sha256_hash=fa5416553ca94a8c071a27134c094a5fb736fe1bd0ecc5ef2d9bc02754e1bef0
12+
13+
$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef
14+
$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive
15+
$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz
16+
$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz
17+
$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3
18+
1219
$(package)_extra_sources=$($(package)_clang_file_name)
20+
$(package)_extra_sources += $($(package)_libtapi_file_name)
1321

1422
define $(package)_fetch_cmds
1523
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
16-
$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash))
24+
$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \
25+
$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash))
1726
endef
1827

1928
define $(package)_extract_cmds
2029
mkdir -p $($(package)_extract_dir) && \
2130
echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \
2231
echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \
32+
echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \
2333
$(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \
24-
mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \
34+
mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \
35+
mkdir -p libtapi && \
36+
tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \
2537
tar --no-same-owner --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
2638
rm -f toolchain/lib/libc++abi.so* && \
27-
echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \
28-
echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \
29-
chmod +x toolchain/bin/$(host)-dsymutil && \
3039
tar --no-same-owner --strip-components=1 -xf $($(package)_source)
3140
endef
3241

3342
define $(package)_set_vars
34-
$(package)_config_opts=--target=$(host) --disable-lto-support
35-
$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
36-
$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang
37-
$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++
43+
$(package)_config_opts=--target=$(host) --disable-lto-support --with-libtapi=$($(package)_extract_dir)
44+
$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
45+
$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang
46+
$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++
3847
endef
3948

4049
define $(package)_preprocess_cmds
41-
cd $($(package)_build_subdir); ./autogen.sh && \
42-
sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h
50+
CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \
51+
CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \
52+
sed -i.old "/define HAVE_PTHREADS/d" $($(package)_build_subdir)/ld64/src/ld/InputFiles.h
4353
endef
4454

4555
define $(package)_config_cmds
@@ -52,6 +62,9 @@ endef
5262

5363
define $(package)_stage_cmds
5464
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
65+
mkdir -p $($(package)_staging_prefix_dir)/lib/ && \
66+
cd $($(package)_extract_dir) && \
67+
cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \
5568
cd $($(package)_extract_dir)/toolchain && \
5669
mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \
5770
mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \

depends/packages/qt.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ $(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSIO
121121
$(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-"
122122
$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION)
123123
$(package)_config_opts_darwin += -device-option MAC_TARGET=$(host)
124-
$(package)_config_opts_darwin += -device-option MAC_LD64_VERSION=$(LD64_VERSION)
125124
endif
126125

127126
$(package)_config_opts_linux = -qt-xkbcommon-x11

depends/patches/qt/mac-qmake.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ QMAKE_APPLE_DEVICE_ARCHS=x86_64
1818
!host_build: QMAKE_CFLAGS += -target $${MAC_TARGET}
1919
!host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
2020
!host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
21-
!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION}
21+
!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET}
2222
QMAKE_AR = $${CROSS_COMPILE}ar cq
2323
QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
2424
QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool

0 commit comments

Comments
 (0)