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 cc: --as-needed is an unsupported linker flag #10164

Closed
matpow2 opened this issue Nov 17, 2021 · 7 comments
Closed

zig cc: --as-needed is an unsupported linker flag #10164

matpow2 opened this issue Nov 17, 2021 · 7 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. zig cc Zig as a drop-in C compiler feature
Milestone

Comments

@matpow2
Copy link

matpow2 commented Nov 17, 2021

Zig Version

0.9.0-dev.1625+d3a099c14

Steps to Reproduce

This can be easily reproduced using a command like

> zig cc (...) -Wl,--as-needed -libus-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 (...)
(...)
warning: unsupported linker arg: --as-needed

If you use objdump -p on the resulting executable, you will also see DT_NEEDED entries for e.g. ibus-1.0.

Expected Behavior

zig cc should accept --as-needed as a linker flag such that unnecessary DT_NEEDED entries are removed.
--as-needed is supported by both lld and GNU ld, but zig cc needs to be changed to allow for this particular flag.

Actual Behavior

zig cc gave a message warning: unsupported linker arg: --as-needed.

This is especially problematic when compiling libraries like SDL2 which rely on the --as-needed behavior to remove such DT_NEEDED entries.
Otherwise, the executable will depend on dynamic libraries which might not exist on the host system.

It seems like #10050 is a different issue related to -lgcc_s/-lunwind, so creating a new issue here.

As a sidenote, we are currently evaluating using zig cc as a cross compiler from Windows -> Linux/Mac for our games (Baba Is You, Mighty Goose, etc).
This has worked perfectly so far for Linux, except for this particular issue :)

@matpow2 matpow2 added the bug Observed behavior contradicts documented or intended behavior label Nov 17, 2021
@andrewrk andrewrk added zig cc Zig as a drop-in C compiler feature enhancement Solving this issue will likely involve adding new logic or components to the codebase. and removed bug Observed behavior contradicts documented or intended behavior labels Nov 20, 2021
@andrewrk andrewrk added this to the 0.9.0 milestone Nov 20, 2021
@andrewrk
Copy link
Member

Thanks for the report! Looking into this.

@andrewrk
Copy link
Member

andrewrk commented Nov 21, 2021

I solved this by changing the default to strip dependencies on dynamic libraries that are unused by default. So you won't even need the -Wl,--as-needed flag. However, I also added support for that flag (as well as -Wl,--no-as-needed):

$ cat test.c
int main(int argc, char **argv) {
    return 0;
}

$ zig cc -o test test.c  -lSDL2

$ objdump -p test | grep NEEDED
  NEEDED               libc.so.6

$ zig cc -o test test.c -Wl,--no-as-needed -lSDL2

$ objdump -p test | grep NEEDED
  NEEDED               libSDL2-2.0.so.0
  NEEDED               libc.so.6

Looks like that should unblock you for Linux.

As for macOS, I extracted #10192. But let's chat about this use case- I happen to have a local branch of https://github.com/andrewrk/zig-sdl that works for x86_64-macos (tested on Catalina). There are a couple of issues with it that I am working with @kubkon to fix. But it sounds like maybe this is what you would want, yeah? The idea is that you would copy this code into your repository, and then you end up with a macOS binary that has a static dependency on SDL and therefore can't run into any problems with trying to dynamic link it.

@matpow2
Copy link
Author

matpow2 commented Nov 21, 2021

Thanks for looking into this!
I think this means we will ship Baba Is You on Linux using zig cc :)

Ultimately, we ended up using another toolchain for Windows -> Mac, but we will definitely check back on Zig + Mac in the future.


Just to elaborate on our usecase, for both Linux/Mac we:

  • git checkout a fairly bleeding-edge SDL2 revision, apply some patches and build it using its own CMake script.
  • Compile our game sources + deps and link statically to SDL2 using CMake.

Using a Zig CMake toolchain and X11/GL/etc borrowed from Steam Runtime sysroots, it seems like this works pretty well for Windows -> Linux compilation with zig cc.

For Windows -> Mac, we ran into some link errors with the Zig MachO linker and SDL2, and we also had to do some workarounds to get Objective-C compilation working, but we will see about creating tickets for these once we can find some time.

@kubkon
Copy link
Member

kubkon commented Nov 21, 2021

Thanks for looking into this! I think this means we will ship Baba Is You on Linux using zig cc :)

Ultimately, we ended up using another toolchain for Windows -> Mac, but we will definitely check back on Zig + Mac in the future.

Just to elaborate on our usecase, for both Linux/Mac we:

  • git checkout a fairly bleeding-edge SDL2 revision, apply some patches and build it using its own CMake script.
  • Compile our game sources + deps and link statically to SDL2 using CMake.

Using a Zig CMake toolchain and X11/GL/etc borrowed from Steam Runtime sysroots, it seems like this works pretty well for Windows -> Linux compilation with zig cc.

For Windows -> Mac, we ran into some link errors with the Zig MachO linker and SDL2, and we also had to do some workarounds to get Objective-C compilation working, but we will see about creating tickets for these once we can find some time.

Would you be able to provide a small repro of Win->Mac? I wrote zld (which is our in-house MachO linker) and with a repro I can come up with a solution fairly quickly. Also, did you use released zig version (0.8.1) or upstream/master?

@matpow2
Copy link
Author

matpow2 commented Nov 21, 2021

@kubkon

We used zig master built from source.
For the MachO linker error, I really wish we had more time to do a minimal repro or more troubleshooting, but we're basically out of time for this cross-compilation project :(

I don't have the stack trace for the error any longer (sorry), but the error occurred here:

try self.dylibs_map.putNoClobber(self.base.allocator, dylib.id.?.name, dylib_id);

leading to an assert assert(!self.containsContext(key, ctx)); failing.

@kubkon
Copy link
Member

kubkon commented Nov 21, 2021

@matpow2 You'd be surprised but this is a huge hint. However, I'd still need a repro case - the error will be related to a bug in processing dylibs either directly from the linker invocation line (if you could paste it, even abridged, that would be of help) or in handling of the dylib dependents (recursive descent of the re-exported dylibs).

@matpow2
Copy link
Author

matpow2 commented Nov 21, 2021

@kubkon

I think this was approximately the link command:

zig c++ -target x86_64-apple-darwin -std=c++11 -IC:/MacOSX11.0.sdk/lib/c++/v1  -std=c++11 -stdlib=libc++ -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -isysroot C:/MacOSX11.0.sdk -mmacosx-version-min=10.7 -Wl,-headerpad_max_install_names (... object files ...)  SDLbuild/libSDL2.a  SDLbuild/libSDL2main.a  -framework  OpenGL  -framework  OpenGL  -framework  Carbon  -lc++  -lm  -liconv  -framework  CoreVideo  -framework  Cocoa  -framework  IOKit  -framework  ForceFeedback  -framework  CoreAudio  -framework  AudioToolbox  -framework  AVFoundation  -framework  Foundation  -Wl,-undefined,error  -Wl,-compatibility_version,1.0.0  -Wl,-current_version,15.1.0  -Wl,-weak_framework,Metal  -Wl,-weak_framework,QuartzCore  -framework  Carbon

Hope it helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. zig cc Zig as a drop-in C compiler feature
Projects
None yet
Development

No branches or pull requests

3 participants