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

Allow using LLVM for cross compilation toolchain #55750

Merged
merged 4 commits into from Feb 27, 2019

Conversation

matthewbauer
Copy link
Member

@matthewbauer matthewbauer commented Feb 14, 2019

Motivation for this change

The idea is to allow you to build with LLVM by passing something like this in Nixpkgs:

nix-build -A hello --arg crossSystem '{ config = "aarch64-unknown-linux-gnu"; useLLVM = true; }'

Lots of this is based on the approach taking in wasm-cross repo:

https://github.com/WebGHC/wasm-cross

Unfortunately I haven't gotten libc to cross compile without using GCC.

@dtzWill
Copy link
Member

dtzWill commented Feb 14, 2019

Regarding crtbegin/crtend bits: https://reviews.llvm.org/D28791 .

We may want to start looking at using LLVM utilities for binutils, there's a build-time option and they act like the gnu binutils if symlink'd over I think. No idea how well they'd be suited to our needs but something to keep in mind. And of course optionally using LLD as default linker :).

Looking at these changes presently! :)

Copy link
Member

@dtzWill dtzWill left a comment

Choose a reason for hiding this comment

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

Generally looks very good! I haven't been able to look at it more hands-on so as to help catch some more subtle problems, sorry. Offhand I remember something like if we don't specify --gcc-toolchain and clang was built with gcc, it will try to find the path of the compiler that built it-- which can cause some painfully subtle problems re:staging if that's not what you expect. I'm not sure what the behavior is with recent clang, and haven't really dug into this for a while :). Will be looking into this again "soon" but not sure when that'll be so nevermind that :). Exciting!!

ln -sf $prog $out/bin/${prefix}$(basename $prog)
done
rm -f $out/bin/${prefix}cat
ln -s ${lld}/bin/lld $out/bin/${prefix}ld
Copy link
Member

Choose a reason for hiding this comment

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

LOL I see my comment re:using llvm bits symlinked over ... is not news to you! 🗡️

FWIW this might be a great deal simpler and more predictable if instead of shell globs and loops it used linkFarm or whichever over in trivial-builders.nix. I think enumerating what we intend/expect to symlink is reasonable- the number shouldn't grow much higher than it is and this way nothing sneaks in as part of a bump :).

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah that probably would be better. Even just listing out all of the utilities here like we do in https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/darwin/binutils/default.nix would be helpful. This is actually originally from wasm-cross here:

https://github.com/WebGHC/wasm-cross/blob/master/llvm-head/default.nix#L58-L82

but I think that change would be a good idea.

@matthewbauer
Copy link
Member Author

@GrahamcOfBorg test.hello

@matthewbauer
Copy link
Member Author

@GrahamcOfBorg test hello

@matthewbauer
Copy link
Member Author

It looks like the built binaries aren't actually working! I get it to hang on the qemu-user emulator.

@GrahamcOfBorg build tests.cross.hello.aarch64-multiplatform-musl

@Ericson2314
Copy link
Member

Ericson2314 commented Feb 16, 2019

Instead of useLLVM, could we have like something more structured? E.g. *Platform.{cc, bintools} = {"gnu", "llvm", "cctools" /* just for cc */ } that would be defaulted and everything like the lib attribute that exists today? That would support the full combinatorial explosion of use-cases.

@@ -92,7 +92,7 @@ stdenv.mkDerivation rec {
outputs = [ "out" "dev" ];

dontDisableStatic = true;
separateDebugInfo = true;
separateDebugInfo = !(stdenv.hostPlatform.useLLVM or false);
Copy link
Member Author

Choose a reason for hiding this comment

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

This should be set for everything - separate-debug-info relies on gcc binutils

Copy link
Member

Choose a reason for hiding this comment

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

I believe you, but am a bit surprised by this. Is this because of the way we do things or do LLVM bits not support split debug info? Or is "split"/"separate" an important difference? O:)

Copy link
Member Author

Choose a reason for hiding this comment

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

I looked into it and it looks like there are no build ids produced:

$CC test.c -o test
$READELF -n test

Probably configurable?

cc = tools.clang-unwrapped;
bintools = wrapBintoolsWith {
inherit (tools) bintools;
libc = null;
Copy link
Member Author

Choose a reason for hiding this comment

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

should set isLLVM or similar

@matthewbauer matthewbauer changed the title [wip] Allow using LLVM for cross compilation toolchain Allow using LLVM for cross compilation toolchain Feb 26, 2019
@matthewbauer matthewbauer force-pushed the llvm-cross branch 4 times, most recently from c741414 to 364dfdc Compare February 26, 2019 03:42
@matthewbauer
Copy link
Member Author

@GrahamcOfBorg build tests.cross.file-llvm.aarch64-multiplatform-musl tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.musl64 tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.musl64 tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.mingwW64 tests.cross.file-llvm.musl-power

@matthewbauer
Copy link
Member Author

@GrahamcOfBorg build tests.cross.file-llvm.aarch64-multiplatform-musl tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.musl64 tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.musl64 tests.cross.file-llvm.armv7l-unknown-linux-gnueabihf tests.cross.file-llvm.mingwW64 tests.cross.file-llvm.musl-power

});

libraries = stdenv.lib.makeExtensible (libraries: let
callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python isl release_version version fetch; });
in {

compiler-rt = callPackage ./compiler-rt.nix {};
compiler-rt = callPackage ./compiler-rt.nix {
stdenv = if stdenv.hostPlatform.useLLVM or false
Copy link
Member

Choose a reason for hiding this comment

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

Oh can do you do the stdenv.hostPlatform.cc = "llvm" thing?

LLVM should be target independent because it will work with all
machine types. This is different from GCC where it needs to know what
target to build ahead of time.
(cherry picked from commit 08f5b419b9efc77db044f8c1d725632552617966)
You can build (partially) with LLVM toolchain using the useLLVM flag.
This works like so:

  nix-build -A hello --arg crossSystem '{ system =
    "aarch64-unknown-linux-musl"; useLLVM = true }'

also don’t separate debug info in lldClang

It doesn’t work currently with that setup hook. Missing build-id?
@ElvishJerricco
Copy link
Contributor

@matthewbauer This is awesome! Is there an example of how to make a nixpkgs instance using this and musl for stdenv?

@matthewbauer

This comment has been minimized.

@ElvishJerricco
Copy link
Contributor

@matthewbauer Sweet! And the musl will be buillt with Clang?

@dtzWill
Copy link
Member

dtzWill commented Feb 28, 2019 via email

@delroth
Copy link
Contributor

delroth commented Feb 28, 2019

This PR seems to have broken compiler-rt on x86_64 (which breaks stuff like chromium). https://hydra.nixos.org/eval/1507125

$ nix-shell -p llvmPackages_latest.compiler-rt
...
CMake Error at cmake/base-config-ix.cmake:153 (add_default_target_arch):
  add_default_target_arch Macro invoked with incorrect arguments for macro
  named: add_default_target_arch
Call Stack (most recent call first):
  cmake/config-ix.cmake:140 (test_targets)
  CMakeLists.txt:168 (include)

@delroth
Copy link
Contributor

delroth commented Feb 28, 2019

Sent a fix in #56502.

@matthewbauer
Copy link
Member Author

Oops yeah meant crossSystem

@dtzWill
Copy link
Member

dtzWill commented Feb 28, 2019 via email

@matthewbauer
Copy link
Member Author

Yeah it’s a lot cheaper than having to recompile the whooe gcc each time too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants