Skip to content

Commit b1678dd

Browse files
committed
Improve macOS handling
Add minimum os version to packaged outputs, fix some tools like `llvm-objcopy`, `xcrun`, etc...
1 parent 2cdcd06 commit b1678dd

File tree

6 files changed

+112
-22
lines changed

6 files changed

+112
-22
lines changed

BinaryBuilderToolchains.jl/src/toolchains/CToolchain.jl

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,11 @@ function jll_source_selection(vendor::Symbol, platform::CrossPlatform,
266266
target=sysroot_path,
267267
)]
268268
elseif os(platform.target) == "macos"
269-
@warn("Take in `macos_version(platform.target)` and feed that to `macOSSDK_jll.jl` here", maxlog=1)
269+
if macos_version(platform.target) !== nothing
270+
if macos_version(platform.target) > v"11.1"
271+
throw(ArgumentError("We need to upgrade our macOSSDK_jll to support such a new version: $(triplet(platform.target))"))
272+
end
273+
end
270274
libc_jlls = [JLLSource(
271275
"macOSSDK_jll",
272276
platform.target;
@@ -689,11 +693,23 @@ function toolchain_env(toolchain::CToolchain, deployed_prefix::String)
689693

690694
sdk_jll = get_jll(toolchain, "macOSSDK_jll")
691695
if sdk_jll !== nothing
692-
env["MACOSX_DEPLOYMENT_TARGET"] = string(
693-
sdk_jll.package.version.major,
694-
".",
695-
sdk_jll.package.version.minor,
696+
# If toolchain platform already has an `os_version`, we need to obey that, otherwise we
697+
# use the default deployment targets for the architecture being built:
698+
function default_kernel_version(arch)
699+
if arch == "x86_64"
700+
return 14
701+
elseif arch == "aarch64"
702+
return 20
703+
else
704+
throw(ArgumentError("Unknown macOS architecture '$(arch)'!"))
705+
end
706+
end
707+
708+
kernel_version = something(
709+
os_version(toolchain.platform.target),
710+
default_kernel_version(arch(toolchain.platform.target))
696711
)
712+
env["MACOSX_DEPLOYMENT_TARGET"] = macos_version(kernel_version)
697713
end
698714

699715
return env
@@ -842,7 +858,7 @@ function add_macos_flags(io, toolchain)
842858
append_flags(io, :PRE, "-D_DARWIN_FEATURE_CLOCK_GETTIME=0")
843859
end
844860
end
845-
861+
846862
# Always compile for a particular minimum macOS version
847863
if macos_ver !== nothing
848864
append_flags(io, :PRE, "-mmacosx-version-min=$(macos_version(toolchain.platform.target))")
@@ -1058,6 +1074,24 @@ function clang_wrappers(toolchain::CToolchain, dir::String)
10581074
add_ccache_preamble(io, toolchain)
10591075
end
10601076

1077+
if Sys.isapple(p)
1078+
function _xcrun_wrapper(io)
1079+
flagmatch(io, [flag"--show-sdk-path"]) do io
1080+
println(io, raw"""
1081+
"${CC}" -print-sysroot
1082+
exit 0
1083+
""")
1084+
end
1085+
flagmatch(io, [flag"--show-sdk-version"]) do io
1086+
println(io, raw"""
1087+
echo "${MACOSX_DEPLOYMENT_TARGET}"
1088+
exit 0
1089+
""")
1090+
end
1091+
end
1092+
make_tool_wrappers(toolchain, dir, "xcrun", "exec"; wrapper=_xcrun_wrapper, toolchain_prefix)
1093+
end
1094+
10611095
make_tool_wrappers(toolchain, dir, "clang", "clang"; wrapper=_clang_wrapper, toolchain_prefix)
10621096
make_tool_wrappers(toolchain, dir, "clang++", "clang++"; wrapper=io -> _clang_wrapper(io; is_clangxx = true), toolchain_prefix)
10631097
make_tool_wrappers(toolchain, dir, "clang-scan-deps", "clang-scan-deps"; toolchain_prefix)
@@ -1075,10 +1109,7 @@ function binutils_wrappers(toolchain::CToolchain, dir::String)
10751109
gcc_version = get_gcc_version(toolchain)
10761110

10771111
# These tools don't need anything fancy; just `compiler_wrapper()`
1078-
simple_tools = [
1079-
"objcopy",
1080-
"objdump",
1081-
]
1112+
simple_tools = String[]
10821113
@warn("TODO: Verify that `as` does not need adjusted MACOSX_DEPLOYMENT_TARGET", maxlog=1)
10831114
@warn("TODO: Add in `ld.64` and `ld.target-triplet` again", maxlog=1)
10841115
# Apple has some extra simple tools
@@ -1356,6 +1387,12 @@ function binutils_wrappers(toolchain::CToolchain, dir::String)
13561387
ranlib_name = Sys.isapple(p) ? "llvm-ranlib" : "$(gcc_triplet)-ranlib"
13571388
make_tool_wrappers(toolchain, dir, "ranlib", ranlib_name; wrapper=_ranlib_wrapper, toolchain_prefix=llvm_toolchain_prefix)
13581389

1390+
objcopy_name = Sys.isapple(p) ? "llvm-objcopy" : "$(gcc_triplet)-objcopy"
1391+
make_tool_wrappers(toolchain, dir, "objcopy", objcopy_name; toolchain_prefix=llvm_toolchain_prefix)
1392+
1393+
objdump_name = Sys.isapple(p) ? "llvm-objdump" : "$(gcc_triplet)-objdump"
1394+
make_tool_wrappers(toolchain, dir, "objdump", objdump_name; toolchain_prefix=llvm_toolchain_prefix)
1395+
13591396
if Sys.isapple(p)
13601397
# dsymutil is just called `dsymutil`
13611398
make_tool_wrappers(toolchain, dir, "dsymutil", "dsymutil"; toolchain_prefix=llvm_toolchain_prefix)

bootstrap/LLVM/bundled/xcrun

Lines changed: 0 additions & 8 deletions
This file was deleted.

bootstrap/LLVM/compiler_rt.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ build_tarballs(;
2828
JLLSource(
2929
"Zlib_jll";
3030
repo=Pkg.Types.GitRepo(
31-
rev="bb2/GCC",
31+
rev="main",
3232
source="https://github.com/staticfloat/Zlib_jll.jl"
3333
),
3434
),
3535
],
36-
host_toolchains = [CToolchain(;vendor=:clang), CMakeToolchain(), HostToolsToolchain()],
37-
target_toolchains = [CToolchain(;vendor=:clang, lock_microarchitecture=false), CMakeToolchain()],
36+
host_toolchains = [CToolchain(;vendor=:clang_bootstrap), CMakeToolchain(), HostToolsToolchain()],
37+
target_toolchains = [CToolchain(;vendor=:clang_bootstrap, lock_microarchitecture=false), CMakeToolchain()],
3838
)

src/build_api/ExtractConfig.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ function SandboxConfig(config::ExtractConfig, output_dir::String, mounts = copy(
147147
return SandboxConfig(config.build.config, mounts; env, kwargs...)
148148
end
149149

150+
150151
function BinaryBuilderAuditor.audit!(config::ExtractConfig, artifact_dir::String; verbose::Bool = AbstractBuildMeta(config).verbose, kwargs...)
151152
build_config = config.build.config
152153
meta = AbstractBuildMeta(config)

src/build_api/PackageConfig.jl

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,56 @@ function JLLBuildLicenses(result::ExtractResult)
226226
return [JLLBuildLicense(f, String(read(joinpath(licenses_dir, package_name, f)))) for f in filenames]
227227
end
228228

229+
230+
231+
"""
232+
add_os_version(platform::AbstractPlatform, target_spec::BuildTargetSpec)
233+
234+
Adds an `os_version` tag to `platform` according to the runtimes built against
235+
in `target_spec`. Currently this is only done for macOS and FreeBSD but
236+
it is very possible this will be extended to glibc Linux in the future.
237+
238+
This is done automatically as part of the `package!()` call. There does not
239+
yet exist a way to opt out of this.
240+
"""
241+
function add_os_version(platform::Platform, target_spec::BuildTargetSpec)
242+
if os_version(platform) !== nothing
243+
return platform
244+
end
245+
246+
# Make a copy, since we actually modify `platform` here.
247+
platform = parse(Platform, triplet(platform))
248+
249+
if Sys.isapple(platform)
250+
libc_jll_name = "macOSSDK_jll"
251+
version_map = macos_kernel_version
252+
elseif Sys.isfreebsd(platform)
253+
libc_jll_name = "freebsd_something_jll"
254+
version_map = freebsd_kernel_version
255+
else
256+
# Other platforms don't do versioning yet
257+
return platform
258+
end
259+
260+
for toolchain in target_spec.toolchains
261+
if !isa(toolchain, CToolchain)
262+
continue
263+
end
264+
265+
tenv = toolchain_env(toolchain, "")
266+
# Get the version that the JLL corresponds to, and return!
267+
platform["os_version"] = string(version_map(tenv["MACOSX_DEPLOYMENT_TARGET"]))
268+
return platform
269+
end
270+
271+
# Unable to find an OS version, that's fine!
272+
return nothing
273+
end
274+
275+
function add_os_version(cp::CrossPlatform, target_spec::BuildTargetSpec)
276+
return CrossPlatform(add_os_version(cp.host, target_spec) => cp.target)
277+
end
278+
229279
function JLLGenerator.JLLBuildInfo(name::String, result::ExtractResult, extra_deps::Vector{PackageSpec})
230280
if result.status (:success, :cached)
231281
throw(ArgumentError("Cannot package failing result: $(result)"))
@@ -237,7 +287,7 @@ function JLLGenerator.JLLBuildInfo(name::String, result::ExtractResult, extra_de
237287
deps = JLLPackageDependencies(result, extra_deps),
238288
# Encode all sources that are mounted in `/workspace/srcdir`
239289
sources = JLLSourceRecords(result),
240-
platform = result.config.platform,
290+
platform = add_os_version(result.config.platform, result.config.target_spec),
241291
name,
242292
# TODO: Add links to our eventual deployment target
243293
artifact = JLLArtifactBinding(

test/BuildAPITests/ConvenienceTests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,14 @@ using BinaryBuilder2: get_package_result
4646
uni = Universe(universe_name; persistent=false)
4747
jll_names = ["Zlib_jll", "Ncurses_jll", "Readline_jll"]
4848
@test all(BinaryBuilder2.contains_jll.((uni,), jll_names))
49+
50+
51+
# All the tests above target a native linux; let's run a test on Windows and macOS, just so that
52+
# we're exercising those troublesome platforms in at least some way:
53+
@testset "Zlib on Windows and macOS" begin
54+
meta = BuildMeta(;universe_name,target_list=[Platform("x86_64", "windows"), Platform("aarch64", "macos")])
55+
run_build_tarballs(meta, joinpath(bootstrap_dir, "Zlib", "build_tarballs.jl"))
56+
package_result = get_package_result(meta, "Zlib")
57+
@test package_result.status == :success
58+
end
4959
end

0 commit comments

Comments
 (0)