-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
macos: change rules and improve detection of native SDK #16212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This should also close #11631 no? |
e322dc4 to
ce35ae8
Compare
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
I see a couple more things that could be further improved, let me know what you think.
src/Compilation.zig
Outdated
| try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2); | ||
| for (paths.include_dirs.items) |include_dir| { | ||
| clang_argv.appendAssumeCapacity("-isystem"); | ||
| clang_argv.appendAssumeCapacity(include_dir); | ||
| } | ||
|
|
||
| try clang_argv.ensureUnusedCapacity(paths.framework_dirs.items.len * 2); | ||
| try framework_dirs.ensureUnusedCapacity(paths.framework_dirs.items.len); | ||
| for (paths.framework_dirs.items) |framework_dir| { | ||
| clang_argv.appendAssumeCapacity("-iframework"); | ||
| clang_argv.appendAssumeCapacity(framework_dir); | ||
| framework_dirs.appendAssumeCapacity(framework_dir); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic pertaining to clang_argv should go in addCCArgs.
src/Compilation.zig
Outdated
| var clang_argv = std.ArrayList([]const u8).init(arena); | ||
| var lib_dirs = std.ArrayList([]const u8).init(arena); | ||
| var framework_dirs = std.ArrayList([]const u8).init(arena); | ||
| var rpath_list = std.ArrayList([]const u8).init(arena); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you try adding a commit that adds the needed state here (except clang_argv) to LibCDirs and moving the corresponding logic to detectLibCIncludeDirs or getZigShippedLibCIncludeDirsDarwin?
I think that might clean this up even more.
|
@andrewrk I took your suggestions a step further and now moved all of the logic into |
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting closer. I still see some things where they don't belong. Apologies for the vague review feedback - hopefully knowing what not to do reduces the possibility space so it becomes more clear how to proceed.
| break :blk false; | ||
| }; | ||
|
|
||
| const darwin_native = (comptime builtin.target.isDarwin()) and options.target.isDarwin() and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this boolean is already provided via options.is_native_os. It does not currently to take into account sysroot, however, and I'm not sure whether it should. Perhaps this would be better:
| const darwin_native = (comptime builtin.target.isDarwin()) and options.target.isDarwin() and | |
| const darwin_native = options.is_native_os and options.target.isDarwin() and |
src/Compilation.zig
Outdated
| var lib_dirs = std.ArrayList([]const u8).init(arena); | ||
| try lib_dirs.appendSlice(options.lib_dirs); | ||
| try lib_dirs.appendSlice(libc_dirs.libc_lib_dir_list); | ||
|
|
||
| var framework_dirs = std.ArrayList([]const u8).init(arena); | ||
| try framework_dirs.appendSlice(options.framework_dirs); | ||
| try framework_dirs.appendSlice(libc_dirs.libc_framework_dir_list); | ||
|
|
||
| var rpath_list = std.ArrayList([]const u8).init(arena); | ||
| try rpath_list.appendSlice(options.rpath_list); | ||
| try rpath_list.appendSlice(libc_dirs.libc_rpath_list); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these should be added here. This information is available to whatever logic needs it via link.File.options.libc_installation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, all are needed by the linker, and framework paths are needed by the frontend (compiler) too. How else would you provide this info then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the linker and the frontend have access to link.File.options.libc_installation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, did I finally understand it that you mean we can recreate this info on request in whatever linker needs it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I believe that is correct 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took me long enough to get it...
src/Compilation.zig
Outdated
| } | ||
|
|
||
| if (want_native_paths) { | ||
| const paths = std.zig.system.NativePaths.detect(arena, target) catch |err| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should not be called from detectLibCFromLibCInstallation. This function is intended to only extract libc information from the LibCInstallation and not inspect the host at all.
|
I'm not sure how to proceed from here for one reason: our libc detection mechanism so far assumed that libc is only a set of include dirs which is wrong. Depending on the host, in this case macos or any Apple platform, the linker needs also the knowledge of libc search dir paths, rpaths and framework dirs. All of those together with a set of include dirs make up an actually libc installation on a given host. With that in mind, I'm not sure how to go about addressing some of your feedback as it seems to be still based on the assumption that libc installation is only a set of include dirs. Apologies if it is not but it's difficult for me to work out exactly an action plan based on your latest feedback as it's a little too vague. Could you therefore clarify your feedback a bit more? |
|
Can you make sure that this solves #11066? Regarding your question above - As you can see, only 2 out of 6 fields are include directories. Actually most of the fields here are not related to headers. |
Unless we detect Nix, in which case, we use Nix provided paths via env vars.
05eb30e to
6d0f831
Compare
|
@andrewrk I haven't put the contents of |
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it needs more work before it's ready to land.
| pub inline fn getIncludeDirs(self: *const NativePaths) []const [:0]const u8 { | ||
| return self.include_dirs.items; | ||
| } | ||
|
|
||
| pub inline fn getLibDirs(self: *const NativePaths) []const [:0]const u8 { | ||
| return self.lib_dirs.items; | ||
| } | ||
|
|
||
| pub inline fn getFrameworkDirs(self: *const NativePaths) []const [:0]const u8 { | ||
| return self.framework_dirs.items; | ||
| } | ||
|
|
||
| pub inline fn getRpaths(self: *const NativePaths) []const [:0]const u8 { | ||
| return self.rpaths.items; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why inline?
why do these getters even exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It made sense to me instead of typing paths.lib_dirs.items everywhere but it's a matter of preference so I am happy to remove it.
| break :blk sdk.path; | ||
| } else { | ||
| break :blk null; | ||
| const darwin_native = (comptime builtin.target.isDarwin()) and options.target.isDarwin() and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incorrect logic for darwin_native. When options.is_native_os is false, darwin_native must be false. Otherwise, it's going to look at the system sometimes when it should be cross-compiling. Zig should not rely on the Darwin SDK when cross-compiling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, fair point. The reason I re-introduced comptime check is because it then emits darwin-specific code that requires a host that spawn subprocesses which isn't always the case plus it should even exist unless it's a native OS AND Darwin. Can I make it more verbose and add is_native_os here but leave the comptime check? Or perhaps you have a nicer suggestion for this?
| for (paths.warnings.items) |warning| { | ||
| log.warn("{s}", .{warning}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you give an example of what this looks like when it occurs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot, I copied the code that was already there. You may either ask the original author, or we can remove it.
| // TODO figure out if we can make it part of LibCInstallation | ||
| native_paths: ?NativePaths = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be a TODO. I think it should be done as part of this patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but I will require assistance here as I don't yet know how to do that.
|
I solved these problems by expanding our existing frontend abstractions that are already designed to handle this situation (and already do handle it on the other operating systems besides macOS). Namely, |
Summary of breaking changes:
Now, the nitty-gritty:
In order to achieve 1. we have to apply this rule to all possible
Compilation.createinvocations which made it natural to move some of the existing code that is concerned with native paths detection intoCompilation.create. And so, now detection of native Apple SDK is done withinCompilation.create, as well as detection/unpacking of paths supplied by Nix. I think this bit of functionality really belongs inLibcInstallationstruct, as it is a natural companion to autodetection logic of libc include paths thatLibcInstallationprovides. I haven't acted on this yet in this PR, so feel free to comment on the correctness of my assertion.Detection of native libc include paths for Apple platforms is now done via
LibcInstallationstruct as it is done for other platforms - this got rid of a lot of special casing for Apple inCompilation.zigwhich is nice. The detection logic inLibcInstallationfor Apple platforms relies on a two-tier logic: if SDK was detected, we use that, otherwise, we fallback toclangfor detection. The latter is to mainly support the Nix environment. Anyhow, with this PR,zig libcnow works on macOS (no more panicking). Instead we get this if the SDK is available:Closes #15024
Closes #14569
EDIT:
Closes #11631
@haze marking #11631 as closed but I will ask you to verify it did indeed completely fix the issue for you once 0.11 lands, and is available via Nix.
EDIT2:
Closes #16118
Closes #15963