Skip to content

cc-wrapper: use a temporary file for reponse file#245282

Merged
wegank merged 1 commit intoNixOS:stagingfrom
reckenrode:gccStdenv-fix
Aug 2, 2023
Merged

cc-wrapper: use a temporary file for reponse file#245282
wegank merged 1 commit intoNixOS:stagingfrom
reckenrode:gccStdenv-fix

Conversation

@reckenrode
Copy link
Contributor

@reckenrode reckenrode commented Jul 25, 2023

The Darwin stdenv rework conditionally sets NIX_CC_USE_RESPONSE_FILE depending on the ARG_MAX of the build system. If it is at least 1 MiB, the stdenv passes the arguments on the command-line (like Linux). Otherwise, it falls back to the response file. This was done to prevent intermitent failures with clang 16 being unable to read the response file. Unfortunately, this breaks gccStdenv on older Darwin platforms.

Note: While the stdenv logic will also be reverted, this change is needed for compatibility with clang 16.

GCC is capable of using a response file, but it does not work correctly when the response file is a file descriptor. This can be reproduced using the following sequence of commands:

$ nix shell nixpkgs#gcc; NIX_CC_USE_RESPONSE_FILE=1 gcc
# Linux
/nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: unrecognized option '-B/nix/store/vnwdak3n1w2jjil119j65k8mw1z23p84-glibc-2.35-224/lib/'
/nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
# Darwin
ld: unknown option: -mmacosx-version-min=11.0
collect2: error: ld returned 1 exit status

The fix is to create a temporary file instead and remove it in a trap. This should also prevent intermitent failures with clang 16 on older Darwin systems.

Tested by building acme-client with NIX_CC_USE_RESPONSE_FILE=1 set. $TMP was reviewed afterward to confirm no files, and fswatch was used to confirm that temporary response files were used.

Fixes #245167

Description of changes
Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.11 Release Notes (or backporting 23.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@reckenrode reckenrode requested a review from Ericson2314 as a code owner July 25, 2023 01:57
@reckenrode reckenrode requested a review from a user July 25, 2023 01:57
@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. labels Jul 25, 2023
@ghost
Copy link

ghost commented Jul 25, 2023

TIL what a "response file" is. Thanks! For the benefit of others.

The fix is to create a temporary file instead and remove it in a trap.

Do we need to remove it?

Debugging failed sandboxed builds in Nix is notoriously difficult. Really the only reliable tool is --keep-failed, and we'd like to leave behind as much useful data as possible for diagnosis (since there's really no reliable way to get a shell inside the sandbox at the point of failure -- I've tried a lot of tools that claim to offer this and none of them really works robustly).

LGTM other than this, but somebody with Darwin hardware should review this.

@reckenrode
Copy link
Contributor Author

Do we need to remove it?

When I was exploring solutions to the clang 16 issue, I tried leaving the temporary files around (with the idea they would be cleaned up when the whole build is cleaned up). Unfortunately, not every build is well-behaved. I found temporary response files in /tmp (e.g., while building GHC). I also expect it would be an issue for users with dev shells. /tmp is cleaned automatically on Darwin, but user-private temporary directories are not.

Debugging failed sandboxed builds in Nix is notoriously difficult. Really the only reliable tool is --keep-failed, and we'd like to leave behind as much useful data as possible for diagnosis (since there's really no reliable way to get a shell inside the sandbox at the point of failure -- I've tried a lot of tools that claim to offer this and none of them really works robustly).

Given my work recently on the Darwin stdenv and having to fix the fallout of updating clang, I’m sympathetic to that. However, I don’t think the trade-offs are worth it. It’s usually been possible to debug interactively (e.g., source env-vars with --keep-failed or use nix develop), so I wouldn’t want to fill up users’ temporary directories with junk (especially since this is only going to be used on older systems, who may not have a lot of storage to start).

@reckenrode
Copy link
Contributor Author

I’m going to open a PR to revert the NIX_CC_USE_RESPONSE_FILE logic in the stdenv. It turns out qtwebengine is failing to build even on new versions of macOS with 1 MiB ARG_MAX. This commit will still be needed by clang 16 and should provide compatibility for GCC should it ever need to use response files.

reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Jul 27, 2023
To work around intermitent build failures with clang 16, the stdenv
attempted to pass arguments on the command-line on newer versions of
macOS. Unfortunately, the larger `ARG_MAX` is still not large enough to
build qtwebengine. This commit reverts the `NIX_CC_NO_RESPONSE_FILE`
logic in the stdenv. The changes to cc-wrapper in NixOS#245282 are needed for
clang 16 to prevent the above-mentioned build failures.
The Darwin stdenv rework conditionally sets `NIX_CC_USE_RESPONSE_FILE`
depending on the `ARG_MAX` of the build system. If it is at least 1 MiB,
the stdenv passes the arguments on the command-line (like Linux).
Otherwise, it falls back to the response file. This was done to prevent
intermitent failures with clang 16 being unable to read the response
file. Unfortunately, this breaks `gccStdenv` on older Darwin platforms.

Note: While the stdenv logic will also be reverted, this change is
needed for compatibility with clang 16.

GCC is capable of using a response file, but it does not work correctly
when the response file is a file descriptor. This can be reproduced
using the following sequence of commands:

    $ nix shell nixpkgs#gcc; NIX_CC_USE_RESPONSE_FILE=1 gcc
    # Linux
    /nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: unrecognized option '-B/nix/store/vnwdak3n1w2jjil119j65k8mw1z23p84-glibc-2.35-224/lib/'
    /nix/store/9n9gjvzci75gp2sh1c4rh626dhizqynl-binutils-2.39/bin/ld: use the --help option for usage information
    collect2: error: ld returned 1 exit status
    # Darwin
    ld: unknown option: -mmacosx-version-min=11.0
    collect2: error: ld returned 1 exit status

Instead of using process substitution, create a temporary file and
remove it in a trap. This should also prevent the intermitent build
failures with clang 16 on older Darwin systems.

Fixes NixOS#245167
@reckenrode
Copy link
Contributor Author

I was going to update the PR when I got home tonight, but thanks for pushing an updated commit.

@wegank wegank merged commit 7c1239a into NixOS:staging Aug 2, 2023
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request May 31, 2024
This changes ld-wrapper to use a temporary file for the response file
passed to ld instead of using process substitution.

ld64 does not handle long command-lines when reading from the response
file, which defeats the point of using a response file to handle long
command-lines. cctools-port was patched to work around this, but nixpkgs
is now using Apple’s source release directly instead of the port.

Since it’s preferable not to patch Apple’s release heavily (to reduce
the difficulty of updating to new versions and to match upstream’s
behavior), use the approach that was adopted in cc-wrapper to work
around issues with response files in newer versions of clang.

Related PRs (cctools-port):
- NixOS#213831
- tpoechtrager/cctools-port#132

Related PRs (cc-wrapper):
- NixOS#245282
- NixOS#258608
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Jun 2, 2024
This changes ld-wrapper to use a temporary file for the response file
passed to ld instead of using process substitution.

ld64 does not handle long command-lines when reading from the response
file, which defeats the point of using a response file to handle long
command-lines. cctools-port was patched to work around this, but nixpkgs
is now using Apple’s source release directly instead of the port.

Since it’s preferable not to patch Apple’s release heavily (to reduce
the difficulty of updating to new versions and to match upstream’s
behavior), use the approach that was adopted in cc-wrapper to work
around issues with response files in newer versions of clang.

Related PRs (cctools-port):
- NixOS#213831
- tpoechtrager/cctools-port#132

Related PRs (cc-wrapper):
- NixOS#245282
- NixOS#258608
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Jul 13, 2024
This changes ld-wrapper to use a temporary file for the response file
passed to ld instead of using process substitution.

ld64 does not handle long command-lines when reading from the response
file, which defeats the point of using a response file to handle long
command-lines. cctools-port was patched to work around this, but nixpkgs
is now using Apple’s source release directly instead of the port.

Since it’s preferable not to patch Apple’s release heavily (to reduce
the difficulty of updating to new versions and to match upstream’s
behavior), use the approach that was adopted in cc-wrapper to work
around issues with response files in newer versions of clang.

Related PRs (cctools-port):
- NixOS#213831
- tpoechtrager/cctools-port#132

Related PRs (cc-wrapper):
- NixOS#245282
- NixOS#258608
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Jul 16, 2024
This changes ld-wrapper to use a temporary file for the response file
passed to ld instead of using process substitution.

ld64 does not handle long command-lines when reading from the response
file, which defeats the point of using a response file to handle long
command-lines. cctools-port was patched to work around this, but nixpkgs
is now using Apple’s source release directly instead of the port.

Since it’s preferable not to patch Apple’s release heavily (to reduce
the difficulty of updating to new versions and to match upstream’s
behavior), use the approach that was adopted in cc-wrapper to work
around issues with response files in newer versions of clang.

Related PRs (cctools-port):
- NixOS#213831
- tpoechtrager/cctools-port#132

Related PRs (cc-wrapper):
- NixOS#245282
- NixOS#258608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants