-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
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
stdenv: log build hooks as they run #290081
Conversation
This is an excellent idea, I like it a lot. |
Addresses the following review comments: - https://github.com/NixOS/nixpkgs/pull/290081/files/eb28e5e72ef912629ded3e265f7344ca21d115b9#r1501466125 - https://github.com/NixOS/nixpkgs/pull/290081/files/eb28e5e72ef912629ded3e265f7344ca21d115b9#r1501466232 This will be squashed into the previous commit pending review.
Thanks @fogti! Those are now fixed |
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 like how this makes the Nix build process more discoverable. I've learned a lot about Nix from reading logs, and this turbo-charges that process.
I've got a couple questions about the most complicated piece of this review, the "${NIX_DEBUG:-0}" < 2
section. Dropping that complexity would be ideal, in my view, if it didn't come with bad tradeoffs.
while IFS= read -r hookExprLine; do | ||
# These lines often have indentation, | ||
# so let's remove leading whitespace. | ||
hookExprLine="${hookExprLine#"${hookExprLine%%[![:space:]]*}"}" | ||
# If this line wasn't entirely whitespace, | ||
# then add it to our output. | ||
if [[ -n "$hookExprLine" ]]; then | ||
exprToOutput+="$hookExprLine\\n " | ||
fi | ||
done <<< "$hookExpr" | ||
|
||
# And then remove the final, unnecessary, \n | ||
exprToOutput="${exprToOutput%%\\n }" |
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 is cute, but what's the damage just showing the log-viewing user what the hook value is directly? How many of these are there?
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 many. I only know of one, which is autoPatchelfHook. I ran rg -U -t sh 'hook.?\+?=\(.\n'
to try to find other examples but I couldn't find any, though I'm not confidant that regex is all-inclusive. By far most hooks are either functions, or single-line if [[ -z "${dontDoHookThing-}" ]]; then doHookThing; fi
. I am fine with splatting out potential multiline hooks, and autoPatchelfHook could easily be changed to do its multiline logic in its hook function instead of inline.
source "$hookName" | ||
elif [ -n "${!hookName:-}" ]; then | ||
echo "evaling implicit '$hookName' string hook" |
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.
For instance, here you don't do the trick with "${NIX_DEBUG:-0}" >= 2
and just splat it out.
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.
Actually this part doesn't splat out the hook string — since implicit hooks are for specifying "one-off" hooks right in a derivation, they're going to be specified by the derivation being built itself. Those often are multiline, but since they're also by far the most obvious hooks, I went with just logging the name. So something like
preConfigure = ''
some foo commands
'';
Gets logged as evaling implicit 'preConfigure' hook
without printing the text itself. If you have something better I'm absolutely all ears 🙂
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.
That's definitely good enough. Thanks for the example.
I wonder (and this isn't for this review) whether "implicit" is the right name for this concept, and whether "immediate" or "derivation-supplied" might be a better name. In fact, from the perspective of the derivation or package author, they might be thought of as "explicit" hooks as opposed to the "implicit" ones that come from elsewhere. An irony if so.
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.
A lot of my time spent debugging this ended up actually amounting to figuring out what implicit hooks are and where they come from and why there's a separate, special mechanism for them in stdenv 😅
So I completely agree; a rename of the concept would be very helpful. "Immediate" is decent, but further bikeshedding can be at a later date
Addresses the following review comment: NixOS#290081 (comment) This will be squashed into the previous commit pending review. Co-authored-by: Philip Taron <philip.taron@gmail.com>
Addresses the following review comment: NixOS#290081 (comment) This will be squashed into the previous commit pending review. Co-authored-by: Philip Taron <philip.taron@gmail.com>
OK, I made a version of this PR (philiptaron@e7e7675) that I could grep through the produced build logs and see what it looked like. After building my entire machine derivation:
To me, this suggests that each of these hooks ought to be made to fit under the previous function or sourcing hook logic (probably function) ... and that the cute, complicated loop actually works. Nice, @Qyriad. |
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.
Tested and works.
Is this ready to be squashed? Edit: Nevermind! Thank you Raito! |
i am seeing debug output when invoking nix-shell and i don't think i should see anything. $ nix-shell -I nixpkgs=. -p bash
sourcing setup hook '/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh'
sourcing setup hook '/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh'
sourcing setup hook '/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh'
sourcing setup hook '/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh'
sourcing setup hook '/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh'
sourcing setup hook '/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh'
sourcing setup hook '/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh'
sourcing setup hook '/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh'
sourcing setup hook '/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh'
sourcing setup hook '/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh'
sourcing setup hook '/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh'
sourcing setup hook '/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh'
sourcing setup hook '/nix/store/wmknncrif06fqxa16hpdldhixk95nds0-strip.sh'
sourcing setup hook '/nix/store/8dylc060lmn314b8wmz9bzm8f1dxv1n6-clang-wrapper-16.0.6/nix-support/setuphook'
sourcing setup hook '/nix/store/z46kig749819lcaz5sdbklnmx0bndlwg-cctools-binutils-darwin-wrapper-16.0.6-973.0.1/nix-support/setuphook'
calling 'envHostHostHook' function hook 'ccWrapper_addCVars' /nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh
calling 'envHostHostHook' function hook 'bintoolsWrapper_addLDVars' /nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh
calling 'envHostHostHook' function hook 'ccWrapper_addCVars' /nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh
calling 'envHostHostHook' function hook 'bintoolsWrapper_addLDVars' /nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh
calling 'envHostHostHook' function hook 'ccWrapper_addCVars' /nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh
calling 'envHostHostHook' function hook 'bintoolsWrapper_addLDVars' /nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh
[...] using a8149b5 |
In NixOS#290081 it came to attention that autoPatchelfHook is one of if not the only hook in Nixpkgs that is a multiline string expression. Almost all hooks are functions, which guard with something like `if [ -z "${dontDoTheThing-}" ]; then ...` in the function, or single-line strings which include that guard inline and then call the real function, e.g. `if [ -z "${dontDoTheThing-} ]; then doTheThing; fi`. This commit moves autoPatchelfHook to the former, which seems to be the most common style now.
Description of changes
Hooks are vital to Nixpkgs, and are often the "magic" to make things Just Work, but they're also extremely opaque. Adding something like
undmg
to a derivation'snativeBuildInputs
adds a hook to the unpackPhase to automatically extract DMG sources — this is fantastic, but a beginner would have no way of knowing that adding something as a build input could have such a major effect (undmg
gets only a single passing mention in the Nixpkgs manual), and even to Nixpkgs veterans it's far from obvious what the final array of hooks for a build might be, or what order they even run in (a source of confusion if one causes an error!).This PR changes stdenv's setup.sh to log hooks to stdout as they run, as it does currently with phases. Setup hook files are logged just before they're sourced, and individual build hooks like
patchShebangsAuto
are also logged just before they're run.With this PR, now anyone building with
--print-build-logs
will have transparency into one of the most important aspects of Nixpkgs, to aid heavily in both debugging and learning.For example, here what it now looks like when building Curlie:
There are more example output diffs at https://github.com/Qyriad/nixpkgs/compare/before/diag/log-hooks...Qyriad:nixpkgs:after/diag/log-hooks?diff=split&w=.
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.