Skip to content

Zig passes incorrect sysroot to Clang when combined with Nix #14569

@winterqt

Description

@winterqt

Zig Version

0.10.1

Steps to Reproduce and Observed Behavior

This is once again a bug that I've only been able to observe when compiling 0.10.1, but I believe it is still present in master, and should be fixed.

std.zig.system.NativePaths.detect has special support for Nix, by searching NIX_CFLAGS_COMPILE. When this is done, it results in absolute include directories being returned.

There are two codepaths that stage3's stage1 compilation for Darwin under Nix can take -- the sandboxed case and the non-sandboxed case:

zig/src/main.zig

Lines 2510 to 2527 in a5b34a6

const has_sysroot = if (comptime builtin.target.isDarwin()) outer: {
if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) {
const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse
break :outer false;
native_darwin_sdk = sdk;
try clang_argv.ensureUnusedCapacity(2);
clang_argv.appendAssumeCapacity("-isysroot");
clang_argv.appendAssumeCapacity(sdk.path);
break :outer true;
} else break :outer false;
} else false;
try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2);
const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem";
for (paths.include_dirs.items) |include_dir| {
clang_argv.appendAssumeCapacity(isystem_flag);
clang_argv.appendAssumeCapacity(include_dir);
}

The sandboxed case is when the macOS SDK cannot be found, resulting in -isystem being passed to specify include directories. The issue is when the sandbox is disabled, and Xcode is installed. This results in -isysroot specifying a path to the macOS SDK, and absolute include directories being specified with -iwithsysroot.

For example, this results in -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -iwithsysroot /nix/store/j88zc0bv69jpiyh3k2g6s67x3i3wgs24-llvm-15.0.7-dev/include being passed to Clang, which results in the incorrect search path /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk//nix/store/j88zc0bv69jpiyh3k2g6s67x3i3wgs24-llvm-15.0.7-dev/include being used.

This manifests itself as failures to find headers such as stdlib.h when compiling stage1 from stage3, as @kubkon observed in #14559 (comment).

There's at least a few ways to fix this, but I'm unsure which is the most optimal. For example, we can return the is_nix value from NativePaths.detect and special-case has_sysroot to always be false if is_nix is true (which I've confirmed does fix the issue).

Expected Behavior

For it to pass the correct flags.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavioros-macosmacOS

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions