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

Use otool to read dylib install name #16542

Closed

Conversation

keith
Copy link
Member

@keith keith commented Oct 24, 2022

When linking an executable on darwin, cc_wrapper.sh contains functionality to ensure rpath entries and shared library install names are relative and match the intended paths that will be used in downstream actions. This depends on being able to traverse symlinks from the _solibs path (like
_solib_darwin_x86_64/_U_S_S_Cgenlib_Uimport___U/libgenlib.so) to the actual file (like bazel-out/darwin-opt-exec-31C2CD59/bin/libgenlib.so). This also assumes that the library has its internal install name equal to that latter path - this seems to be generally true right now, but is maybe a bit brittle.

This system breaks down when doing linking on a remote executor, because Bazel does not encode symlinks, and so the file shows up in _solib_darwin_x86_64 as a real file, and the wrapper picks the wrong install name. The resulting executable works when run directly from bazel-bin/bazel-out on a local machine, but will not work via bazel run, or when used in remote actions.

This change uses otool to read the install name of the target library, which is guaranteed to match what was embedded into the executable during link time. This result will be immune to the peculiarities of how symlinks are used and what install_name is encoded into the shared library during its creation.

Co-authored-by: John Laxson [email protected]

When linking an executable on darwin, cc_wrapper.sh contains
functionality to ensure rpath entries and shared library install names
are relative and match the intended paths that will be used in
downstream actions. This depends on being able to traverse symlinks from
the _solibs path (like
_solib_darwin_x86_64/_U_S_S_Cgenlib_Uimport___U/libgenlib.so) to the
actual file (like bazel-out/darwin-opt-exec-31C2CD59/bin/libgenlib.so).
This also assumes that the library has its internal install name equal
to that latter path - this seems to be generally true right now, but is
maybe a bit brittle.

This system breaks down when doing linking on a remote executor, because
Bazel does not encode symlinks, and so the file shows up in
_solib_darwin_x86_64 as a real file, and the wrapper picks the wrong
install name. The resulting executable works when run directly from
bazel-bin/bazel-out on a local machine, but will not work via bazel run,
or when used in remote actions.

This change uses otool to read the install name of the target library,
which is guaranteed to match what was embedded into the executable
during link time. This result will be immune to the peculiarities of how
symlinks are used and what install_name is encoded into the shared
library during its creation.

Co-authored-by: John Laxson <[email protected]>
@ShreeM01 ShreeM01 added team-Rules-ObjC Issues for Objective-C maintainers awaiting-review PR is awaiting review from an assigned reviewer labels Oct 24, 2022
Copy link
Contributor

@Yannic Yannic left a comment

Choose a reason for hiding this comment

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

There's also --incompatible_macos_set_install_name, which (IIRC) makes the whole wrapper not needed anymore.

@keith
Copy link
Member Author

keith commented Nov 1, 2022

I completely forgot about that, do you think we should try to flip it? Been around for a while

@keith
Copy link
Member Author

keith commented Nov 1, 2022

Looks like it might have rotted a bit:

% otool -L bazel-bin/libfoo.so
bazel-bin/libfoo.so:
        @rpath/liblibfoo.so (compatibility version 0.0.0, current version 0.0.0)

note the duplicate lib prefix, my target here is just named foo

@Yannic
Copy link
Contributor

Yannic commented Nov 1, 2022

IIRC, it broke rules_go last time I checked downstream. Let's see if we can flip it

@pcjanzen
Copy link
Contributor

pcjanzen commented Nov 1, 2022

There were some problems in rules_rust specifically due to the fact that the install name of a cc_binary(linkshared=True) is mangled with --incompatible_set_macos_install_name (even though it shouldn't be): #15261

@keith
Copy link
Member Author

keith commented Nov 1, 2022

we should probably merge this in the meantime regardless, because even if we flip it now it will take a while before we can entirely remove this codepath

@keith
Copy link
Member Author

keith commented Nov 1, 2022

looks like some real failures #16620, I'm not going to debug them atm

@keith
Copy link
Member Author

keith commented Nov 1, 2022

I've setup a bounty for flipping that here: bazel-contrib/SIG-rules-authors#68

@keith keith closed this Jan 10, 2023
@keith keith deleted the ks/use-otool-to-read-dylib-install-name branch January 10, 2023 18:39
@keith
Copy link
Member Author

keith commented Jan 10, 2023

not sure why this one works and that one doesn't, but probably flipping that flag is the ideal solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-review PR is awaiting review from an assigned reviewer team-Rules-ObjC Issues for Objective-C maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants