-
Notifications
You must be signed in to change notification settings - Fork 152
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
[Updated] Append to RPATH (instead of overwrite) #245
Conversation
Codecov Report
@@ Coverage Diff @@
## master #245 +/- ##
==========================================
+ Coverage 89.72% 90.21% +0.49%
==========================================
Files 20 20
Lines 1012 1053 +41
Branches 215 223 +8
==========================================
+ Hits 908 950 +42
+ Misses 64 61 -3
- Partials 40 42 +2
Continue to review full report at Codecov.
|
auditwheel/patcher.py
Outdated
@@ -61,6 +61,10 @@ def set_rpath(self, | |||
file_name: str, | |||
rpath: str) -> None: | |||
|
|||
old_rpath = check_output(['patchelf', '--print-rpath', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this logic should not live in this method as other implementations of ElfPatcher
in the future will not work consistently (my understanding is that having to append the RPATH
is not a patchelf
quirk, we should always do it). set_rpath
should just set the provided RPATH
.
We should either have get_rpath
and append_rpath
methods on the interface, or have an append
flag which can trigger this behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good -- if you don't have a particular preference I'll extend the interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How's this?
|
Thanks @fbrennen, the change looks good. I thought about this a bit more and, still have a question about the overall change: what happens if an extension has a relative RPATH to some library, and this library is present on the system where the wheel is installed? I can imagine a situation where the wrong library is picked up from the system, instead of the vendored library. For example, |
I see what you're saying -- the core issue that I (and I think @thomaslima ) have is that the RPATHS for libraries that are already in the wheel are getting trampled -- the place where those RPATHs are adjusted is separate from the one applied to generic libraries grafted into the wheel. I could make the first one use |
Yes, I think that works. However, I would like to better understand the problem before we make this change, just to make sure we are not missing something here, as this is quite a significant change in existing logic. See #134 (comment) as well. Sorry for holding up the PR, I'll try to report back ASAP. |
Not a problem -- I appreciate this could have unexpected consequences. |
Ah, I see that the first RPATH adjustment is done inside an |
I looked into this a bit more and I think we have to address the following issues:
I think given these, the best solution would be to create a function which is used to append the RPATH of Python extensions (but not other |
That sound good to me, and not too hard to do -- I'll adjust |
…int within the wheel structure and are not duplicates
…st that they get installed in different locations
Hi @lkollar -- sorry for the delay. Here's an initial go at implementing what I think you were after. What do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @fbrennen thanks for taking the time and implementing the changes. I think the overall approach looks good. I left a few comments, but I haven't had time to review the tests yet.
auditwheel/patcher.py
Outdated
file_name: str, | ||
rpath: str, | ||
wheel_base_dir: str) -> None: | ||
"""Add a new rpath entry to a file while preserving as many existing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep the ELF patcher implementation as a thin layer abstracting ELF operations, and move anything which is not an implementation detail of a specific ELF patcher to the caller. I think append
should really just append and the caller should implement all the checks on duplicates, etc. Consider that all of this logic would probably be implemented the exact same way in a different implementation of ELFPatcher
, so it's probably a better idea to extract it into a set of common functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good call, ok -- so move this into repair_wheel()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I moved all this into repair_wheel()
along with the tests. There is a slight change to the way patching works -- the patcher
calls now always modify the absolute path to the library. I can't think of a reason why this would be a problem but it is different. If you object it would be very easy to change.
auditwheel/patcher.py
Outdated
2) Not be a duplicate of an already-existing rpath entry. | ||
""" | ||
old_rpaths = self.get_rpath(file_name) | ||
old_rpaths = _preserve_existing_rpaths(old_rpaths, file_name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this implementation is OK, but I think it could be simplified a bit by breaking _preserve_existing_rpaths
up.
Create a single function to check if an RPATH is under wheel_base
(e.g _is_valid_rpath
) and do
rpaths = filter(is_valid_rpath, old_rpaths.split(':'))
Then create the ordered set out of rpaths
, and stick the new RPATH in the end. This way we don't have to do the duplicate check.
I might have missed something, but this is the general idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a problem -- that does sound simpler. =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better?
There seems to be an issue on Travis with s390x builds: https://travis-ci.community/t/s390-xenial-builds-fail-with-an-error-occurred-while-generating-the-build-script/9039. This platform has been problematic on Travis, I would just ignore the failure. |
Thanks @fbrennen! |
No problem =) |
Thanks y'all for this fix. I was working on this issue yesterday and saw this PR was open, and I'm glad it's been merged! @finos/perspective suffers from the same issue as described in #69 and #137 - we have a Because it's detected via Looking over this patch it seems like that issue will be fixed in the next release? Thanks - appreciate the hard work! Update I've been using auditwheel from master and it fixes our issue entirely. Thanks! |
Seems like this is fixed via pypa/auditwheel#245
Seems like this is fixed via pypa/auditwheel#245
Seems like this is fixed via pypa/auditwheel#245
Closes #137 (also closes #69 as far as I can tell)
A refreshed version of work done by @thomaslima in #140