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

Support for @loader_path. #94

Merged
merged 50 commits into from Jul 15, 2021
Merged

Conversation

HexDecimal
Copy link
Collaborator

@HexDecimal HexDecimal commented Jan 11, 2021

Added more stuff on top of my previous PR's. This adds a DependencyTree class which uses itself to resolve dependencies recursively and is a little easier to read its attributes than parse the tree_libs return value. I tried to use it to update tree_libs itself but it turns out everything relies on its original behavior.

Tests fail unless I remove recursion and remove libraries with @loader_path in their install name. That's the current state of things. It might work better if I kept a backwards compatible tree_libs and started switching tools to use DependencyTree instead.

Closes #91, my previous PR.
Closes #37, closes #62, closes #90, open issues involving missing @loader_path support.
#7 might be solved with additional commits to delocate_listdeps.py.

Still a lot to work on obviously. I just made this PR to report the current status and so that it doesn't clobber #91 which I might need to return to if this PR doesn't turn out well. I've only really gotten familiar with libsana.py at the moment.

I'll also need to add tests for DependencyTree itself. I doubt its __repr__ works.

@HexDecimal
Copy link
Collaborator Author

After several iterations of refactoring I ended up with the functions: get_dependencies, walk_library, and walk_directory in the libsana.py module rather than a new class. These can be used collect all dependencies of a library or directory of libraries while also handing possible issues like cyclic dependencies.

delocate_path was modified to use the new system. It should support @loader_path and now rejects situations with missing dependencies. copy_recurse is no longer used since dependencies are discovered all at once.

tree_libs seems to still be in use by delocate_listdeps, but I think this PR is already doing too much so I probably won't touch it right now. Code which is still using tree_libs will show up in pytest as warnings.

Travis tests have been difficult to work with. The way asserts are currently handled break pytests error reporting and should be updated to use assert statements directly. The set -vx line in the Travis script adds a lot of uncollapsible output making the logs hard to navigate.

I'm still missing @loader_path tests. Mostly it's hard for me to create the libraries for them. A good test might be to have a library with an install path of @rpath/libtarget.dylib loaded from an adjacent library with an rpath of @loader_path/, this seems like a common setup.

@HexDecimal
Copy link
Collaborator Author

delocate_tree_libs can now copy and modify libraries at the same time. It can now work with a complete lib_dict where the dependencies referenced in it will be moved during the process.

Some functions from pytest_tools were replaced by asserts so that I could debug them. I also moved set -vx in the Travis script so that I could read the tests easier. I ran into a major issue with one of the tests where it seems like the test did not match the documentation (0d54dd8), I did my best to salvage that test and put it into a new test called test_delocate_path_install_names.

So far my plans to make a dependency tree traversal more strict haven't turned out well due to what I think are optional dependencies. Right now I just log these cases as errors and ignore them. Issues like this were ignored without output before now.

I now have a working version with recursive @loader_path support. I've used my own library depending on SDL to test it with.

This is my current output. The errors are from missing files on the runner. It might be too verbose to list these system files which aren't going to be copied anyway, but it's weird to me how these files are detected as missing but then the library can still load in an isolated environment afterwards. Only hidapi was needed for me, and that library was bundled within SDL.

delocate-wheel -v dist/*.whl
ERROR:delocate.libsana:/usr/lib/libiconv.2.dylib not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/GameController.framework/Versions/A/GameController not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreHaptics.framework/Versions/A/CoreHaptics not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/Metal.framework/Versions/A/Metal not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/Frameworks/hidapi.framework/Versions/A/hidapi
ERROR:delocate.libsana:/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/Frameworks/hidapi.framework/Versions/A/hidapi
ERROR:delocate.libsana:/usr/lib/libSystem.B.dylib not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/Frameworks/hidapi.framework/Versions/A/hidapi
ERROR:delocate.libsana:/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/ForceFeedback.framework/Versions/A/ForceFeedback not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/usr/lib/libSystem.B.dylib not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/usr/lib/libobjc.A.dylib not found, requested by /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2
ERROR:delocate.libsana:/usr/lib/libSystem.B.dylib not found, requested by /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmpzjsze8hl/wheel/tcod/_libtcod.abi3.so
INFO:delocate.delocating:Copying library /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2 to .dylibs/SDL2
INFO:delocate.delocating:Copying library /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/Frameworks/hidapi.framework/Versions/A/hidapi to .dylibs/hidapi
INFO:delocate.delocating:Modifying install name in _libtcod.abi3.so from @rpath/SDL2.framework/Versions/A/SDL2 to @loader_path/.dylibs/SDL2
INFO:delocate.delocating:Modifying install name in .dylibs/SDL2 from @rpath/hidapi.framework/Versions/A/hidapi to @loader_path/hidapi
Fixing: dist/tcod-11.19.3.dev6-cp35-abi3-macosx_10_9_x86_64.whl
Copied to package .dylibs directory:
  /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/Frameworks/hidapi.framework/Versions/A/hidapi
  /Users/runner/work/python-tcod/python-tcod/dependencies/SDL2-2.0.14/SDL2.framework/Versions/A/SDL2

This might be finished, but I'm not certain. I'll at least be using this branch for my own wheels for the moment.

@HexDecimal HexDecimal marked this pull request as ready for review January 20, 2021 03:54
@matthew-brett
Copy link
Owner

So sorry to be slow to reply to this and your other PR. I'm a university lecturer, and things are really busy at the moment.

This is a) very welcome, thank you so much and b) a lot to review.

And you've got your other very welcome and large PR over at #93 .

I wonder, would you have any interest in taking over the job of maintainer? I'm happy to continue to help, of course, but the code-base is soon going to be more fresh and up to date in your memory than mine.

@HexDecimal
Copy link
Collaborator Author

So sorry to be slow to reply to this and your other PR. I'm a university lecturer, and things are really busy at the moment.

I made this PR since my own project suddenly had a requirement for @loader_path. I've been installing this branch directly and haven't been affected by it not being merged.

And you've got your other very welcome and large PR over at #93 .

This PR doesn't change as many files as #93, so merging that one first would make this one easier to review.

I wonder, would you have any interest in taking over the job of maintainer? I'm happy to continue to help, of course, but the code-base is soon going to be more fresh and up to date in your memory than mine.

I don't have a Mac to test things on. It's hard for me to check the tools or build test libraries and I rely on open-source CI for doing anything. I think I could update the library tests using Actions but I don't think GitHub has an old enough MacOS runner to compile the older x86 binaries.

I planned on doing simple maintenance tasks through PRs and maybe adding simple features now that I'm knowledgeable with the library. I lack the experience to solve MacOS specific issues and this PR took more effort because I couldn't perform tasks directly on a Mac.

I'd be willing to try and help as a co-maintainer but I'd be overwhelmed on my own.

@matthew-brett
Copy link
Owner

Right - that's totally fair - I have access to quite a few Macs, and use them all the time, so it's much more reasonable for me to responsible for the library. I'll do my best to get to these PRs quickly. Thanks again.

@matthew-brett
Copy link
Owner

Sorry - coming back to this now, in an attempt to clear the backlog.

Is there anything else you'd like to do on this PR? Or should I review as-is?

@isuruf - did you try this branch as an alternative to gh-100?

@HexDecimal
Copy link
Collaborator Author

It's been a very long time since I last checked this PR. I couldn't merge this since I added too many type hints, but I needed those type hints in order to design this PR in the first place. This PR was doomed since #93 couldn't be merged.

I can try rebasing this and removing any unnecessary changes if you want.

@matthew-brett
Copy link
Owner

I've got time now to review this properly. Would you prefer to put this one together with the type hints? We can also drop Python 2, if that would help.

@HexDecimal
Copy link
Collaborator Author

Dropping Python 2 would only help all future work. It won't really affect what that's already been done.

I think I can go with whatever plan you want. I feel like I can split my previous PR's up if necessary, or I can just resolve merge conflicts in this one.

@matthew-brett
Copy link
Owner

matthew-brett commented Jul 2, 2021 via email

@HexDecimal
Copy link
Collaborator Author

Just checking - this PR includes the changes in #93?

Yes.

@matthew-brett
Copy link
Owner

OK - then please do just rebase, and I'll work through it, probably tomorrow.

@HexDecimal HexDecimal marked this pull request as ready for review July 2, 2021 13:55
Adds type hinting to the delocating and libsana modules.
@isuruf
Copy link
Collaborator

isuruf commented Jul 2, 2021

@isuruf - did you try this branch as an alternative to gh-100?

I haven't, but I'll try this branch soon.

@HexDecimal
Copy link
Collaborator Author

I've already rebased this branch so I'm not sure if it still works until tests pass. The TravisCI jobs are taking a while.

Test output has been cleaned up.  Debug flags no longer escape the wheel
tests.
Additional information is printed before the traceback, so this check
had to be modified.
@HexDecimal
Copy link
Collaborator Author

I've finished the rebase and the tests now pass again. This is ready for review.

Copy link
Owner

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Some comments, working through.

.travis.yml Outdated Show resolved Hide resolved
delocate/cmd/delocate_wheel.py Outdated Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Outdated Show resolved Hide resolved
delocate/delocating.py Show resolved Hide resolved
Co-authored-by: Matthew Brett <matthew.brett@gmail.com>
The list copy of lib_dict wasn't needed.

Use an alternative type-hint for lib_filt_func.

Co-authored-by: Matthew Brett <matthew.brett@gmail.com>
Copy link
Owner

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Finish up the comments, first pass.

It would be good to have direct tests of the new functions:

  • walk_library.
  • walk_directory.

Are we testing executable_path somewhere?

Thanks - the type-hinting is useful, and the test changes are nice too.

delocate/libsana.py Outdated Show resolved Hide resolved
delocate/libsana.py Outdated Show resolved Hide resolved
delocate/libsana.py Outdated Show resolved Hide resolved
delocate/libsana.py Outdated Show resolved Hide resolved
delocate/libsana.py Outdated Show resolved Hide resolved
delocate/libsana.py Outdated Show resolved Hide resolved
This must be the directory of the library which is loading `lib_path`.
executable_path : str, optional
The path to be used for `@executable_path`.
Assumed to be the working directory by default.
Copy link
Owner

Choose a reason for hiding this comment

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

Is this a reasonable assumption? I didn't investigate much, but my guess would have been that it would be the path containing Python - not so? Maybe this should be an input option, from the command line. Should the default be the working directory? Or some signal that we are not raise an error when we see this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It isn't a good default. It was hard to imagine what circumstances would lead to having to delocate a Python library using @executable_path, but I put something there anyway.

I can use sys.base_exec_prefix to make @executable_path relative to the Python executable. That seems like a reasonable choice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

dirname(sys.executable) is now the default for @executable_path, and this can be changed from the command line.

delocate/libsana.py Show resolved Hide resolved
delocate/tests/test_delocating.py Outdated Show resolved Hide resolved
delocate/tests/test_delocating.py Outdated Show resolved Hide resolved
@matthew-brett
Copy link
Owner

Did you have any thoughts on the right way to close #7 ?

@HexDecimal HexDecimal force-pushed the loader_path branch 6 times, most recently from a0de7bd to 51bc7e7 Compare July 12, 2021 00:18
This name was given a specific type and can not be reassigned to a
plain tuple.
@HexDecimal HexDecimal marked this pull request as ready for review July 12, 2021 09:39
@matthew-brett
Copy link
Owner

A pull request into your branch to fix an error I was getting testing locally: HexDecimal#2

Copy link
Owner

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Have you tested on your own wheel as well?

Otherwise - I think this is good to go. Do you agree?

Changelog Show resolved Hide resolved
@HexDecimal
Copy link
Collaborator Author

Have you tested on your own wheel as well?

I modified the rpath test wheel to add an indirect dependency very similar to what SDL has. I think my wheels should be okay as long as that test passes.

* MRG: Allow for realpath differences in listdeps

I was getting an error locally running the tests, because my code
directory realpath differs from the apparent path.
@matthew-brett
Copy link
Owner

@isuruf - we're planning to merge this branch soon - can you test it for your needs and let us know?

@isuruf
Copy link
Collaborator

isuruf commented Jul 13, 2021

I checked this PR and with isuruf@6717410 added on top of this PR, numpy arm64 wheels work correctly.

@matthew-brett
Copy link
Owner

@HexDecimal - a couple of test failures on Travis - would you mind taking a look?

Early versions of this fixture could not be used as a path directly.
The parameter is now converted into str before use.
@matthew-brett
Copy link
Owner

OK - let's give this a try. Thanks @HexDecimal for all your patient work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants