Skip to content

feat(Toolchain): Darwin toolchain for SDK paths#974

Open
dotcarmen wants to merge 1 commit into
Vexu:masterfrom
dotcarmen:darwin-toolchain
Open

feat(Toolchain): Darwin toolchain for SDK paths#974
dotcarmen wants to merge 1 commit into
Vexu:masterfrom
dotcarmen:darwin-toolchain

Conversation

@dotcarmen

@dotcarmen dotcarmen commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

as i'm working on objective-c support (per #970), i've realized that support is somewhat blocked on fetching the SDK path for the target platform - specifically, for objc headers, which i believe are implicitly included in Objective-C files.

this PR adds a new toolchains/Darwin.zig file for Darwin-specific target behavior. Right now, this is only used to:

  1. add the SDK library path ($SDKROOT/usr/lib)
  2. add the SDK include path ($SDKROOT/usr/include)

In a future PR, this file will be expanded to add the SDK framework path ($SDKROOT/System/Library/Frameworks)

@dotcarmen

This comment was marked as outdated.

@dotcarmen dotcarmen marked this pull request as draft March 5, 2026 02:26
@dotcarmen dotcarmen force-pushed the darwin-toolchain branch 5 times, most recently from 3157b10 to b79e0b3 Compare April 5, 2026 22:48
Comment thread src/aro/toolchains/Darwin.zig
Comment thread src/aro/toolchains/Darwin.zig Outdated
@dotcarmen dotcarmen force-pushed the darwin-toolchain branch 2 times, most recently from 181bdb0 to 6be63d9 Compare April 5, 2026 23:20
@brodo

brodo commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

You may want to allow uses to specify the system framework and include paths independently of --sysroot. We did need that for dvui. I can't really remember why, though. Also, maybe this is helpful.

@dotcarmen

dotcarmen commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

You may want to allow uses to specify the system framework and include paths independently of --sysroot.

i'm not going to do that in this PR - that could probably done similarly to eg clang's -internal-isystem, which i think bypasses the automatic path-adding done here. but overall i think it's usually unnecessary. (more on this below)

framework paths will come via objc pr(s)

We did need that for dvui. I can't really remember why, though.

looks like it's for sdl3. this is the commit referenced in dvui's build.zig.zon (that commit doesn't appear to be in a branch btw). the reason why it's needed seems to be here. that use case is already covered by -isystem with aro :) no need to add anything new for it.

i will note as an aside that darwin system clang is actually a wrapper for clang that seems to run xcrun to find the toolchain and sdk for the sysroot. run any clang command with --verbose and something like this shows up (formatted by me):

clang output
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" \
  -cc1 \
  -triple arm64-apple-macosx26.0.0 \
  -Wundef-prefix=TARGET_OS_ \
  -Wdeprecated-objc-isa-usage \
  -Werror=deprecated-objc-isa-usage \
  -Werror=implicit-function-declaration \
  -emit-obj \
  -dumpdir a- \
  -disable-free \
  -clear-ast-before-backend \
  -disable-llvm-verifier \
  -discard-value-names \
  -main-file-name - \
  -mrelocation-model pic \
  -pic-level 2 \
  -mframe-pointer=non-leaf \
  -fno-strict-return \
  -ffp-contract=on \
  -fno-rounding-math \
  -funwind-tables=1 \
  -fobjc-msgsend-selector-stubs \
  -fno-sized-deallocation \
  -target-sdk-version=26.5 \
  -fvisibility-inlines-hidden-static-local-var \
  -fno-modulemap-allow-subdirectory-search \
  -fdefine-target-os-macros \
  -fno-assume-unique-vtables \
  -fno-modulemap-allow-subdirectory-search \
  -enable-tlsdesc \
  -target-cpu apple-m1
  -target-feature +v8.5a \
  -target-feature +aes \
  -target-feature +altnzcv \
  -target-feature +ccdp \
  -target-feature +ccpp \
  -target-feature +complxnum \
  -target-feature +crc \
  -target-feature +dotprod \
  -target-feature +flagm \
  -target-feature +fp-armv8 \
  -target-feature +fp16fml \
  -target-feature +fptoint \
  -target-feature +fullfp16 \
  -target-feature +jsconv \
  -target-feature +lse \
  -target-feature +neon \
  -target-feature +pauth \
  -target-feature +perfmon \
  -target-feature +predres \
  -target-feature +ras \
  -target-feature +rcpc \
  -target-feature +rdm \
  -target-feature +sb \
  -target-feature +sha2 \
  -target-feature +sha3 \
  -target-feature +specrestrict \
  -target-feature +ssbs \
  -target-abi darwinpcs \
  -debugger-tuning=lldb \
  -fdebug-compilation-dir=/Users/carmen/github.com/Vexu/arocc \
  -target-linker-version 1267 \
  -v \
  -fcoverage-compilation-dir=/Users/carmen/github.com/Vexu/arocc \
  -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21 \
  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \
  -I/usr/local/include \
  -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include \
  -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/21/include \
  -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include \
  -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include \
  -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks \
  -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/SubFrameworks \
  -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks \
  -Wno-elaborated-enum-base \
  -ferror-limit 19 \
  -fmessage-length=101 \
  -stack-protector 1 \
  -fstack-check \
  -mdarwin-stkchk-strong-link \
  -fblocks \
  -fencode-extended-block-signature \
  -fregister-global-dtors-with-atexit \
  -fgnuc-version=4.2.1 \
  -fskip-odr-check-in-gmf \
  -fmax-type-align=16 \
  -fcommon \
  -fcolor-diagnostics \
  -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation \
  -fno-odr-hash-protocols \
  -clang-vendor-feature=+enableAggressiveVLAFolding \
  -clang-vendor-feature=+revert09abecef7bbf \
  -clang-vendor-feature=+thisNoAlignAttr \
  -clang-vendor-feature=+thisNoNullAttr \
  -clang-vendor-feature=+disableAtImportPrivateFrameworkInImplementationError \
  -Wno-error=allocator-wrappers \
  -fdwarf2-cfi-asm \
  -o /var/folders/5h/0zrj5b294l96v9hpw7gyk_qw0000gn/T/--d78b35.o \
  -x c \
  -

those -internal-* flags look like they might be used to prevent adding the relevant paths based on sysroot. i also won't be implementing that (not particularly helpful, i believe), but it's something to consider

Also, maybe this is helpful.

that would be helpful for cross-platform testing objc work :) it would probably only be a test dependency though - i imagine if users want to cross-compile macos applications, they would probably want to control the SDK versions

@dotcarmen

dotcarmen commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

that could probably done similarly to eg clang's -internal-isystem, which i think bypasses the automatic path-adding done here.

i forgot about -nostdinc :) so yeah, -nostdinc -isystem ... would be the way to go if you really need to bypass the logic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i had another commit that used xcrun xcodebuild -sdk -version, but that looked a lot different and i think this is good enough, at least for now

Comment on lines +22 to +44
// clang args (via --verbose):
// -resource-dir <toolchain-path>/usr/lib/clang/21
// -isysroot <sdk-path>
// -I/usr/local/include
// -internal-isystem <sdk-path>/usr/local/include
// -internal-isystem <toolchain-path>/usr/lib/clang/21/include
// -internal-externc-isystem <sdk-path>/usr/include
// -internal-externc-isystem <toolchain-path>/usr/include
// -internal-iframework <sdk-path>/System/Library/Frameworks
// -internal-iframework <sdk-path>/System/Library/SubFrameworks
// -internal-iframework <sdk-path>/Library/Frameworks
//
// clang messages (via -E):
// ignoring nonexistent directory "/usr/local/include"
// ignoring nonexistent directory "<sdk-path>/usr/local/include"
// ignoring nonexistent directory "<sdk-path>/Library/Frameworks"
// #include "..." search starts here:
// #include <...> search starts here:
// <toolchain-path>/usr/lib/clang/21/include
// <sdk-path>/usr/include
// <toolchain-path>/usr/include
// <sdk-path>/System/Library/Frameworks (framework directory)
// <sdk-path>/System/Library/SubFrameworks (framework directory)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments here and below might be helpful in the future, but lmk if i should remove

if (tc.driver.sysroot) |sysroot| {
darwin.sdk_path = sysroot;
} else if (builtin.target.os.tag.isDarwin()) {
try tc.driver.diagnostics.add(.{ .kind = .note, .text = "--sysroot may be required when cross-compiling to Darwin targets", .location = null });

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apparently this can be a fatal error with -Weverything -Werror -Wfatal, which is why Driver.main now has to handle error.FatalError. this can be printed with std.debug.print instead, i can do that if desired

@dotcarmen dotcarmen marked this pull request as ready for review July 1, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants