oom pushed a commit to branch c++-team
in repository guix.

commit 37c6d11f120ae82f063809b850c79dc6a81f6de1
Author: Greg Hogan <c...@greghogan.com>
AuthorDate: Tue Oct 22 18:08:51 2024 +0000

    build-system/cmake: Use CMake.
    
    * guix/build/cmake-build-system.scm (configure): Add and use generator
    field to configure the build system. Create and use CMake variable cache
    file. Set the CMake variable BUILD_TESTING to the value of TESTS? so
    that a package can optionally build tests. Set CMAKE_COLOR_DIAGNOSTICS
    to ON. Set max load for parallel builds.
    (build, install): New function.
    (check): Replace call to gnu-build's non-parallelizable check with
    function using cmake's ctest.
    (%standard-phase): Add new build and install functions as phases.
    
    * guix/build-system/cmake.scm (cmake-build, cmake-cross-build),
    * guix/build-system/qt.scm (qt-build, qt-cross-build): Add generator
    and test-exclude fields and remove unused test-target field.
    * doc/guix.texi: Document new parameters.
    
    * guix/build-system/cmake.scm (cmake-build),
    * guix/build-system/qt.scm (qt-build): Add ninja to build-inputs.
    
    Change-Id: Ifa8174c91f0fdc030ac5813e98f7c21cba1a7725
---
 doc/guix.texi                     |  33 ++++++++---
 guix/build-system/cmake.scm       |  16 ++++--
 guix/build-system/qt.scm          |  16 ++++--
 guix/build/cmake-build-system.scm | 113 +++++++++++++++++++++++++++++---------
 4 files changed, 135 insertions(+), 43 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 34092a2f73..591830f948 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -135,6 +135,7 @@ Copyright @copyright{} 2024-2025 Nigko Yerden@*
 Copyright @copyright{} 2024 Troy Figiel@*
 Copyright @copyright{} 2024 Sharlatan Hellseher@*
 Copyright @copyright{} 2024 45mg@*
+Copyright @copyright{} 2024 Greg Hogan@*
 Copyright @copyright{} 2025 Sören Tempel@*
 Copyright @copyright{} 2025 Rostislav Svoboda@*
 Copyright @copyright{} 2025 Zacchaeus@*
@@ -9691,16 +9692,30 @@ This variable is exported by @code{(guix build-system 
cmake)}.  It
 implements the build procedure for packages using the
 @url{https://www.cmake.org, CMake build tool}.
 
-It automatically adds the @code{cmake} package to the set of inputs.
-Which package is used can be specified with the @code{#:cmake}
-parameter.
+This build system adds the following keyword parameters to the ones
+defined by @code{gnu-build-system}:
 
-The @code{#:configure-flags} parameter is taken as a list of flags
-passed to the @command{cmake} command.  The @code{#:build-type}
-parameter specifies in abstract terms the flags passed to the compiler;
-it defaults to @code{"RelWithDebInfo"} (short for ``release mode with
-debugging information''), which roughly means that code is compiled with
-@code{-O2 -g}, as is the case for Autoconf-based packages by default.
+@table @code
+@item #:cmake
+The @code{cmake} package is added to the set of inputs. Which package
+is used can be specified with the @code{#:cmake} parameter.
+
+@item #:build-type
+The @code{#:build-type} parameter specifies in abstract terms the flags
+passed to the compiler; it defaults to @code{"RelWithDebInfo"} (short
+for ``release mode with debugging information''), which roughly means
+that code is compiled with @code{-O2 -g}, as is the case for
+Autoconf-based packages by default.
+
+@item #:generator
+This parameter specifies the
+@url{https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html, CMake 
generator}
+responsible for writing the input files for the native build system.
+
+@item #:test-exclude
+Tests matching this regular expression are excluded from testing by
+@url{https://cmake.org/cmake/help/latest/manual/ctest.1.html, ctest}.
+@end table
 @end defvar
 
 @defvar composer-build-system
diff --git a/guix/build-system/cmake.scm b/guix/build-system/cmake.scm
index 8b1889e36b..785dd17fe6 100644
--- a/guix/build-system/cmake.scm
+++ b/guix/build-system/cmake.scm
@@ -84,6 +84,10 @@
                           `(("source" ,source))
                           '())
                     ,@`(("cmake" ,cmake))
+                    ,@`(("ninja" ,(module-ref
+                                   (resolve-interface
+                                    '(gnu packages ninja))
+                                   'ninja)))
                     ,@native-inputs
                     ,@(if target '() inputs)
                     ,@(if (and target implicit-cross-inputs?)
@@ -115,9 +119,10 @@
                       (search-paths '())
                       (make-flags ''())
                       (out-of-source? #t)
+                      (generator "Unix Makefiles")
                       (build-type "RelWithDebInfo")
                       (tests? #t)
-                      (test-target "test")
+                      (test-exclude "")
                       (parallel-build? #t) (parallel-tests? #t)
                       (validate-runpath? #t)
                       (patch-shebangs? #t)
@@ -155,9 +160,10 @@ provides a 'CMakeLists.txt' file as its build system."
                                                      configure-flags)
                              #:make-flags #$make-flags
                              #:out-of-source? #$out-of-source?
+                             #:generator #$generator
                              #:build-type #$build-type
                              #:tests? #$tests?
-                             #:test-target #$test-target
+                             #:test-exclude #$test-exclude
                              #:parallel-build? #$parallel-build?
                              #:parallel-tests? #$parallel-tests?
                              #:validate-runpath? #$validate-runpath?
@@ -193,9 +199,10 @@ provides a 'CMakeLists.txt' file as its build system."
                             (native-search-paths '())
                             (make-flags ''())
                             (out-of-source? #t)
+                            (generator "Unix Makefiles")
                             (build-type "RelWithDebInfo")
                             (tests? #f) ; nothing can be done
-                            (test-target "test")
+                            (test-exclude "")
                             (parallel-build? #t) (parallel-tests? #t)
                             (validate-runpath? #t)
                             (patch-shebangs? #t)
@@ -256,9 +263,10 @@ build system."
                                                    configure-flags))
                        #:make-flags #$make-flags
                        #:out-of-source? #$out-of-source?
+                       #:generator #$generator
                        #:build-type #$build-type
                        #:tests? #$tests?
-                       #:test-target #$test-target
+                       #:test-exclude #$test-exclude
                        #:parallel-build? #$parallel-build?
                        #:parallel-tests? #$parallel-tests?
                        #:validate-runpath? #$validate-runpath?
diff --git a/guix/build-system/qt.scm b/guix/build-system/qt.scm
index d1f721c54e..ea1095a64c 100644
--- a/guix/build-system/qt.scm
+++ b/guix/build-system/qt.scm
@@ -96,6 +96,10 @@
                           `(("source" ,source))
                           '())
                     ,@`(("cmake" ,cmake))
+                    ,@`(("ninja" ,(module-ref
+                                   (resolve-interface
+                                    '(gnu packages ninja))
+                                   'ninja)))
                     ,@`(("qtbase" ,qtbase))
                     ,@native-inputs
                     ,@(if target
@@ -128,9 +132,10 @@
                    (search-paths '())
                    (make-flags ''())
                    (out-of-source? #t)
+                   (generator "Unix Makefiles")
                    (build-type "RelWithDebInfo")
                    (tests? #t)
-                   (test-target "test")
+                   (test-exclude "")
                    (parallel-build? #t) (parallel-tests? #t)
                    (validate-runpath? #t)
                    (patch-shebangs? #t)
@@ -168,9 +173,10 @@ provides a 'CMakeLists.txt' file as its build system."
                     #:configure-flags #$configure-flags
                     #:make-flags #$make-flags
                     #:out-of-source? #$out-of-source?
+                    #:generator #$generator
                     #:build-type #$build-type
                     #:tests? #$tests?
-                    #:test-target #$test-target
+                    #:test-exclude #$test-exclude
                     #:parallel-build? #$parallel-build?
                     #:parallel-tests? #$parallel-tests?
                     #:validate-runpath? #$validate-runpath?
@@ -205,9 +211,10 @@ provides a 'CMakeLists.txt' file as its build system."
                          (native-search-paths '())
                          (make-flags ''())
                          (out-of-source? #t)
+                         (generator "Unix Makefiles")
                          (build-type "RelWithDebInfo")
                          (tests? #f)              ; nothing can be done
-                         (test-target "test")
+                         (test-exclude "")
                          (parallel-build? #t) (parallel-tests? #f)
                          (validate-runpath? #t)
                          (patch-shebangs? #t)
@@ -258,9 +265,10 @@ build system."
                     #:configure-flags #$configure-flags
                     #:make-flags #$make-flags
                     #:out-of-source? #$out-of-source?
+                    #:generator #$generator
                     #:build-type #$build-type
                     #:tests? #$tests?
-                    #:test-target #$test-target
+                    #:test-exclude #$test-exclude
                     #:parallel-build? #$parallel-build?
                     #:parallel-tests? #$parallel-tests?
                     #:validate-runpath? #$validate-runpath?
diff --git a/guix/build/cmake-build-system.scm 
b/guix/build/cmake-build-system.scm
index 61033061c6..0115881931 100644
--- a/guix/build/cmake-build-system.scm
+++ b/guix/build/cmake-build-system.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2013 Cyril Roelandt <tipec...@gmail.com>
 ;;; Copyright © 2014, 2015 Andreas Enge <andr...@enge.fr>
 ;;; Copyright © 2017 Efraim Flashner <efr...@flashner.co.il>
+;;; Copyright © 2024 Greg Hogan <c...@greghogan.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -23,6 +24,8 @@
   #:use-module ((guix build gnu-build-system) #:prefix gnu:)
   #:use-module (guix build utils)
   #:use-module (ice-9 match)
+  #:use-module (ice-9 threads)
+  #:use-module (srfi srfi-34)
   #:export (%standard-phases
             cmake-build))
 
@@ -33,7 +36,7 @@
 ;; Code:
 
 (define* (configure #:key outputs (configure-flags '()) (out-of-source? #t)
-                    build-type target
+                    build-type target generator (tests? #t)
                     #:allow-other-keys)
   "Configure the given package."
   (let* ((out        (assoc-ref outputs "out"))
@@ -48,38 +51,96 @@
       (chdir "../build"))
     (format #t "build directory: ~s~%" (getcwd))
 
-    (let ((args `(,srcdir
-                  ,@(if build-type
-                        (list (string-append "-DCMAKE_BUILD_TYPE="
-                                             build-type))
-                        '())
-                  ,(string-append "-DCMAKE_INSTALL_PREFIX=" out)
-                  ;; ensure that the libraries are installed into /lib
-                  "-DCMAKE_INSTALL_LIBDIR=lib"
-                  ;; add input libraries to rpath
-                  "-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE"
-                  ;; add (other) libraries of the project itself to rpath
-                  ,(string-append "-DCMAKE_INSTALL_RPATH=" out "/lib")
-                  ;; enable verbose output from builds
-                  "-DCMAKE_VERBOSE_MAKEFILE=ON"
-                  ,@configure-flags)))
-      (format #t "running 'cmake' with arguments ~s~%" args)
-      (apply invoke "cmake" args))))
+    (call-with-temporary-output-file
+      (lambda (temp port)
+        (let ((args `(,srcdir
+                      ;; Load variables into the the cache to prevent
+                      ;; warnings about unused manually-specified variables.
+                      ,(string-append "-C " temp)
+                      ,@(if generator
+                            (list (string-append "-G" generator))
+                            '())
+                      ,@configure-flags)))
 
-(define* (check #:key (tests? #t) (parallel-tests? #t) (test-target "test")
+          (define save-to-cache
+            (lambda* (name value)
+              ;; <type> and <docstring> arguments are used only by CMake GUIs.
+              (format port "set(~a \"~a\" CACHE STRING \"\")~%" name value)))
+
+          (if build-type
+              (save-to-cache "CMAKE_BUILD_TYPE" build-type))
+          (save-to-cache "CMAKE_INSTALL_PREFIX" out)
+          ;; Ensure that the libraries are installed into /lib.
+          (save-to-cache "CMAKE_INSTALL_LIBDIR" "lib")
+          ;; Add input libraries to rpath.
+          (save-to-cache "CMAKE_INSTALL_RPATH_USE_LINK_PATH" "TRUE")
+          ;; Add (other) libraries of the project itself to rpath.
+          (save-to-cache "CMAKE_INSTALL_RPATH" (string-append out "/lib"))
+          ;; Enable verbose output from builds.
+          (save-to-cache "CMAKE_VERBOSE_MAKEFILE" "ON")
+          ;; Enable colored compiler diagnostics.
+          (save-to-cache "CMAKE_COLOR_DIAGNOSTICS" "ON")
+          ;; BUILD_TESTING in an option of CMake's CTest module.
+          (save-to-cache "BUILD_TESTING" (if tests? "ON" "OFF"))
+
+          (close-port port)
+          (format #t "running 'cmake' with arguments ~s~%" args)
+          (apply invoke "cmake" args))))))
+
+(define* (build #:key (make-flags '()) (parallel-build? #t)
                 #:allow-other-keys)
-  (let ((gnu-check (assoc-ref gnu:%standard-phases 'check)))
-    (setenv "CTEST_OUTPUT_ON_FAILURE" "1")
-    (gnu-check #:tests? tests? #:test-target test-target
-              #:parallel-tests? parallel-tests?)))
+  (apply invoke "cmake"
+         `("--build"
+           "."
+           ,@(if parallel-build?
+                 `("-j" ,(number->string (parallel-job-count)))
+                 ;; When unset CMake defers to the build system.
+                 '("-j" "1"))
+           ;; Pass the following options to the native tool.
+           "--"
+           ,@(if parallel-build?
+                 ;; Set load average limit for Make and Ninja.
+                 `("-l" ,(number->string (total-processor-count)))
+                 '())
+           ,@make-flags)))
+
+(define %test-suite-log-regexp
+  ;; Name of test suite log files as commonly found in CMake.
+  "^LastTest\\.log$")
+
+(define* (check #:key (tests? #t) (test-exclude "")
+                (parallel-tests? #t)
+                (test-suite-log-regexp %test-suite-log-regexp)
+                #:allow-other-keys)
+  (if tests?
+      (guard (c ((invoke-error? c)
+                 ;; Dump the test suite log to facilitate debugging.
+                 (display "\nTest suite failed, dumping logs.\n"
+                          (current-error-port))
+                 (gnu:dump-file-contents "." test-suite-log-regexp)
+                 (raise c)))
+        (apply invoke "ctest" "--output-on-failure" "--no-tests=error"
+               `(,@(if (string-null? test-exclude)
+                       '()
+                       `("--exclude-regex" ,test-exclude))
+                 ,@(if parallel-tests?
+                       `("-j" ,(number->string (parallel-job-count))
+                         "--test-load"
+                         ,(number->string (total-processor-count)))
+                       ;; When unset CMake defers to the build system.
+                       '("-j" "1")))))
+      (format #t "test suite not run~%")))
+
+(define* (install #:rest args)
+  (invoke "cmake" "--install" "."))
 
 (define %standard-phases
-  ;; Everything is as with the GNU Build System except for the `configure'
-  ;; and 'check' phases.
   (modify-phases gnu:%standard-phases
     (delete 'bootstrap)
+    (replace 'build build)
     (replace 'check check)
-    (replace 'configure configure)))
+    (replace 'configure configure)
+    (replace 'install install)))
 
 (define* (cmake-build #:key inputs (phases %standard-phases)
                       #:allow-other-keys #:rest args)

Reply via email to