Message ID | 499e5dba47ef40df93a8b33fbb8e41cc2354e7a1.1646387919.git.julien@lepiller.eu |
---|---|
State | New |
Headers | show |
Series | [bug#54239,v2,1/5] gnu: Add cross-llvm. | expand |
Context | Check | Description |
---|---|---|
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
Hi Julien,
Julien Lepiller <julien@lepiller.eu> writes:
> * gnu/packages/llvm.scm (cross-llvm): New variable.
Do you really need to define a cross package for LLVM? In my experience
it was possible to use the same llvm libraries for native and cross
compilation. By default LLVM builds support for all supported targets
(provided they are not "experimental" IIRC).
Whereas for the clang package, at the moment it does have to be built
for a specific target IIUC. I hope that one day we could have the same
clang for native and cross compilation in Guix, but I don't think it can
work without some serious re-design of how cross-compilation works. I've
been trying to think about it but I don't yet have a good understanding
of it.
Thanks,
Pierre
Le Fri, 04 Mar 2022 19:34:07 +0000, Pierre Langlois <pierre.langlois@gmx.com> a écrit : > Hi Julien, > > Julien Lepiller <julien@lepiller.eu> writes: > > > * gnu/packages/llvm.scm (cross-llvm): New variable. > > Do you really need to define a cross package for LLVM? In my > experience it was possible to use the same llvm libraries for native > and cross compilation. By default LLVM builds support for all > supported targets (provided they are not "experimental" IIRC). No, I don't think it's required. I only need it so I can define a default target that's different from the host. > > Whereas for the clang package, at the moment it does have to be built > for a specific target IIUC. I hope that one day we could have the same > clang for native and cross compilation in Guix, but I don't think it > can work without some serious re-design of how cross-compilation > works. I've been trying to think about it but I don't yet have a good > understanding of it. You can use --target to control which target clang builds for (although I don't know if our clang package can work like that). I wanted to have a default target though, because passing --target all the time is cumbersome and we would have to adjust all recipes to pass the flag. With the default target set appropriately, (clang-for-target) will always produce binaries for the correct architecture, whether cross-compiling or not. > > Thanks, > Pierre >
Julien Lepiller <julien@lepiller.eu> writes: > Le Fri, 04 Mar 2022 19:34:07 +0000, > Pierre Langlois <pierre.langlois@gmx.com> a écrit : > >> Hi Julien, >> >> Julien Lepiller <julien@lepiller.eu> writes: >> >> > * gnu/packages/llvm.scm (cross-llvm): New variable. >> >> Do you really need to define a cross package for LLVM? In my >> experience it was possible to use the same llvm libraries for native >> and cross compilation. By default LLVM builds support for all >> supported targets (provided they are not "experimental" IIRC). > > No, I don't think it's required. I only need it so I can define a > default target that's different from the host. > >> >> Whereas for the clang package, at the moment it does have to be built >> for a specific target IIUC. I hope that one day we could have the same >> clang for native and cross compilation in Guix, but I don't think it >> can work without some serious re-design of how cross-compilation >> works. I've been trying to think about it but I don't yet have a good >> understanding of it. > > You can use --target to control which target clang builds for (although > I don't know if our clang package can work like that). I wanted to have > a default target though, because passing --target all the time is > cumbersome and we would have to adjust all recipes to pass the flag. > With the default target set appropriately, (clang-for-target) will > always produce binaries for the correct architecture, whether > cross-compiling or not. > Ah I see, that makes sense! I suppose a possible alternative could be to define a wrapper around clang to pass the `--target=<triplet>' option by default, but that might be a bit ugly (although we already have a ld-wrapper). Thanks, Pierre
Julien Lepiller <julien@lepiller.eu> writes: > * gnu/packages/llvm.scm (cross-llvm): New variable. > --- > gnu/packages/llvm.scm | 21 +++++++++++++++++++-- > 1 file changed, 19 insertions(+), 2 deletions(-) > > diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm > index eb949bed1b..d6e9846699 100644 > --- a/gnu/packages/llvm.scm > +++ b/gnu/packages/llvm.scm > @@ -18,7 +18,7 @@ > ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net> > ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be> > ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> > -;;; Copyright © 2021 Julien Lepiller <julien@lepiller.eu> > +;;; Copyright © 2021, 2022 Julien Lepiller <julien@lepiller.eu> > ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net> > ;;; Copyright © 2021 Guillaume Le Vaillant <glv@posteo.net> > ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> > @@ -74,7 +74,8 @@ (define-module (gnu packages llvm) > #:use-module (srfi srfi-1) > #:use-module (ice-9 match) > #:export (make-lld-wrapper > - system->llvm-target)) > + system->llvm-target > + cross-llvm)) > > (define* (system->llvm-target #:optional > (system (or (and=> (%current-target-system) > @@ -99,6 +100,22 @@ (define* (system->llvm-target #:optional > ("i686" => "X86") > ("i586" => "X86")))) > > +(define (cross-llvm llvm target) > + "Return a native LLVM package that targets a different system. The resulting > +libraries are running on the host but target a different system by default. > +This packge can be used to control clang's default target." > + (package > + (inherit llvm) > + (arguments > + (substitute-keyword-arguments (package-arguments llvm) > + ((#:configure-flags flags) > + #~(append > + (list > + (string-append "-DLLVM_DEFAULT_TARGET_TRIPLE=" #$target) > + (string-append "-DLLVM_TARGET_ARCH=" > + #$(system->llvm-target (gnu-triplet->nix-system target)))) While playing with trying to use this series to build a WebAssembly cross-compiler, I /think/ we have a bug here, and also in master, when it comes to setting LLVM_TARGET_ARCH. It's a bit confusing though, the documentation is as follows: --8<---------------cut here---------------start------------->8--- LLVM_TARGET_ARCH:STRING LLVM target to use for native code generation. This is required for JIT generation. It defaults to “host”, meaning that it shall pick the architecture of the machine where LLVM is being built. If you are cross-compiling, set it to the target architecture name. --8<---------------cut here---------------end--------------->8--- It's not clear what naming scheme the variable needs, is it the internal LLVM target name or the triplet? I think it's architecture part of the triplet...ish? But instead we pass it the internal target name. It still works at the moment because whenever LLVM_TARGET_ARCH is used, the cmake code looks quite permissive and tries to do the right thing by turning the string lowercase and matching common names (hence the "...ish" :-) ). https://github.com/llvm/llvm-project/blob/24f88f57de588817bd21e799e2ac1069c025674c/llvm/cmake/config-ix.cmake#L420 So if I try and add WebAssembly into the mix, the architecure name is wasm32, but the LLVM target is called WebAssembly, and the lowercase version of it doesn't work :-( | nix-system | LLVM target | LLVM target lowercase | Does it match? | |------------+-------------+-----------------------+----------------| | aarch64 | AArch64 | aarch64 | Y | | armhf | ARM | arm | Y | | mips64el | Mips | mips | Y | | powerpc | PowerPC | powerpc | Y | | riscv | RISCV | riscv | Y | | x86_64 | X86 | x86 | Y | | i686 | X86 | x86 | Y | | i586 | X86 | x86 | Y | |------------+-------------+-----------------------+----------------| | wasm32 | WebAssembly | webassembly | N :-( | I /think/ we might want to use the nix-system instead of the LLVM target for LLVM_TARGET_ARCH: --8<---------------cut here---------------start------------->8--- (string-append "-DLLVM_TARGET_ARCH=" #$(gnu-triplet->nix-system target))) --8<---------------cut here---------------end--------------->8--- But I'm not sure, it might not work for mips64el for example, so we could need yet-another-mapping. Given it works as it is today with the current set of supported targets, we don't necessarily need to fix it now. I'll be happy to take a look later when eventually adding support for the wasm32-wasi toolchain in Guix. Thanks, Pierre
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm index eb949bed1b..d6e9846699 100644 --- a/gnu/packages/llvm.scm +++ b/gnu/packages/llvm.scm @@ -18,7 +18,7 @@ ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net> ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be> ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> -;;; Copyright © 2021 Julien Lepiller <julien@lepiller.eu> +;;; Copyright © 2021, 2022 Julien Lepiller <julien@lepiller.eu> ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net> ;;; Copyright © 2021 Guillaume Le Vaillant <glv@posteo.net> ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> @@ -74,7 +74,8 @@ (define-module (gnu packages llvm) #:use-module (srfi srfi-1) #:use-module (ice-9 match) #:export (make-lld-wrapper - system->llvm-target)) + system->llvm-target + cross-llvm)) (define* (system->llvm-target #:optional (system (or (and=> (%current-target-system) @@ -99,6 +100,22 @@ (define* (system->llvm-target #:optional ("i686" => "X86") ("i586" => "X86")))) +(define (cross-llvm llvm target) + "Return a native LLVM package that targets a different system. The resulting +libraries are running on the host but target a different system by default. +This packge can be used to control clang's default target." + (package + (inherit llvm) + (arguments + (substitute-keyword-arguments (package-arguments llvm) + ((#:configure-flags flags) + #~(append + (list + (string-append "-DLLVM_DEFAULT_TARGET_TRIPLE=" #$target) + (string-append "-DLLVM_TARGET_ARCH=" + #$(system->llvm-target (gnu-triplet->nix-system target)))) + #$flags)))))) + (define (llvm-uri component version) ;; LLVM release candidate file names are formatted 'tool-A.B.C-rcN/tool-A.B.CrcN.src.tar.xz' ;; so we specify the version as A.B.C-rcN and delete the hyphen when referencing the file name.