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

zig ld: link Obj-C, link frameworks, improve linker's implementation #9229

Merged
merged 17 commits into from Jun 25, 2021

Conversation

kubkon
Copy link
Member

@kubkon kubkon commented Jun 24, 2021

General gist of the PR

  • add support for Obj-C - accept .m sources and link them correctly with zig ld
  • (finally) link against frameworks
  • clean up a lot of redundant codepaths in linker's implementation making it easier to contribute to by other (I really do hope!)

In more detail

This now works on macOS without the system linker hack (cc @floooh, @prime31, @mikdusan):

zig cc helloworld.m -framework Foundation -o helloworld

and produces a functional binary with all frameworks and dylibs (here, libobjc.dylib, Foundation.dylib, CoreFoundation.dylib and of course libSystem.dylib) autoresolved - the linker when resolving dylibs from tbd stubs now automatically descends the re-exported tree and looks for dependent libraries meaning it's enough to just link with the top framework, e.g., Foundation. This effectively mimics the behaviour of ld64 making zig ld a true linker replacement for the end-user.

Scanning of dependent libs is currently missing for binary dylibs (as opposed to tbd stubs), and the linker doesn't yet track the visited dylibs meaning it may visit a linked dylib more than once if it is referenced in multiple linked frameworks. Oh, and we don't detect cycles which we probably should for malformed dynamic libraries.

I have also exposed zig cc to Obj-C sources, i.e., it accepts .m files; however, given that @redj started working on a more general exposition in #9029, I'm happy to reverse the change, or whatever is needed. Exposing this option allowed me to test linking Obj-C with Zig in a systematic and simple manner hence why it's included in this PR.

kubkon added 15 commits June 24, 2021 18:53
Move the logic into default-init structs part of constructors in
`SegmentCommand` struct in `commands.zig` module.
After giving it more thought, it doesn't make sense to separate
the two structurally. Instead, there should be two constructors
for a Dylib struct: one from binary file, and the other from a stub
file. This cleans up a lot of code and opens the way for recursive
parsing of re-exports from a dylib which are a hard requirement for
native feel when linking frameworks.
when parsing the umbrella lib
after `LC_LOAD_DYLIB` commands to match ld64 and make the binaries
compatible with Apple tools.
kubkon added a commit to kubkon/pacman.zig that referenced this pull request Jun 24, 2021
which include:
* ast fixes
* `extern enum(i32)` is now `enum(i32)`
* there is no need for `ZIG_SYSTEM_LINKER_HACK` on macOS

The last change depends on ziglang/zig#9229
@kubkon kubkon requested a review from andrewrk June 24, 2021 21:44
Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

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

Really nice work!

@redj
Copy link
Contributor

redj commented Jun 25, 2021

Thanks @kubkon, I don't mind re-basing.

@kubkon kubkon merged commit 350ead9 into master Jun 25, 2021
@kubkon kubkon deleted the zld-objc-frameworks branch June 25, 2021 05:51
@jmrico01 jmrico01 mentioned this pull request Jul 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants