Skip to content

--sysroot is behaving differently between search paths for includes, libraries, and frameworks.Β #22704

Open

Description

@mcourteaux

Zig Version

0.14.0-dev.3008+7cef585f5

Steps to Reproduce and Observed Behavior

I wrote this helper function:

pub fn linkMacOSSDK(b: *Builder, compile: *std.Build.Step.Compile) void {
    if (b.sysroot == null) {
        @panic(" Pass --sysroot <path/to/macOS/SDK>");
    }
    const path_include = b.pathJoin(&.{ b.sysroot.?, "/usr/include" });
    //const path_include = "/usr/include";

    //const path_lib = b.pathJoin(&.{ b.sysroot.?, "/usr/lib" });
    const path_lib = "/usr/lib";

    const path_framework = b.pathJoin(&.{ b.sysroot.?, "/System/Library/Frameworks" });
    //const path_framework = "/System/Library/Frameworks";

    std.debug.print("Exposing macOS SDK to {s}:\n", .{compile.name});
    std.debug.print("\x1b[2m", .{});
    std.debug.print("  +   include path: {s}\n", .{path_include});
    std.debug.print("  +   library path: {s}\n", .{path_lib});
    std.debug.print("  + framework path: {s}\n", .{path_framework});
    std.debug.print("\x1b[0m", .{});

    compile.addSystemIncludePath(.{ .cwd_relative = path_include });
    compile.addLibraryPath(.{ .cwd_relative = path_lib });
    compile.addFrameworkPath(.{ .cwd_relative = path_framework });
}

And it works (yey! πŸ₯³) But it shows that not everywhere the sysroot is handled the same way. I have to manually prepend the sysroot to the include search path and the frameworks search path, but NOT to the library search path. When I did prepend it, I got an error saying something along the lines of:

cannot open directory: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/

Notice that it basically looked in: sysroot/sysroot/usr/lib.

Expected Behavior

Specifying a sysroot should probably alter the behaviour of all search paths? If not, then they should probably at least behave uniformly across addSystemIncludePath, addLibraryPath, and addFrameworkPath.

Activity

  1. added
    bugObserved behavior contradicts documented or intended behavior
    on Jan 31, 2025
  2. added
    frontendTokenization, parsing, AstGen, Sema, and Liveness.
    zig ccZig as a drop-in C compiler feature
    on Jan 31, 2025
  3. added this to the 0.15.0 milestone on Jan 31, 2025
  4. alexrp commented on Jan 31, 2025

    @alexrp
    Member

    Partial duplicate of #19638, but I'm going to close that one in favor of this as it covers both include and framework paths, and the fix for both is presumably very similar.

  5. alexrp commented on Feb 1, 2025

    @alexrp
    Member

    Having looked at it in GCC and Clang now, I don't actually think implementing --sysroot properly is that hard in and of itself.

    But there is one elephant in the room: Are you expecting Zig to use sysroot-based paths in addition to native system paths, with lookup precedence given to the former? Or are you expecting Zig to exclusively use sysroot-based paths?

    A similar question applies when cross-compiling; should zig cc -target x86_64-linux-gnu --sysroot=<...> result in using paths to Zig's bundled glibc headers in addition to sysroot-based paths?

  6. mcourteaux commented on Feb 1, 2025

    @mcourteaux
    Author

    But there is one elephant in the room: Are you expecting Zig to use sysroot-based paths in addition to native system paths, with lookup precedence given to the former? Or are you expecting Zig to exclusively use sysroot-based paths?

    A similar question applies when cross-compiling; should zig cc -target x86_64-linux-gnu --sysroot=<...> result in using paths to Zig's bundled glibc headers in addition to sysroot-based paths?

    I don't know at all. I'm totally not qualified to answer that question. I can only share my thoughts: it's weird that when zig goes in cross-compilation mode, it forces you to set a sysroot on macos, yet, seems to ignore it for the most part. I have to pass in all the search paths anyway. Additionally, the search paths are not even relative to said sysroot, so honestly, at this point I'm not even sure what sysroot does, and why it's such a hard requirement. What I know for sure, is that it's weird that they behave differently between include,lib,framework.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.zig ccZig as a drop-in C compiler feature

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions