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

mac: relink 'libfoo.dylib' as '@rpath/libfoo.dylib' #1477

Merged
merged 3 commits into from
Mar 12, 2025

Conversation

minrk
Copy link
Contributor

@minrk minrk commented Mar 10, 2025

similar to conda-build, but not the same. conda-build searches a lot more, and sets the link to find any matching file anywhere in the package, whereas this only handles the case where it's in $PREFIX/lib.

This also fixes an erroneous check for absolute path install_name for dylibs in $prefix/lib. The check was strip_prefix(prefix) whereas it should have been strip_prefix(encoded_prefix.join("lib")) if it were to match the path of absolute install_names.

I'm not sure how to add a test for this in this repo, but this sample recipe is fixed by it.

closes #1476

(feel free to ignore my code and rewrite with your own fix, I don't know how to rust).

similar to conda-build

and fix $PREFIX/lib/libfoo.dylib as `@rpath/libfoo.dylib`, which was checking the wrong prefix
@minrk
Copy link
Contributor Author

minrk commented Mar 10, 2025

While this correctly rewrites the paths now, I think I may have found a different bug, because this produces libraries that crash on loading if the builtin relink is used. If I skip the builtin and go straight to relinking with install_name_tool, everything works correctly.

@minrk
Copy link
Contributor Author

minrk commented Mar 11, 2025

The crashes appear to be related to updating the codesignature (e.g. not doing it):

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
Exception Codes:       UNKNOWN_0x32 at 0x0000000100bd8000
Exception Codes:       0x0000000000000032, 0x0000000100bd8000

Termination Reason:    Namespace CODESIGNING, Code 2 Invalid Page

The install_name_tool code path works fine, but the rust reimplementation doesn't appear to produce valid dylibs.

@wolfv
Copy link
Member

wolfv commented Mar 11, 2025

Yes, after any relink we need to run codesign again. The install_name_tool on conda-forge has some facilities that automatically run codesign, but this is not true for macOS own install_name_tool IIRC.

@minrk
Copy link
Contributor Author

minrk commented Mar 11, 2025

ah, the crash is apparently because I have codesign from sigtool on my path and it's just failing every time because it doesn't recognize the --preserve-metadata=entitlements,requirements arg, but the error isn't reported.

I guess this code doesn't catch exit codes or report errors. This is unrelated, I'll open a separate issue to avoid getting too far off track.

I'm not sure if rattler-build is expected to work with conda-forge-distributed codesign? If so, I guess it needs to lose the --preserve-metadata or check for its support.

@minrk
Copy link
Contributor Author

minrk commented Mar 11, 2025

ok, after fixing my codesigning issue (#1478), this PR does appear to be working as intended, with both relink implementations. But there are still no tests to exercise exchange_dylib or dependency rewriting. What should that look like? I've made a test recipe to work with, but I'm not sure how/what to integrate as tests here.

@wolfv
Copy link
Member

wolfv commented Mar 11, 2025

We have some test binaries, and we can re-read the modified binary to check that the value meets the expectations.

Maybe you can take the test binary in test-data/binary-files/zlink-macos, modify it (e.g. using install_name_tool), and turn it into a test?

I'll make sure that codesigning works (and fails) as expected in #1479

@wolfv
Copy link
Member

wolfv commented Mar 12, 2025

Hey @minrk - i pushed some changes to use the actual rpath which is most often lib/ - but can be set to something else by the user.

Can you test your recipe against this change?

@minrk
Copy link
Contributor Author

minrk commented Mar 12, 2025

Yes, this produces the expected result. Thanks!

@wolfv
Copy link
Member

wolfv commented Mar 12, 2025

@minrk would you be able to add your test recipe to test-data/recipes and we just run it in test_simple.py?

@wolfv
Copy link
Member

wolfv commented Mar 12, 2025

When I run your recipe I think the test is exiting with 1 because the diff is not clean.

@minrk
Copy link
Contributor Author

minrk commented Mar 12, 2025

hm, it passes for me because difft doesn't set the exit code by default. I'll look into adding it. The diff isn't part of the test, it's just for viewing purposes, so not really needed when bringing it into this repo

@wolfv
Copy link
Member

wolfv commented Mar 12, 2025

I think it wasn't passing for me because I didn't pull in the codesign changes. Now it passes. Sorry.

verifies that both absolute `$PREFIX/lib/lib...` and relative `lib...` links
are rewritten to `@rpath/lib...`
@minrk
Copy link
Contributor Author

minrk commented Mar 12, 2025

Added a slightly simplified version that checks for the expected rewrites with a simple otool -L | grep

@wolfv
Copy link
Member

wolfv commented Mar 12, 2025

Thank you so much!

@wolfv wolfv merged commit ea13d29 into prefix-dev:main Mar 12, 2025
16 checks passed
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.

BUG: mac relinking doesn't rewrite default install_name in dependencies like conda-build
2 participants