diff mbox series

[bug#60934,v2,1/2] gnu: Add llvm-for-mesa.

Message ID 37a43bcd770f26694343af3ae0534208dc052055.1674136307.git.efraim@flashner.co.il
State New
Headers show
Series llvm-for-mesa patch | expand

Commit Message

Efraim Flashner Jan. 19, 2023, 1:56 p.m. UTC
* gnu/packages/llvm.scm (llvm-for-mesa): New variable.
---
 gnu/packages/llvm.scm | 49 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

Comments

Ludovic Courtès Jan. 23, 2023, 10:35 a.m. UTC | #1
Hello!

Efraim Flashner <efraim@flashner.co.il> skribis:

> * gnu/packages/llvm.scm (llvm-for-mesa): New variable.

Yay for reduced closures!!

> +(define-public llvm-for-mesa

Maybe add a line saying that this is a slim variant specifically
tailored for Mesa, that takes X% of the size of the default LLVM.

> +  ;; Note: update the 'clang' input of mesa-opencl when bumping this.
> +  (let ((base-llvm llvm-15))
> +    (package
> +      (inherit base-llvm)

Add (name "llvm-for-mesa") ?

> +      (arguments
> +       (substitute-keyword-arguments (package-arguments base-llvm)
> +         ((#:modules modules '((guix build cmake-build-system)
> +                               (guix build utils)))
> +          `((ice-9 regex)
> +            (srfi srfi-1)
> +            (srfi srfi-26)
> +            ,@modules))
> +         ((#:configure-flags cf ''())
> +          #~(cons*
> +              ;; AMDGPU is needed by the vulkan drivers.
> +              #$(string-append "-DLLVM_TARGETS_TO_BUILD="
> +                               (system->llvm-target) ";AMDGPU")

So the result is two build only two backends, for example x86_64 and
AMDGPU, right?

> +         ((#:phases phases '%standard-phases)
> +          #~(modify-phases #$phases
> +              (add-after 'install 'delete-static-libraries
> +                ;; If these are just relocated then llvm-config can't find them.
> +                (lambda* (#:key outputs #:allow-other-keys)
> +                  (for-each delete-file
> +                            (find-files (string-append
> +                                          (assoc-ref outputs "out") "/lib")
> +                                        "\\.a$"))))

Should we pass -DDISABLE_STATIC=ON or whatever it’s called instead?

> +              (add-after 'install 'build-and-install-llvm-config
> +                (lambda* (#:key outputs #:allow-other-keys)

Why do we need this extra phase compared to ‘llvm’?  Please add a
comment.  :-)

> +                  (let ((out (assoc-ref outputs "out")))
> +                    (substitute*
> +                      "tools/llvm-config/CMakeFiles/llvm-config.dir/link.txt"
> +                      (((string-append "/tmp/guix-build-llvm-"
> +                                       #$(package-version base-llvm)
> +                                       ".drv-0/build/lib"))
> +                       (string-append out "/lib")))

The non-literal pattern here, and that it explicitly refers to the build
directory, is not great.

I believe you can use (string-append (getcwd) "/lib") as the pattern,
fixing the second problem.  Not sure about the first one.

Thank you!

Ludo’.
Efraim Flashner Jan. 23, 2023, 11:57 a.m. UTC | #2
On Mon, Jan 23, 2023 at 11:35:44AM +0100, Ludovic Courtès wrote:
> Hello!
> 
> Efraim Flashner <efraim@flashner.co.il> skribis:
> 
> > * gnu/packages/llvm.scm (llvm-for-mesa): New variable.
> 
> Yay for reduced closures!!
> 
> > +(define-public llvm-for-mesa
> 
> Maybe add a line saying that this is a slim variant specifically
> tailored for Mesa, that takes X% of the size of the default LLVM.

Will do.

> > +  ;; Note: update the 'clang' input of mesa-opencl when bumping this.
> > +  (let ((base-llvm llvm-15))
> > +    (package
> > +      (inherit base-llvm)
> 
> Add (name "llvm-for-mesa") ?

I don't have a strong preference. By leaving it as 'llvm' we make it
more easily substitutable by any other build of llvm since they'd have
the same name length. Having it as 'llvm-for-mesa' makes it really clear
what it is.

> > +      (arguments
> > +       (substitute-keyword-arguments (package-arguments base-llvm)
> > +         ((#:modules modules '((guix build cmake-build-system)
> > +                               (guix build utils)))
> > +          `((ice-9 regex)
> > +            (srfi srfi-1)
> > +            (srfi srfi-26)
> > +            ,@modules))
> > +         ((#:configure-flags cf ''())
> > +          #~(cons*
> > +              ;; AMDGPU is needed by the vulkan drivers.
> > +              #$(string-append "-DLLVM_TARGETS_TO_BUILD="
> > +                               (system->llvm-target) ";AMDGPU")
> 
> So the result is two build only two backends, for example x86_64 and
> AMDGPU, right?

That's right. I tried with just (system->llvm-target) but AMDGPU was
needed for the vulkan drivers.

> > +         ((#:phases phases '%standard-phases)
> > +          #~(modify-phases #$phases
> > +              (add-after 'install 'delete-static-libraries
> > +                ;; If these are just relocated then llvm-config can't find them.
> > +                (lambda* (#:key outputs #:allow-other-keys)
> > +                  (for-each delete-file
> > +                            (find-files (string-append
> > +                                          (assoc-ref outputs "out") "/lib")
> > +                                        "\\.a$"))))
> 
> Should we pass -DDISABLE_STATIC=ON or whatever it’s called instead?

It turns out that static is the default, and we override it in most of
the llvm packages to build shared libraries instead. If we disable the
static ones too then it errors out and says it has nothing to build.

> > +              (add-after 'install 'build-and-install-llvm-config
> > +                (lambda* (#:key outputs #:allow-other-keys)
> 
> Why do we need this extra phase compared to ‘llvm’?  Please add a
> comment.  :-)

Fair enough :) It turns out that *everyone* expects llvm-config to
exist, and doing it this way allows us to only build llvm-config, not
all the tools/utilities.

> > +                  (let ((out (assoc-ref outputs "out")))
> > +                    (substitute*
> > +                      "tools/llvm-config/CMakeFiles/llvm-config.dir/link.txt"
> > +                      (((string-append "/tmp/guix-build-llvm-"
> > +                                       #$(package-version base-llvm)
> > +                                       ".drv-0/build/lib"))
> > +                       (string-append out "/lib")))
> 
> The non-literal pattern here, and that it explicitly refers to the build
> directory, is not great.
> 
> I believe you can use (string-append (getcwd) "/lib") as the pattern,
> fixing the second problem.  Not sure about the first one.

I suppose it would be (string-append (getcwd) "/bin/lib") to fix both. I
wasn't able to find a good way to get llvm-config to be configured
correctly by the build system without also having it install all the
utilities. When I looked in the build directory after a RUNPATH failure
it had that directory as the one to link to for the libraries.

> Thank you!

This one's been bothering everyone for years :)
Efraim Flashner Jan. 30, 2023, 6:12 p.m. UTC | #3
master merged into core-updates and this patch pushed!
diff mbox series

Patch

diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 58bd91d7be..8379b23fa5 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -2070,6 +2070,55 @@  (define-public emacs-clang-rename
 ;;; LLVM variants.
 ;;;
 
+(define-public llvm-for-mesa
+  ;; Note: update the 'clang' input of mesa-opencl when bumping this.
+  (let ((base-llvm llvm-15))
+    (package
+      (inherit base-llvm)
+      (arguments
+       (substitute-keyword-arguments (package-arguments base-llvm)
+         ((#:modules modules '((guix build cmake-build-system)
+                               (guix build utils)))
+          `((ice-9 regex)
+            (srfi srfi-1)
+            (srfi srfi-26)
+            ,@modules))
+         ((#:configure-flags cf ''())
+          #~(cons*
+              ;; AMDGPU is needed by the vulkan drivers.
+              #$(string-append "-DLLVM_TARGETS_TO_BUILD="
+                               (system->llvm-target) ";AMDGPU")
+              ;; Tools and utils decrease the output by ~100 MiB.
+              "-DLLVM_BUILD_TOOLS=NO"
+              (remove (cut string-match
+                           "-DLLVM_(TARGETS_TO_BUILD|INSTALL_UTILS).*" <>)
+                      #$cf)))
+         ((#:phases phases '%standard-phases)
+          #~(modify-phases #$phases
+              (add-after 'install 'delete-static-libraries
+                ;; If these are just relocated then llvm-config can't find them.
+                (lambda* (#:key outputs #:allow-other-keys)
+                  (for-each delete-file
+                            (find-files (string-append
+                                          (assoc-ref outputs "out") "/lib")
+                                        "\\.a$"))))
+              (add-after 'install 'build-and-install-llvm-config
+                (lambda* (#:key outputs #:allow-other-keys)
+                  (let ((out (assoc-ref outputs "out")))
+                    (substitute*
+                      "tools/llvm-config/CMakeFiles/llvm-config.dir/link.txt"
+                      (((string-append "/tmp/guix-build-llvm-"
+                                       #$(package-version base-llvm)
+                                       ".drv-0/build/lib"))
+                       (string-append out "/lib")))
+                    (invoke "make" "llvm-config")
+                    (install-file "bin/llvm-config"
+                                  (string-append out "/bin")))))))))
+      ;; We don't override the name so we hide it so we don't have package
+      ;; ambiguities from the CLI.
+      (properties `((hidden? . #t)
+                    ,@(package-properties base-llvm))))))
+
 (define make-ocaml-llvm
   ;; Make it a memoizing procedure so its callers below don't end up defining
   ;; two equal-but-not-eq "ocaml-llvm" packages for the default LLVM.