Skip to content

Commit be100cf

Browse files
committed
Merge bitcoin/bitcoin#21778: build: LLD based macOS toolchain
e8c25e8 guix: drop binutils from macOS env (fanquake) 555fddf guix: use GUIX_LD_WRAPPER_DISABLE_RPATH for all HOSTS (fanquake) 9ec238d guix: remove ZERO_AR_DATE export (fanquake) f836f7e depends: remove cctools & libtapi (fanquake) 4a0536c build: switch to using lld for macOS builds (fanquake) c6a6b2d build: add lld into macOS build environment(s) (fanquake) 437e908 depends: swap cctools-x for llvm-x (fanquake) bab287d depends: don't use -no_warning_for_no_symbols in macOS qt build (fanquake) Pull request description: This switches us to using a [LLD](https://lld.llvm.org/) based toolchain for macOS builds. ### Benefits * Less complicated macOS toolchain. * No longer beholden to Apple releasing it's [source](https://opensource.apple.com/source/) for [cctools](https://opensource.apple.com/source/cctools/), [ld64](https://opensource.apple.com/source/ld64/) & [libtapi](https://opensource.apple.com/source/tapi/). * No more reliance on third parties to modify those sources for us. i.e [apple-libtapi](https://github.com/tpoechtrager/apple-libtapi), [cctools-port](https://github.com/tpoechtrager/cctools-port) (cctools + ld64). ACKs for top commit: theuni: Tentative ACK e8c25e8. Tree-SHA512: ec73304e8a2cd4c71041f7863d7d2e4e0408787299fb4fa3745076853156e8f64e4742e16f30d65e3a27f1e9c0d19cdf802248366b72a4fcb4ea821f92bb7a00
2 parents 417b6ce + e8c25e8 commit be100cf

File tree

18 files changed

+66
-162
lines changed

18 files changed

+66
-162
lines changed

contrib/devtools/symbol-check.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def check_MACHO_sdk(binary) -> bool:
240240
return False
241241

242242
def check_MACHO_ld64(binary) -> bool:
243-
if binary.build_version.tools[0].version == [711, 0, 0]:
243+
if binary.build_version.tools[0].version == [17, 0, 6]:
244244
return True
245245
return False
246246

contrib/devtools/test-security-check.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,15 @@ def test_MACHO(self):
120120
arch = get_arch(cc, source, executable)
121121

122122
if arch == lief.ARCHITECTURES.X86:
123-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-no_fixup_chains']),
124-
(1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE NX CONTROL_FLOW'))
125-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-fixup_chains']),
126-
(1, executable+': failed NOUNDEFS Canary PIE NX CONTROL_FLOW'))
127-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all', '-Wl,-fixup_chains']),
128-
(1, executable+': failed NOUNDEFS PIE NX CONTROL_FLOW'))
129-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']),
130-
(1, executable+': failed NOUNDEFS PIE CONTROL_FLOW'))
131-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']),
132-
(1, executable+': failed PIE CONTROL_FLOW'))
133-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']),
134-
(1, executable+': failed PIE CONTROL_FLOW'))
135-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']),
136-
(1, executable+': failed PIE'))
137-
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']),
123+
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']),
124+
(1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE CONTROL_FLOW'))
125+
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains']),
126+
(1, executable+': failed NOUNDEFS Canary CONTROL_FLOW'))
127+
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']),
128+
(1, executable+': failed NOUNDEFS CONTROL_FLOW'))
129+
self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains']),
130+
(1, executable+': failed CONTROL_FLOW'))
131+
self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']),
138132
(0, ''))
139133
else:
140134
# arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks

contrib/guix/libexec/build.sh

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,7 @@ for p in "${PATHS[@]}"; do
133133
done
134134

135135
# Disable Guix ld auto-rpath behavior
136-
case "$HOST" in
137-
*darwin*)
138-
# The auto-rpath behavior is necessary for darwin builds as some native
139-
# tools built by depends refer to and depend on Guix-built native
140-
# libraries
141-
#
142-
# After the native packages in depends are built, the ld wrapper should
143-
# no longer affect our build, as clang would instead reach for
144-
# x86_64-apple-darwin-ld from cctools
145-
;;
146-
*) export GUIX_LD_WRAPPER_DISABLE_RPATH=yes ;;
147-
esac
136+
export GUIX_LD_WRAPPER_DISABLE_RPATH=yes
148137

149138
# Make /usr/bin if it doesn't exist
150139
[ -e /usr/bin ] || mkdir -p /usr/bin
@@ -173,16 +162,6 @@ esac
173162
# Environment variables for determinism
174163
export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name"
175164
export TZ="UTC"
176-
case "$HOST" in
177-
*darwin*)
178-
# cctools AR, unlike GNU binutils AR, does not have a deterministic mode
179-
# or a configure flag to enable determinism by default, it only
180-
# understands if this env-var is set or not. See:
181-
#
182-
# https://github.com/tpoechtrager/cctools-port/blob/55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/ar/archive.c#L334
183-
export ZERO_AR_DATE=yes
184-
;;
185-
esac
186165

187166
####################
188167
# Depends Building #

contrib/guix/manifest.scm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,9 @@ inspecting signatures in Mach-O binaries.")
532532
((string-contains target "darwin")
533533
(list ;; Native GCC 11 toolchain
534534
gcc-toolchain-11
535-
binutils
536535
clang-toolchain-17
536+
lld-17
537+
(make-lld-wrapper lld-17 #:lld-as-ld? #t)
537538
python-signapple
538539
zip))
539540
(else '())))))

contrib/macdeploy/README.md

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,13 @@ The `sha256sum` should be `c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c28
5656

5757
## Deterministic macOS App Notes
5858

59-
macOS Applications are created in Linux by combining a recent `clang` and the Apple
60-
`binutils` (`ld`, `ar`, etc).
59+
macOS Applications are created in Linux using a recent LLVM.
6160

6261
Apple uses `clang` extensively for development and has upstreamed the necessary
6362
functionality so that a vanilla clang can take advantage. It supports the use of `-F`,
6463
`-target`, `-mmacosx-version-min`, and `-isysroot`, which are all necessary when
6564
building for macOS.
6665

67-
Apple's version of `binutils` (called `cctools`) contains lots of functionality missing in the
68-
FSF's `binutils`. In addition to extra linker options for frameworks and sysroots, several
69-
other tools are needed as well. These do not build under Linux, so they have been patched to
70-
do so. The work here was used as a starting point: [mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4).
71-
72-
In order to build a working toolchain, the following source packages are needed from
73-
Apple: `cctools`, `dyld`, and `ld64`.
74-
75-
These tools inject timestamps by default, which produce non-deterministic binaries. The
76-
`ZERO_AR_DATE` environment variable is used to disable that.
77-
78-
This version of `cctools` has been patched to use the current version of `clang`'s headers
79-
and its `libLTO.so` rather than those from `llvmgcc`, as it was originally done in `toolchain4`.
80-
8166
To complicate things further, all builds must target an Apple SDK. These SDKs are free to
8267
download, but not redistributable. See the SDK Extraction notes above for how to obtain it.
8368

depends/Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ all_packages = $(packages) $(native_packages)
185185

186186
meta_depends = Makefile config.guess config.sub funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
187187

188-
$(host_arch)_$(host_os)_native_binutils?=$($(host_os)_native_binutils)
189188
$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain)
190189

191190
include funcs.mk
@@ -217,9 +216,8 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages)
217216
# tool needs to be available in $PATH at all times.
218217
#
219218
# 2. If the tool is _**not**_ expected to be available in $PATH at all times
220-
# (such as is the case for our native_cctools binutils tools), it needs to
221-
# be referred to by its absolute path, such as would be output by the
222-
# AC_PATH_{PROG,TOOL} macros.
219+
# it needs to be referred to by its absolute path, such as would be output
220+
# by the AC_PATH_{PROG,TOOL} macros.
223221
#
224222
# Minor note: it is also okay to refer to tools by their absolute path even if
225223
# we expect them to be available in $PATH at all times, more specificity does

depends/builders/darwin.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ darwin_STRIP:=$(shell xcrun -f strip)
1818
darwin_OBJDUMP:=$(shell xcrun -f objdump)
1919
darwin_NM:=$(shell xcrun -f nm)
2020
darwin_DSYMUTIL:=$(shell xcrun -f dsymutil)
21-
darwin_native_binutils=
2221
darwin_native_toolchain=
2322

2423
x86_64_darwin_CFLAGS += -arch x86_64

depends/funcs.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ endef
4646

4747
define int_get_build_id
4848
$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
49-
$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies)))
49+
$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies)))
5050
$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
5151
$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id))
5252
$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
@@ -299,4 +299,4 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$
299299
$(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package))))
300300

301301
#special exception: if a toolchain package exists, all non-native packages depend on it
302-
$(foreach package,$(packages),$(eval $($(package)_extracted): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) $($($(host_arch)_$(host_os)_native_binutils)_cached) ))
302+
$(foreach package,$(packages),$(eval $($(package)_extracted): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) ))

depends/gen_id

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
echo "BEGIN AR"
5454
bash -c "${AR} --version"
5555
env | grep '^AR_'
56-
echo "ZERO_AR_DATE=${ZERO_AR_DATE}"
5756
echo "END AR"
5857

5958
echo "BEGIN NM"

depends/hosts/darwin.mk

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,28 @@ LD64_VERSION=711
66

77
OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers
88

9-
darwin_native_binutils=native_cctools
10-
119
ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),)
12-
# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang
10+
# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned LLVM
1311
# from llvm.org
1412

15-
# Clang is a dependency of native_cctools when FORCE_USE_SYSTEM_CLANG is empty
16-
darwin_native_toolchain=native_cctools
13+
darwin_native_toolchain=native_llvm
1714

1815
clang_prog=$(build_prefix)/bin/clang
1916
clangxx_prog=$(clang_prog)++
2017
llvm_config_prog=$(build_prefix)/bin/llvm-config
2118

22-
darwin_OBJDUMP=$(build_prefix)/bin/$(host)-objdump
19+
llvm_TOOLS=AR NM OBJDUMP RANLIB STRIP
20+
21+
# Make-only lowercase function
22+
lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
23+
24+
# For well-known tools provided by LLVM, make sure that their well-known
25+
# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG}
26+
# would.
27+
$(foreach TOOL,$(llvm_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/llvm-$(call lc,$(TOOL))))
28+
29+
# Clang expects dsymutil to be called dsymutil
30+
darwin_DSYMUTIL=$(build_prefix)/bin/dsymutil
2331

2432
else
2533
# FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's
@@ -40,19 +48,14 @@ llvm_config_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-config")
4048

4149
llvm_lib_dir=$(shell $(llvm_config_prog) --libdir)
4250

51+
darwin_AR=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ar")
52+
darwin_DSYMUTIL=$(shell $(SHELL) $(.SHELLFLAGS) "command -v dsymutil")
53+
darwin_NM=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-nm")
4354
darwin_OBJDUMP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-objdump")
55+
darwin_RANLIB=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ranlib")
56+
darwin_STRIP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-strip")
4457
endif
4558

46-
cctools_TOOLS=AR RANLIB STRIP NM DSYMUTIL
47-
48-
# Make-only lowercase function
49-
lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
50-
51-
# For well-known tools provided by cctools, make sure that their well-known
52-
# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG}
53-
# would.
54-
$(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(host)-$(call lc,$(TOOL))))
55-
5659
# Flag explanations:
5760
#
5861
# -mlinker-version
@@ -62,7 +65,7 @@ $(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(
6265
#
6366
# -B$(build_prefix)/bin
6467
#
65-
# Explicitly point to our binaries (e.g. cctools) so that they are
68+
# Explicitly point to our binaries so that they are
6669
# ensured to be found and preferred over other possibilities.
6770
#
6871
# -isysroot$(OSX_SDK) -nostdlibinc
@@ -79,6 +82,11 @@ $(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(
7982
#
8083
# Indicate to the linker the platform, the oldest supported version,
8184
# and the SDK used.
85+
#
86+
# -no_adhoc_codesign
87+
#
88+
# Disable adhoc codesigning (for now) when using LLVM tooling, to avoid
89+
# non-determinism issues with the Identifier field.
8290

8391
darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \
8492
-u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \
@@ -104,6 +112,7 @@ darwin_LDFLAGS=-Wl,-platform_version,macos,$(OSX_MIN_VERSION),$(OSX_SDK_VERSION)
104112
ifneq ($(build_os),darwin)
105113
darwin_CFLAGS += -mlinker-version=$(LD64_VERSION)
106114
darwin_CXXFLAGS += -mlinker-version=$(LD64_VERSION)
115+
darwin_LDFLAGS += -Wl,-no_adhoc_codesign -fuse-ld=lld
107116
endif
108117

109118
darwin_release_CFLAGS=-O2

0 commit comments

Comments
 (0)