-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
Add response file support when compiling with clang #112449
Conversation
Co-authored-by: Matthew Bauer <mjbauer95@gmail.com>
Does macOS reserves a smaller stack for arguments compared to Linux? Is the motivation to only do this for clang that we use clang on macOS? |
I think the main issue is ARG_MAX is a lot smaller on macOS. You can hit this on Linux too in some cases with GHC which can create a really long argument list. |
Yeah i would rather the condition be macOS or Darwin than Clang too. There's no need to change clang on Linux, and there is a need to change non-clang on Darwin. |
As @matthewbauer pointed out, this is sadly not limited to darwin. You can even exceed linux rather generous argument list.
non-clang on Darwin? GCC? That ones is almost impossible to fix, because GCC internally expands response files and feeds them expanded to collect2, which in turn will blow up. That's the reason why this is clang guarded. |
Ah OK. That's a good point. |
Fixes build failures with clang: clang-7: error: unknown argument: '-fPIC -target' clang-7: error: no such file or directory: '@<(printf %qn -O2' clang-7: error: no such file or directory: 'x86_64-apple-darwin' Introduced by 60c5cf9 in NixOS#112449
Currently `ld` uses `mmap` to read in the contents of the response file (presumably for performance reasons), but `mmap` sometimes doesn't work on special files like pipes. For example, if you do something like: ``` $ ld @<(echo --help) ``` … that will currently fail with a segmentation fault. You might wonder why one would want to generate a response file from process substitution. The rationale behind this is that I'm currently in the process of fixing a longstanding issue with the linker failing in Nixpkgs on macOS due to hitting command-line length limits and the fix entails the use of process substitution to generate the process file. Specifically, what I was doing was building upon the work from this PR: NixOS/nixpkgs#112449 … which modified the `cc-wrapper` in Nixpkgs to use a response file generate from process substitution. I was going to do essentially the same for the `ld-wrapper` in Nixpkgs, but that failed with a segmentation fault (for the reasons outlined above). There are other possible ways to work around that, but using process substitution is the "leanest" way of generating the response file for `ld` in Nixpkgs, so I wanted to push on getting that working here instead of working around the problem downstream. So the way I fixed it was to fall back to using `read` instead of `mmap` if the `mmap` failed. After this change, the above sample command now works correctly. This also fixes another small issue along the way: this now correctly detects when the `mmap` fails. Previously, the `mmap` logic was detecting failure by looking for a `NULL`/`0` return value, but that is not the correct error-handling behavior. `mmap` returns `MAP_FAILED` on failure, which is `-1` in practice, and not `0`. That's the reason why the code was failing with a segmentation fault before because it wasn't detecting the failure and proceeding to read from the invalid buffer anyway.
The motivation behind this is to alleviate the problem described in NixOS#41340. I'm not sure if this completely fixes the problem, but it eliminates one more area where we can exceed command line length limits. This is essentially the same change as in NixOS#112449, except for `ld-wrapper.sh` instead of `cc-wrapper.sh`. However, that change alone was not enough; on macOS the `ld` provided by `darwin.cctools` fails if you use process substitution to generate the response file, so I put up a PR to fix that: tpoechtrager/cctools-port#131 … and I included a patch referencing that fix so that the new `ld-wrapper` still works on macOS.
The motivation behind this is to alleviate the problem described in NixOS#41340. I'm not sure if this completely fixes the problem, but it eliminates one more area where we can exceed command line length limits. This is essentially the same change as in NixOS#112449, except for `ld-wrapper.sh` instead of `cc-wrapper.sh`. However, that change alone was not enough; on macOS the `ld` provided by `darwin.cctools` fails if you use process substitution to generate the response file, so I put up two PRs to fix that: tpoechtrager/cctools-port#131 tpoechtrager/cctools-port#132 … and I included a patch referencing that fix so that the new `ld-wrapper` still works on macOS.
The motivation behind this is to alleviate the problem described in NixOS#41340. I'm not sure if this completely fixes the problem, but it eliminates one more area where we can exceed command line length limits. This is essentially the same change as in NixOS#112449, except for `ld-wrapper.sh` instead of `cc-wrapper.sh`. However, that change alone was not enough; on macOS the `ld` provided by `darwin.cctools` fails if you use process substitution to generate the response file, so I put up two PRs to fix that: tpoechtrager/cctools-port#131 tpoechtrager/cctools-port#132 … and I included a patch referencing that fix so that the new `ld-wrapper` still works on macOS.
The motivation behind this is to alleviate the problem described in #41340. I'm not sure if this completely fixes the problem, but it eliminates one more area where we can exceed command line length limits. This is essentially the same change as in #112449, except for `ld-wrapper.sh` instead of `cc-wrapper.sh`. However, that change alone was not enough; on macOS the `ld` provided by `darwin.cctools` fails if you use process substitution to generate the response file, so I put up a PR to fix that: tpoechtrager/cctools-port#131 … and I included a patch referencing that fix so that the new `ld-wrapper` still works on macOS.
Motivation for this change
nixpkgs easily produces lots of arguments to the c compiler. This can in extreme cases lead to the arguments exceeding the space for arguments to be passed. A common fix for this is to write the arguments into a file and pass that file (called response file) to the compiler.
This issues comes up often when building large haskell applications on macOS due to the large amount of library search paths that are being passed as well as other c flags.
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)