- 
                Notifications
    You must be signed in to change notification settings 
- Fork 80
          Fix support for install_rpath
          #724
        
          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
base: main
Are you sure you want to change the base?
Conversation
cfad83c    to
    4f361a9      
    Compare
  
    | install: true, | ||
| subdir: 'mypkg', | ||
| install_rpath: '$ORIGIN', | ||
| install_rpath: build_machine.system() == 'darwin' ? '@loader_path' : '$ORIGIN', | 
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.
So... This test was working before just because of a bug: we did no strip the RPATH pointing to the build directory added by meson when the package does not contain libraries relocated to .<package-name>.mesonpy.libs. Now we do and the test fails. The fix above is required because AFAICT meson does not substitures @loader_path for $ORIGIN on macOS. However, it is only half the fix.
The test installs one library in site-packages/mypkg/ and one in site-packages/mypkg/sub/. An RPATH to both of these directories would need to be added. However, meson does not provide a mechanism to set install_rpath to a list of strings.
I don't know how to fix this other than extending meson to accept a list for install_rpath or to simply change the test.
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.
@rgommers You added the test. Which use case did you have in mind?
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.
The test installs one library in
site-packages/mypkg/and one insite-packages/mypkg/sub/. An RPATH to both of these directories would need to be added. However, meson does not provide a mechanism to setinstall_rpathto a list of strings.
This was helpful to smoke out the details of Windows vs. Cygwin, namely this sentence in the docs:
The Windows DLL search path includes the path to the object attempting
to load the DLL: it needs to be augmented only when the Python extension
modules and the DLLs they require are installed in separate directories.
Now that it's done though, the test case isn't essential. I suggest that we remove the shared library right next to the extension, and keep the one in sub.
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.
The fix above is required because AFAICT meson does not substitures
@loader_pathfor$ORIGINon macOS.
Hmm, something seems wrong there, $ORIGIN really should be made to work without this hack. At least SciPy releases depend on this already, and it's conceptually right. I don't fully understand this yet, but it seems if there's something to fix, it should be done in Meson in a backwards-compatible way.
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.
When building a wheel, install_rpath is handled by meson-python, thus we can easily replace $ORIGIN with @loader_path. However, I think it is better to keep handling of install_rpath consistent between meson and meson-python. I haven't tested it, but the documentation does not mention it, and reading the code I didn't find anything in meson that does the translation, therefore I didn't implement it for meson-python either.
What do you mean when you say that SciPy depends on this? install_rpath did not do anything when building a wheel before this PR.
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.
The tests are actually wrong and they work just because meson-python fails to clean up the RPATH entries added by meson pointing to the build directory. This PR fixes this and the tests start to fail.
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 am not yet convinced that the tests are wrong. As we already determined in the discussion, there are two separate things that need to be achieved:
- Keep the RPATH entries added by the package builder
- Remove RPATH entries added by Meson and which it would have removed in the install step
The tests are for case (1). You can't argue that tests for (1) are wrong because you're trying to fix case (2).
Empirically, I know install_rpath: '$ORIGIN' was necessary and worked for SciPy, also for redistributable wheels tested on different machines where the original build dir doesn't exist.
I was suggesting to break out these changes to the tests so they can be reviewed/understood separately and merged. The test changes here may well be correct, but it's still unclear to me - and given that this PR is in a broken state currently for conda-forge, it makes it hard for me to test. If this is a separate test-only PR, testing will be easier.
they work just because meson-python fails to clean up the RPATH entries added by meson pointing to the build directory
It just occurred to me after writing this comment that this is verifiable, by building the test package as a wheel, then installing it and manually checking that the imports work (the build dir will no longer exist).
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.
It just occurred to me after writing this comment that this is verifiable, by building the test package as a wheel, then installing it and manually checking that the imports work (the build dir will no longer exist).
The build RPATH entries added by Meson are relative to $ORIGIN and do not contain any absolute reference to the build directory. I think I've stated this multiple times now, and there is a long comment in one of the commits explaining this. Therefore, the imports fail only if the layout in the build directory is different from the layout in the in the install location. This is not the case for the current tests.
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.
The tests are for case (1). You can't argue that tests for (1) are wrong because you're trying to fix case (2).
This PR touches different test packages. Some check for (1) and others check for (1) and (2), but succeed by accident. Some use install_rpath as they should (althooug, prior to this PR it has no effect). Some other rely on the bogus meson-python behavior. The tests that use install_rpath are anyhow relying on the bogus meson-python behavior because they use RPATH entries relative to $ORIGIN, which has no meaning on macOS and prior to this patch there is not provision in meson-python to translate $ORIGIN to @loader_path on macOS.
As I explained, this PR assumes that all RPATH entries already present before applying install_rpath that are relative to $ORIGIN (or @loader_path on macOS) are Meson build RPATH entries and must be removed. This is the reason why RPATH entries added with linker arguments (either via $LDFLAGS or via linker arguemts in meson.build and that are relative to $ORIGIN (or @loader_path on macOS) are removed. This is what needs fixing. I have a patch ready. The correct fix depends on mesonbuild/meson#14819
I know
install_rpath: '$ORIGIN'was necessary and worked for SciPy
I don't know why you feel it is necessary to state this. I am nowhere questioning that adding RPATH entries is ncessary. However, before this PR, there is nothing in meson-python that applies install_rpath: '$ORIGIN' thus I cannot believe it makes a difference, and indeed, I don't find any install_rpath in the whole SciPy source code.
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 don't find any
install_rpathin the whole SciPy source code.
Multiple extensions in https://github.com/scipy/scipy/blob/maintenance/1.15.x/scipy/special/meson.build contain install_rpath. Note 1.15.x, not main. Note that that release series is limited to meson-python<0.20.0 in case that matters.
As I explained, this PR assumes that all RPATH entries already present before applying
install_rpaththat are relative to$ORIGIN(or@loader_pathon macOS) are Meson build RPATH entries and must be removed.
I got what you mean now I think. It would have helped me to spell out exactly how to verify this, because I didn't find exactly how to verify this.
Re "and must be removed", my point was that no, if that breaks SciPy 1.15 then they must not be removed. Backwards compatibility matters. I agree that we should make the implementation more correct, but not at the cost of breaking an already-released SciPy version (or any widely used package that uses meson-python for that matter). If we apply this fix in 0.20.0 we should definitely be in the clear here; in 0.19.0 it looks to me like we can't do this.
3c1b103    to
    9951f6f      
    Compare
  
    | This should fix all identified issue and it is ready for review. The failed tests are due to mesonbuild/meson#14254 | 
| @dnicolodi sorry I'm struggling to find the time to think about this more thoroughly right now. This is fixing a pre-existing bug that's been there for a long time, right? And nothing is urgent (I can work around gh-711 for the time being). If so, wouldn't it be better to defer this PR until after 0.18.0? | 
| I don't see a problem with postponing this. On the other hand, I don't see any reason why we need to release 0.18.0 now. We can merge this for the next release or we can release 0.18.0 once this is merged. It is up to you. | 
9951f6f    to
    8420a34      
    Compare
  
    | Hi, what is the status of this PR? Is  In that discussion, the dependency for fixing  | 
| 
 It is not merged yet. What else would you like to know? 
 This PR is not merged yet, thus, no, it is not handled in the latest release of meson-python. | 
| @rgommers I'm inclined to merge this soon. Do you still want to have a better look at it before? | 
Always strip RPATH pointing to the build directory automatically added by meson at build time to all artifacts linking to a shared library built as part of the project. Before this was done only when the project contained a shared library relocated to .<project-name>.mesonpy.libs. Add the RPATH entry specified in the meson.build definition via the install_rpath argument to all artifacts. This automatically remaps the $ORIGIN anchor to @loader_path on macOS. This requires Meson 1.6.0 or later. Deduplicate RPATH entries. Fixes mesonbuild#711.
Rework the dependencies between the Python extension module and the package libraries so that they can be loaded with a single additional RPATH entry for each. The previous dependencies required two RPATH entries to be added to the extension module to find the two libraries installed in two different paths, however setting two RPATH entries is not possible via install_rpath. Meson version 1.6.0 or later is required for insrall_rpath to be present in meson introspection data. Drop test checking correct handling of RPATH set via linker arguments: modern Meson highly discourages doing this. Reorganizes the test package to a flatter layout that helps visualizing all the parts involved in the test.
| 
 Sorry for the delay. Agreed, we should merge this, doing some final testing now - but I expect to find nothing and hit the green button. Going through my whole backlog now. | 
| 
 Okay, that was a bit too optimistic. Started testing with  Linux,  Linux,  
 So the behavior on  We do have a test case for  | 
| link_args = ['-DEXAMPLE_DLL_IMPORTS'] | ||
| else | ||
| lib_compile_args = [] | ||
| link_args = ['-Wl,-rpath,custom-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.
This test case needs to stay, it's important that this works.
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 see a comment in the commit message:
Drop test checking correct handling of RPATH set via linker arguments: modern Meson highly discourages doing this.
Do you have a reference for this? I think that if this is really the case right now, that is misinformed - this is pretty essential for some distros.
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 see the failures in gh-768, looking into them now.
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.
Okay, the warning message is slightly misleading. It comes from here:
The point seems to be to not use -Wl,-rpath inside a meson.build file. So the test needs changing to use LDFLAGS to avoid the warning.
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.
If we do that in a separate PR, it will unblock gh-768 it looks like. Want me to do this?
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.
This test case needs to stay, it's important that this works.
This is working. I'll drop this commit from the PR.
| 
 This PR does not (and cannot) distinguish RPATH entries based on how they are added. The old code didn't remove some Meson build RPATH entries and this has been fixed in this PR. In particular, if SciPy uses  | 
| IIRC meson treats install_rpath as additive, not a replacement. The other angle is that it removes build_rpath -- and tracks various internally added rpaths needed for  So maybe the solution here is to treat the introspection files as incomplete and extend it with even more info? | 
| 
 I didn't even get that far, haven't tested on macOS yet. What I pointed out is that this PR seems to break adding an RPATH with  
 Yes, it is additive indeed. 
 If there is no other way to know what the build-rpath(s) is/are, yes maybe. I'm not yet fully convinced that we cannot know - we know in  | 
| 
 That might work, sure. Though FWIW internally meson does have  | 
| 
 | 
| 
 This is true only of the added RATH is anchored to  | 
| 
 That is not the case. I just checked more extension modules, ones that don't use  For the default conda-forge compilers and scipy-dev environment, with  On  
 With this PR: 
 This should be reproducible for any package in a conda-forge environment with the  Did a bit of digging, linking to the implementation in Meson for future reference: What it seems to do is captured by this comment: 
 That sounds right. If we see one or more absolute paths for rpath/runpath entries, we can't otherwise know if they were added by Meson itself yes or no. | 
No description provided.