Skip to content

wrapQtAppsHook: support structuredAttrs#526277

Merged
K900 merged 2 commits into
NixOS:stagingfrom
MattSturgeon:wrapQtAppsHook-structuredAttrs
Jun 4, 2026
Merged

wrapQtAppsHook: support structuredAttrs#526277
K900 merged 2 commits into
NixOS:stagingfrom
MattSturgeon:wrapQtAppsHook-structuredAttrs

Conversation

@MattSturgeon

@MattSturgeon MattSturgeon commented May 31, 2026

Copy link
Copy Markdown
Contributor

Use stdenv's concatTo helper to normalize qtWrapperArgs, instead of assuming a single string representation. This handles both structuredAttrs modes: when __structuredAttrs = true, qtWrapperArgs is already an array.

Tests are added to cover both structuredAttrs modes and verify that wrapper behaviour remains identical across both configurations, including argument propagation and runtime behaviour.

Fixes #526275, which is blocking #461881.

AI assistance disclosure

  • I used ChatGPT to review the patch and help iterate on test structure and coverage.
  • The final implementation and decisions were made and validated manually.

Things done

@MattSturgeon MattSturgeon linked an issue May 31, 2026 that may be closed by this pull request
@nixpkgs-ci nixpkgs-ci Bot added 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-darwin: 101-500 This PR causes between 101 and 500 packages to rebuild on Darwin. 10.rebuild-linux: 1001-2500 This PR causes many rebuilds on Linux and should target the staging branches. labels May 31, 2026
@MattSturgeon

MattSturgeon commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

I'd like to include a test, does anyone know where this hook's tests live?

Drafting for now as the fix may be incomplete: #461881 (comment)

EDIT: I couldn't find any existing qt hook tests, so I added passthru tests and exposed them to the top-level in pkgs/test/default.nix.

@MattSturgeon MattSturgeon marked this pull request as draft May 31, 2026 10:24
@MattSturgeon MattSturgeon force-pushed the wrapQtAppsHook-structuredAttrs branch 2 times, most recently from 7cc16c2 to ec54798 Compare June 1, 2026 00:14
@MattSturgeon MattSturgeon marked this pull request as ready for review June 1, 2026 00:18
@K900

K900 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Why do the strings dance instead of just sourcing the hook and printing out qtWrapperArgs?

@MattSturgeon

MattSturgeon commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

Why do the strings dance instead of just sourcing the hook and printing out qtWrapperArgs?

Context

When I was iterating on the fix locally, I needed a "full" integration test with makeCWrapper, as my initial approach "fixed" the shell variables in the hook but resulted in args not being passed to makeCWrapper.

I wrote the test to align with my manual debugging method (inspecting the actual wrapper). And the test caught that what I thought was an internal qtWrapperArgs -> qtWrapperArgsArray copy was actually a breaking change.

Sourcing the hook and printing out qtWrapperArgs would catch that too, you're right. And in hindsight, now that I know qtWrapperArgsArray would be a breaking change it'd be much simpler to just read qtWrapperArgs, yes.

It would be slightly less coverage, in that it only asserts the expected array is produced; it wouldn't test that the array is used to produce the expected wrapper.

Even if we kept a strings-based test, checking the expected array is constructed would also be a valuable test in its own right.

@MattSturgeon MattSturgeon force-pushed the wrapQtAppsHook-structuredAttrs branch from ec54798 to 21c05c3 Compare June 1, 2026 12:16
@MattSturgeon

Copy link
Copy Markdown
Contributor Author

I've re-thought the test coverage and removed the strings-based executable inspection. Thanks for the feedback @K900!

The test coverage is now structured as:

  1. Verify that the expected qtWrapperArgs array is produced by wrapQtAppsHook
  2. Verify runtime behaviour: the wrapped program observes the expected effects
    • (working directory, environment variables such as QT_PLUGIN_PATH, and injected wrapper arguments)
  3. Build both cases with __structuredAttrs = true and false

This preserves coverage of both the hook's argument handling and its effect on the final wrapped executable, without relying on inspecting the generated binary wrapper.

The patches to wrapQtAppsHook itself are unchanged; only the test strategy has been simplified.

@MattSturgeon MattSturgeon force-pushed the wrapQtAppsHook-structuredAttrs branch from 21c05c3 to f2cb7c5 Compare June 1, 2026 12:58
@MattSturgeon MattSturgeon force-pushed the wrapQtAppsHook-structuredAttrs branch from f2cb7c5 to 0c0980f Compare June 3, 2026 18:07
@MattSturgeon

Copy link
Copy Markdown
Contributor Author

I pushed a further simplification to the tests: https://github.com/NixOS/nixpkgs/compare/f2cb7c5d4a144bcf9026d5c1ce232a7cedd1b5fa..0c0980f13122c07211ca0c6ad4992a162f62bcab

It turns out qtWrapperArgs is processed when the hook is sourced, before the wrapQtAppsHook function itself is invoked by any stdenv phase.

Therefore, only the runtime integration test needs to call wrapQtAppsHook. The qtWrapperArgs unit test has been simplified to only exercise the hook's setup logic, which is where qtWrapperArgs is setup & processed.

Comment thread pkgs/development/libraries/qt-6/tests/wrap-qt-apps-hook.nix Outdated
Test that wrapQtAppsHook:
- normalizes qtWrapperArgs to a bash array
- preserves user-supplied wrapper arguments
- appends the expected Qt wrapper arguments
- produces wrappers with the expected runtime behaviour
With `__structuredAttrs = true`, `qtWrapperArgs` is provided as an
array; without it, it is provided as a string.

Use stdenv's `concatTo` helper to normalize `qtWrapperArgs` to a bash
array, regardless of its representation.

Adjust the hook's tests to cover both __structuredAttrs true and false.
@MattSturgeon MattSturgeon force-pushed the wrapQtAppsHook-structuredAttrs branch from 0c0980f to cd5e77d Compare June 4, 2026 00:43

@khaneliman khaneliman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM tests pass on darwin now

@nixpkgs-ci nixpkgs-ci Bot added the 12.approvals: 1 This PR was reviewed and approved by one person. label Jun 4, 2026
@K900

K900 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

FWIW you can avoid the C compile dance by just explicitly doing wrapQtApp on a bash script or whatever.

@MattSturgeon

MattSturgeon commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

I started off with a bash script, but it didn't seem to be getting wrapped. I assumed the hook was only wrapping binary executables?

Edit: looks like that's intentional:

# Skip the file if it is not a binary (ELF or Mach-O)
isELF "$file" || isMachO "$file" || continue

EDIT

FWIW you can avoid the C compile dance by just explicitly doing wrapQtApp on a bash script or whatever.

That's true, although my goal with the runtime test was to exercise the normal nativeBuildInputs = [ wrapQtAppsHook ] workflow end-to-end, rather than wrapQtApp in isolation.

I think the C compiled fixture is a reasonable trade-off here, as the hook's main entrypoint filters for ELF binaries.

@K900 K900 added this pull request to the merge queue Jun 4, 2026
Merged via the queue into NixOS:staging with commit 336a60d Jun 4, 2026
29 checks passed
@MattSturgeon MattSturgeon deleted the wrapQtAppsHook-structuredAttrs branch June 4, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10.rebuild-darwin: 101-500 This PR causes between 101 and 500 packages to rebuild on Darwin. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 1001-2500 This PR causes many rebuilds on Linux and should target the staging branches. 12.approvals: 1 This PR was reviewed and approved by one person.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

qtWrapperArgs is broken with __structuredAttrs = true

3 participants