-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
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
cudaPackages: append $ORIGIN to Runpaths #226038
Conversation
Ah I had not previously considered rebuilds caused by autopatchelf that are not CUDA-related |
LGTM any objections to merging? |
Hmm, does anyone in particular own the autopatchelf script? |
@@ -38,6 +38,12 @@ backendStdenv.mkDerivation { | |||
stdenv.cc.cc.lib | |||
]; | |||
|
|||
# Picked up by autoPatchelf | |||
# Needed e.g. for libnvrtc to locate (dlopen) libnvrtc-builtins | |||
appendRunpaths = [ |
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.
Btw, I wanted to name this autoPatchelfAppendRunpaths
so that it would be clear which hook this variable is picked up by, but it was a little too mouthful
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 would rather have the long, complex name. There is no point trying to provide short names, that give little indication of how they work. Also, this variable should not be used too often. The only reason the other variables are so short is mostly historical. runtimeDependencies was already a mistake. Let's not clutter the namespace with more generic variables. More recent additions are of the form autoPatchelfIgnoreMissingDeps
.
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.
Hi @SomeoneSerge, I do happen to own the autoPatchelf script. Mostly because I re-wrote that in python. I do however have some questions:
- Do you really need $ORIGIN added to the libraries ? If you only need the binaries, you could already use
--runtime-dependencies
to add fixed rpath values. Although it is a bit cumbersome because it adds /lib. - Do you really need an indirect, relative path like $ORIGIN ? I mean, you already know what $ORIGIN is at this stage, right ? So you could use the final, resolved value.
- Do you need $ORIGIN added everywhere ? If it is only a few libraries that need to dlopen, you could fix these manually, with patchelf.
- Why do you append these paths instead of prepending ? Won't we soon need another flag to prepend paths ?
What I worry about here is feature creep. autoPatchelfHook is intended to discover and fix as many things as possible, but this extension makes it a bit too magical, less disciplined. It will be really tempting to just add whatever path is missing/undetected in that argument, and call it a day. And that is rather a job for a while loop applying patchelf. I do not want autoPatchelfHook to become the go-to tool to replace all custom patchelf invocations with mkDerivation attributes.
Now, I agree this extension has its uses, because dlopen() is a pain sometimes. I would have loved to have that when packaging matlab. But in the end there was only one matlab lib that needed x11 libs, and once identified adding x11 to the RPATH of all the binaries seemed wasteful.
Doing a cursory glance over nixpkgs, it seems like the feature is not commonly needed. I found only one use case of autoPatchelfHook and $ORIGIN together, in cudann:
nixpkgs/pkgs/development/libraries/science/math/cudnn/generic.nix
Lines 94 to 97 in bca7aaf
# Without --add-needed autoPatchelf forgets $ORIGIN on cuda>=8.0.5. | |
postFixup = strings.optionalString (strings.versionAtLeast versionTriple "8.0.5") '' | |
patchelf $out/lib/libcudnn.so --add-needed libcudnn_cnn_infer.so | |
''; |
I find their solution very elegant. It makes the implicit dlopen dependency explicit, so that autoPatchelf can do it's magic correctly. So I guess this question supersedes all the above: Would that solution work for you, or do you really need a big nuke adding to all the rpaths ?
Hello @layus, and thank you! I start at the end and work back to the beginning
Yes, and this is also what I started with when we have encountered With this assumption, we should either put
Yes, this was my exact concern and the reason I wanted to wait for someone contributing to
Tbh, I feel like providing both
This is a good question. I can provide only a few tangential arguments in favour of keeping the append way:
Current intent is to patchelf all shared libraries
As admitted above, I don't really need it. I tried to find if there is a preferred way in nixpkgs and it seemed like there really isn't. To speculate a little more on this, it seems to me that
I specifically want to address the libraries. This PR modifies the executables as well, but it's more of a side effect that I don't mind. We probably should do this to the executables as well, but they're a more complicated story we didn't really touch upon This turned to be a pretty long reply, but I think it fills in most of the missing context. As you see there are indeed alternatives available. What do you think? |
To clarify, I think this PR is approximately the smallest code change that satisfies #225240: e.g. no |
Thanks you for replying in detail. I see the same problems surfacing over and over. I guess I am being pedantic here about forcing users in the "right" way to use the tool. Maybe they will prefer fast rather than precise, and that is valid too. I can only guess the amount of time you already spent on this. About $ORIGIN, I think it makes a lot of sense. It is already used in several places in nixpkgs, too. So, I am frustrated that there seems to be no perfect, clean way to do automatic patching, but that does not make this PR invalid. Let's merge :-). |
I actually came up with a argument for expanding ORIGIN over the night: if we do make a copy of |
Oh, and also I didn't update |
And more on the feature creep, another feature I still crave for is being able to pass an attrset with the extra needed/extra runpaths to a derivation. Sort of mkDerivation {
elfEnsureNeeded = {
"$out/lib/libnvrtc.so" = "libnvrtc-builtins.so";
};
elfEnsureRunpath = {
"**/*.so" = addOpenGLRunpath.driverLink;
"$out/lib/*.so" = "${placeholder "out"}/lib";
};
...
} |
This is valid, but why would you copy that somewhere else ? And again, this PR only improves the packaging, it does not make it perfect. And that is fine. Thank you for fixing the dependencies, that is already a big improvement.
Oops :-). Ping me on the updated PR. And if you do not find time to do it, it is also fine. It's not like this is worse than |
Not sure why you would want that ? As assertions to ensure that autopatchelf did work as intended ? Or as an advanced api to autoPatchelf for extra dlopen dependencies ? Do not get me wrong, more features can be a good thing, I just like to have a clear use-case with them. |
As a declarative way to prepare instructions (and assertions) for autopatchelf (or a similar tool) to perform (and verify). This way I'd be able to inspect these instructions with a simple |
While assertions kind of make sense, instructions seems like they would require a different tool. If your instructions are complete, there is no need for auto patchelf. It's just advanced patchelf instructions. If you want partial requirements and assertions, well, that indeed looks like a whole new feature for autoPatchelf 🤩 |
Description of changes
Re-opening #225955 to target staging because modifying autopatchelf triggers rebuilds for some measly 21k packages...
@NixOS/cuda-maintainers
Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)