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
nixos/auto-patchelf: Various fixes #40598
Conversation
The old code was complaining about '--' not found, probably the wrong shell was used. This fixes the errors.
The old code was just adding the runtimeDependencies to the rpath of each binary. It did, however, not check those directories for library files, so the search would fail if you didn't specify all dependencies as native build inputs. This commit changes that behaviour by adding the lib directories to the search path and search them for the .so files instead of blindly adding them to the rpath
shift | ||
done | ||
' -- {} + | ||
find "$1" -type f | while IFS='' read -r file; do |
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.
You know about -print0
? That would be better.
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.
Implemented.
find "$1" -type f | while IFS='' read -r file; do | ||
mimeType="$(file -b -N --mime-type "$file")" | ||
if [ "$mimeType" = application/x-executable \ | ||
-o "${mimeType}" = application/x-sharedlib ]; then |
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.
While we're at it, try running https://github.com/koalaman/shellcheck, it's in nixpkgs. I think it will complain about the -o
being non-standard. It should also find other useful things.
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.
Fixed all issues in the file.
@@ -156,6 +151,14 @@ autoPatchelf() { | |||
cachedDependencies+=( | |||
$(find "$prefix" \! -type d \( -name '*.so' -o -name '*.so.*' \)) | |||
) | |||
# Also add all runtime dependencies | |||
if [ -n "$runtimeDependencies" ]; then |
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.
Where is runtimeDependencies
defined anyways?
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 can be defined in your derivation. Some CUDA derivation uses it iirc.
Cc @aszlig |
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.
Except for the fixup of the runtime dependencies I couldn't find a very convincing reason for the other changes made here. Maybe you can further elaborate on them, especially why they're needed in the way you've implemented them.
[ "$mimeType" = application/x-sharedlib ]; then | ||
echo "$file" | ||
fi | ||
done < <(find "$1" -type f -print0) |
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 think this is a big improvement over the old implementation, because IMHO it makes the code less readable. What exactly was the problem with --
? Was it something that shellcheck
reported or did the error occur at runtime?
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 a dependency wasn't found at all, the exact error was:
--: line 5: echo: write error: Broken pipe
Repeated about 20 times
@@ -101,16 +99,11 @@ findDependency() { | |||
} | |||
|
|||
autoPatchelfFile() { | |||
local dep rpath="" toPatch="$1" | |||
local dep interpreter missing rpath="" toPatch="$1" |
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.
Is this also a thing that shellcheck
has reported or did you just prefer to declare all local
s at the top of the function?
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.
Yes, this was shellcheck's SC2155
for dep in $runtimeDependencies; do | ||
while IFS='' read -r -d $'\0' file; do | ||
cachedDependencies+=("$file") | ||
done < <(find "$dep/lib" \! -type d \( -name '*.so' -o -name '*.so.*' \) -print0) |
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.
Recursively adding all the .so
files from a particular runtime dependency is going to also add files like $dep/lib/somename/plugins/foo.so
to the RPATH. So maybe it's generally a better idea to list shared object files explicitly.
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 was the old code and the hook is for automatically detecting the .so dependencies instead of listing them in a patchelf command, so I think this use case is legitimate.
# shellcheck disable=SC2154 | ||
while IFS='' read -r -d $'\0' file; do | ||
cachedDependencies+=("$file") | ||
done < <(find "$prefix" \! -type d \( -name '*.so' -o -name '*.so.*' \) -print0) |
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.
Again here, I think this makes the code less readable.
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 reason for the while loop is -print0
which was suggested above. I need to use this way (done < <(
) instead of find | while
, because the latter one spawns a subshell and so I'm not able to modify variables (see SC2030)
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.
There is also shopt -s lastpipe
btw but that is a fairly recent bash feature (sadly nix-shell
uses impure bash).
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 thought that was fixed recently...?
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.
@bjornfor Oh was it?!
@aszlig The fixup of the runtime dependencies is something I am not sure about anymore. From the nixpkgs manual:
So I am basically breaking this use case - they are not added unconditionally, but only when the .so is needed. I could introduce a new variable, or do you see any way to fix my use case? To elaborate my use case more clearly: My use caseI have a package (Citrix icaclient) that is distributed in binary form only, and that has a lot of .so and executable files. So instead of calling The only other location where |
@dasJ: If I'm understanding correctly then the use case you're describing is the same as the autoPatchelfHook. Initially I wrote the hook for packaging proprietary games mainly because I was tired of getting runtime errors when they add a new library dependency on an upgrade. What I'm not following though is: In which ways does Could you please post the Nix expression of that package (if the binaries are public) to show the nature of the problem? |
Motivation for this change
Maybe I'm just using the tool wrong, but it seems it has two issues (see each individual commit message for more details).
The first thing fixed are shell errors from the
findElfs
function.The other thing is the discovery of runtime dependencies, the commit message really explains that more clearly.
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)