Skip to content
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

Forward framework dirs to embedded clang in addition to linker on macOS #3195

Merged
merged 1 commit into from
Sep 8, 2019
Merged

Forward framework dirs to embedded clang in addition to linker on macOS #3195

merged 1 commit into from
Sep 8, 2019

Conversation

gustavolsson
Copy link
Contributor

@gustavolsson gustavolsson commented Sep 8, 2019

Problem

It seems that the default system/framework paths on macOS is a bit off currently (issue #2319 , #2208). Figuring out the best way to determine these paths is a bit over my head but while trying to work around the issue I do think I've encountered a bug in how zig passes arguments to zig cc:

It seems like if you use exe.addFrameworkDir(path), the path is only forwarded to the linker (-F path), not the embedded clang (-iframework path).

Proposed solution

Forward the argument to embedded clang in addition to the linker.

Feel free to close this if my reasoning is wrong :)

To reproduce

Here is an example project: https://github.com/gustavolsson/zig-sokol-test

I'm trying to build the OpenGL app on macOS (old one 10.13.16) and get zig cc errors about Cocoa.h not being found. I want to work around the issue by explicitly specifying the path to Cocoa.framework on my specific machine, /System/Library/Frameworks, using exe.addFrameworkDir(...):

exe.addFrameworkDir("/System/Library/Frameworks");
exe.linkFramework("Cocoa");
exe.linkFramework("OpenGL");
exe.enableSystemLinkerHack(); // Uses system linker instead of embedded ldd, I think...

const c_args = [2][]const u8{
    "-ObjC",
    "-fobjc-arc",
};
exe.addCSourceFile("src/sokol.c", c_args);
exe.addCSourceFile("src/clear-sapp.c", c_args);

(Note that I also enable the system linker hack because once zig cc succeeds the linking crashes due to MachO problems, which is way over my head and I want to show that the proposed fix manages to build the code)

I get the following error:

In file included from /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/sokol.c:10:
/Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/sokol_app.h:1088:10: fatal error:
      'Cocoa/Cocoa.h' file not found
#include 
         ^~~~~~~~~~~~~~~
1 error generated.

The following command failed:
/usr/local/Cellar/zig/HEAD-9a18db8/bin/zig cc -MD -MV -MF /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/zig-cache/tmp/Ede7tHOXwhUx-sokol.o.d -nostdinc -fno-spell-checking -isystem /usr/local/Cellar/zig/HEAD-9a18db8/lib/zig/include -isystem /usr/include -march=native -g -fno-omit-frame-pointer -D_DEBUG -fstack-protector-strong --param ssp-buffer-size=4
-fPIC -o /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/zig-cache/tmp/Ede7tHOXwhUx-sokol.o -c /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/sokol.c -ObjC -fobjc-arc

The following command exited with error code 1:
/usr/local/Cellar/zig/HEAD-9a18db8/bin/zig build-exe --c-source -ObjC -fobjc-arc /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/sokol.c --c-source -ObjC -fobjc-arc /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/clear-sapp.c --cache-dir /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/zig-cache --name zig-sokol-test
-F /System/Library/Frameworks -framework OpenGL -framework Cocoa --system-linker-hack --cache on

Build failed. The following command failed:
...

Note that the zig cc command does not include -iframework /System/Library/Frameworks even though it exists in the zig build-exe command.

After the proposed change in main.cpp I can successfully build the app. zig build --verbose-cc outputs the following:

/Users/gustav/Documents/Development/zig-ws/zig/build/bin/zig cc -MD -MV -MF /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/zig-cache/tmp/B8D6I_DPJVzG-sokol.o.d -nostdinc -fno-spell-checking -isystem /Users/gustav/Documents/Development/zig-ws/zig/build/lib/zig/include -isystem /usr/include -march=native -g -fno-omit-frame-pointer -D_DEBUG -fstack-protector-strong --param ssp-buffer-size=4
-fPIC -iframework /System/Library/Frameworks -o /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/zig-cache/tmp/B8D6I_DPJVzG-sokol.o -c /Users/gustav/Documents/Development/zig-ws/zig-sokol-test/src/sokol.c -ObjC -fobjc-arc

@andrewrk andrewrk merged commit ec13fa3 into ziglang:master Sep 8, 2019
@andrewrk
Copy link
Member

andrewrk commented Sep 8, 2019

Thanks for the detailed writeup and the patch!

@gustavolsson gustavolsson deleted the clang-frameworks-dir branch September 9, 2019 05:27
@floooh
Copy link
Contributor

floooh commented Sep 9, 2019

I'm having "partial success" with @gustavolsson's fix:

In order to find the system framework headers on macOS Catalina / Xcode11 I need to give the build system the complete path to the macOS frameworks directory (which is the output of xcrun --show-sdk-path + /System/Library/Frameworks).

My build.zig now looks like this (with a hardcoded frameworks path):

https://github.com/floooh/sokol-zig/blob/3928f91e2e8e63cae15aa195d77ec050ef024677/build.zig

The enableSystemLinkerHack() is still needed, but that's an unrelated problem.

Unfortunately my exe now crashes with a segfault, not sure whether this is because of the build or another recent change in the HEAD version. I'll try to investigate in the evening.

@floooh
Copy link
Contributor

floooh commented Sep 9, 2019

Ok, the segfault I'm getting was related to my handling of optional function pointers.

So the two things that are currently still necessary on macOS:

  • pass the absolute macOS SDK Frameworks path to addFrameworkDir()
  • use enableSystemLinkerHack()

...but I can definitely continue now with my sokol experiments, thanks Gustav! :)

@andrewrk
Copy link
Member

andrewrk commented Sep 9, 2019

pass the absolute macOS SDK Frameworks path to addFrameworkDir()

This will be solved with #2041, in which linking against a system library (or framework) will run target-specific logic (potentially even xcrun --show-sdk-path for example) to find and otherwise set up all the paths correctly.

use enableSystemLinkerHack()

Sadly the fix for this is a long way out and it involves writing our own linker. #1535

@floooh
Copy link
Contributor

floooh commented Sep 9, 2019

This will be solved with #2041...

For now I've changed the build script to call xcrun myself and extract the path from the result: https://github.com/floooh/sokol-zig/blob/f2a50e7dd5aeeddd82256d6c757cda3bec08c640/build.zig#L7-L20

FYI: this is what the updated sokol-gfx clear-sample looks like (just opens a window and clears the framebuffer with dynamic colors, via the Metal backend):

https://github.com/floooh/sokol-zig/blob/master/src/main.zig

A nice (recent?) zig addition is the [_], in the new struct initialization with default-values, this allows to omit any "remaining" struct items which should be initialized with default values (I hope that's intended):

https://github.com/floooh/sokol-zig/blob/master/src/main.zig

Compared to the C99 version:

https://github.com/floooh/sokol-samples/blob/master/sapp/clear-sapp.c

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.

3 participants