Skip to content
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

Bintools Wrapper: Init by refactoring out of cc-wrapper, take 2 #29396

Merged
merged 16 commits into from Dec 13, 2017

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Sep 14, 2017

edit see my question in #29396 (comment)

Motivation for this change

This is meant to be reviewed commit by commit.

This is needed so packages that just use binutils get the same setup-hook support. That is, variables like BUILD_AS or LD should be defined the same way, along with the LD_FLAGS. This will be necessary to clean up at least the gcc derivation (which must be built with an binutils not associated with any existsing C compiler when target != host), and probably other compilers too.

More broadly, having two wrappers will help enforce proper layering between binutils and the C compiler. For languages besides C/C++, it would be neat to use `stdenvNoCC + binutils, avoiding a C compiler dependency. This wrapper makes that change possible.

@edolstra I'm hoping for you to merge this change when you approve of it, to avoid a repeat of last time.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option build-use-sandbox in nix.conf on non-NixOS)
  • Built stdenv on platform(s)
    • NixOS --- in progress
    • macOS
    • Linux
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

# TODO(@Ericson2314): Remove this after stable release and force
# everyone to refer to binutils-wrapper directly.
if [[ -f "$binutils/nix-support/dynamic-linker" ]]; then
ln -s "$binutils/nix-support/dynamic-linker" "$out/nix-support"
Copy link
Member Author

Choose a reason for hiding this comment

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

@edolstra this symlink avoids the incompatibility the old version introduced.

@Ericson2314 Ericson2314 changed the title Binutils wrapper: Init by refactoring out of cc-wrapper Binutils wrapper: Init tak 2 by refactoring out of cc-wrapper Sep 14, 2017
@Ericson2314 Ericson2314 changed the title Binutils wrapper: Init tak 2 by refactoring out of cc-wrapper Binutils wrapper: Init by refactoring out of cc-wrapper, take 2 Sep 14, 2017
# Choose 32-bit dynamic linker if needed
if [ -e @out@/nix-support/dynamic-linker-m32 ]; then
prev=
for p in ${params+"${params[@]}"}; do
Copy link
Contributor

Choose a reason for hiding this comment

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

It was determined to be valuable not to iterate over params more times than necessary. Could you merge this loop into the next one? (It has already merged two cases, [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ] and [ "$NIX_@infixSalt@_SET_BUILD_ID" = 1 ].)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea!

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@Ericson2314 Ericson2314 force-pushed the binutils-wrapper branch 2 times, most recently from beb7de1 to f1a1ac2 Compare September 15, 2017 17:16
if [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ] || [ "$NIX_@infixSalt@_SET_BUILD_ID" = 1 ]; then
# Two tasks:
#
# 1. Find all -L... switches for rpath, and relocatable flags for build id.
Copy link
Contributor

@orivej orivej Sep 16, 2017

Choose a reason for hiding this comment

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

These cases are not related, so if you enumerate the cases, these should be 1 and 2.

Copy link
Member Author

Choose a reason for hiding this comment

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

True. Good catch.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

case $depOffset in
-1) local role='BUILD_' ;;
0) local role='' ;;
1) local role='TARGET_' ;;
Copy link
Contributor

Choose a reason for hiding this comment

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

Where may depOffset be set to 1? I find only places where it is set to -1 or 0.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh heh. That would anticipate #26805

Copy link
Member Author

Choose a reason for hiding this comment

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

Cc-wrapper already has that, I guess I'll leave it as consistent anticipation.

@Ericson2314 Ericson2314 force-pushed the binutils-wrapper branch 3 times, most recently from 3dbb0a3 to 621ae3d Compare September 19, 2017 23:36
@Ericson2314 Ericson2314 added the 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on label Sep 20, 2017
@Ericson2314 Ericson2314 added this to the 17.09 milestone Sep 20, 2017
@Ericson2314 Ericson2314 added this to Needed by the big PR---nice to move pick off pieces of it and move here, rebasing the big PR on top in Cross compilation Sep 20, 2017
doc/stdenv.xml Outdated
CC wrapper's setup hook causes any <filename>include</filename> subdirectory of such a dependency to be added to <envar>NIX_CFLAGS_COMPILE</envar>, and any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
Binutils Wrapper's setup hook causes any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
Sine CC Wrapper and Binutils Wrapper use the same strategy, most of the Binutils Wrapper code is sparsely commented and refers to CC Wrapper.
Copy link
Contributor

Choose a reason for hiding this comment

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

"Sine" is a typo.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

doc/stdenv.xml Outdated
It is currently accomplished by collecting directories of host-platform dependencies (i.e. <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>) in environment variables.
CC wrapper's setup hook causes any <filename>include</filename> subdirectory of such a dependency to be added to <envar>NIX_CFLAGS_COMPILE</envar>, and any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
Binutils Wrapper's setup hook causes any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably you're missing the words "be added to" in this sentence.

doc/stdenv.xml Outdated
Firstly, this helps poorly-written packages, e.g. ones that look for just <command>gcc</command> when <envar>CC</envar> isn't defined yet <command>clang</command> is to be used.
Secondly, this helps packages not get confused when cross-compiling, in which case multiple CC wrappers may be simultaneous in use (targeting different platforms).
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional CC Wrappers, properly disambiguating them.
Secondly, this helps packages not get confused when cross-compiling, in which case multiple Binutils Wrappers may be simultaneous in use (targeting different platforms).
Copy link
Contributor

Choose a reason for hiding this comment

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

The idomatic wording options would be:

  • "may be in use simultaneously", or
  • "may be in simultaneous use"

doc/stdenv.xml Outdated
</para>
<para>
Dependency finding is undoubtedly the main task of CC Wrapper.
This works just like Binutils Wrapper, except the any <filename>include</filename> subdirectory of any relevant dependency is added to <envar>NIX_CFLAGS_COMPILE</envar>.
Copy link
Contributor

Choose a reason for hiding this comment

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

"the" should be "that"

doc/stdenv.xml Outdated
Most packages, however, firstly use the C compiler for linking, secondly use <envar>LD</envar> anyways, defining it as the C compiler, and thirdly, only so define <envar>LD</envar> when it is undefined as a fallback.
This triple-threat means CC Wrapper will break those packages, as LD is already defined as the actually linker which the package won't override yet doesn't want to use.
This triple-threat means Binutils Wrapper will break those packages, as LD is already defined as the actually linker which the package won't override yet doesn't want to use.
Copy link
Contributor

Choose a reason for hiding this comment

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

"actually" is not an adjective, probably you meant "actual".

Ericson2314 and others added 13 commits December 13, 2017 16:08
This avoids any `NIX_FOOBAR=1 1` not triggering conditions.
It means stdin, and is morally equivalent to passing a file. e.g.

  $ echo 'int main(void) { return 0; }' | gcc -x c -

will compile and link a binary.
Factor a bintools (i.e. binutils / cctools) wrapper out of cc-wrapper. While
only LD is wrapped, the setup hook defines environment variables on behalf of
other utilites.
Shrunk the CC Wrapper documentation so as not to be repetative.
This is more robust for cross-compilation
Also make the code more precise in the process
These will be installed if the wrappers are. The wrappers aren't very
good to install, but that's another matter.
Will need to be editted again to work for cross
@Ericson2314
Copy link
Member Author

@edolstra told me he doesn't have time to review this any time soon, so we might as well not hold it up further. Yay, thanks!

This has passed nixborg CI many times before. the last change is a mass rebuild, but just from merging with staging. The post-merge change is just an eval fix for a newer package (clang multilib). Merging, but will keep an I on staging just in case.

@Ericson2314 Ericson2314 merged commit c51f27d into NixOS:staging Dec 13, 2017
@Ericson2314 Ericson2314 deleted the binutils-wrapper branch December 13, 2017 21:37
orivej added a commit that referenced this pull request Dec 14, 2017
@orivej
Copy link
Contributor

orivej commented Dec 14, 2017

This broke bloaty, fixed in fe61c3b.

@orivej
Copy link
Contributor

orivej commented Dec 14, 2017

This broke lispPackages.cl-fuse. @Ericson2314 could you fix it? It exports NIX_LDFLAGS with -L/nix/store/wr579906xik1qbnblm0wq1nissxh53sy-fuse-2.9.7/lib and runs gcc (wrapper), but gcc invokes unwrapped gcc without these NIX_LDFLAGS. Here is this sequence of steps: https://gist.github.com/orivej/4c8fc1b12d8d630edf24b6ff5f88cd80 (141-142-sbcl runs sbcl, which runs gcc in the same way as 142-143-gcc, which runs the unwrapped gcc just like 143-144-gcc .) Here is how NIX_LDFLAGS are defined:

echo "export NIX_LDFLAGS='$NIX_LDFLAGS'\"\''${NIX_LDFLAGS:+ \$NIX_LDFLAGS}\"" >> "$config_script"

@orivej
Copy link
Contributor

orivej commented Dec 19, 2017

Two perl packages,perlPackages.EncodeDetect and perlPackages.ExtUtilsCppGuess, fail to build with ld: cannot find -lstdc++. They are needed for spamassassin and slic3r. @Ericson2314 agreed to try to fix them.

It seems that lispPackages.cl-fuse may not be fixed before the merge to master. /cc @7c6f434c

@Ericson2314
Copy link
Member Author

Ericson2314 commented Dec 19, 2017

Can't fix this instant, but the crux of the Perl packages' problem is that ld no longer magically see's into the C(XX)'s compiler's lib directory. LD=$CC might be the best solution to avoid violating layers for now.

orivej added a commit to orivej/nixpkgs that referenced this pull request Dec 19, 2017
after NixOS#29396 removed `-L path/to/dir/of/libstdc++.so` from ld flags

See NixOS#29396 (comment)

Module::Build build helper works correctly when LD is unset (taking LD from Perl
config to be `cc`).  However, we can not unset LD because this goes contrary to
the cross compilation effort, and we can not make it propagate ld-is-cc-hook
because it breaks e.g. the build of `libguestfs`. However, NixOS#29396 makes LD=ld
incompatible with just 3 perl packages; they are individually fixed by this
commit.
@orivej
Copy link
Contributor

orivej commented Dec 19, 2017

Thanks! I'm fixing perl packages in #32830.

@7c6f434c
Copy link
Member

Hm. I don't really understand where NIX_LDFLAGS gets lost in CL-Fuse build… So I gave up and the shared library is now prebuilt separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Cross compilation
Needed by the big PR---nice to move p...
Development

Successfully merging this pull request may close these issues.

None yet