* bug#27076: [PATCH] build-system/cmake: Add support for cross compilation.
2017-05-25 21:05 bug#27076: Cross-build support for cmake-build-system Ricardo Wurmus
@ 2017-05-25 21:16 ` Ricardo Wurmus
2017-05-25 21:26 ` Ricardo Wurmus
1 sibling, 0 replies; 7+ messages in thread
From: Ricardo Wurmus @ 2017-05-25 21:16 UTC (permalink / raw)
To: 27076; +Cc: Ricardo Wurmus
* guix/build-system/gnu.scm: Export standard-cross-packages.
* guix/build-system/cmake.scm (cmake-cross-build): New procedure.
(lower): Add support for cross-builds.
* guix/build/cmake-build-system.scm (configure): Handle "target" argument.
---
guix/build-system/cmake.scm | 158 +++++++++++++++++++++++++++++++++-----
guix/build-system/gnu.scm | 1 +
guix/build/cmake-build-system.scm | 11 ++-
3 files changed, 151 insertions(+), 19 deletions(-)
diff --git a/guix/build-system/cmake.scm b/guix/build-system/cmake.scm
index 25ac262d5..6d1bfc898 100644
--- a/guix/build-system/cmake.scm
+++ b/guix/build-system/cmake.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com>
+;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -56,24 +57,36 @@
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:source #:target #:cmake #:inputs #:native-inputs))
-
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs
-
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (build-inputs `(("cmake" ,cmake)
- ,@native-inputs))
- (outputs outputs)
- (build cmake-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ `(#:source #:cmake #:inputs #:native-inputs #:outputs
+ ,@(if target '() '(#:target))))
+
+ (bag
+ (name name)
+ (system system)
+ (target target)
+ (build-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+ ,@`(("cmake" ,cmake))
+ ,@native-inputs
+ ,@(if target
+ ;; Use the standard cross inputs of
+ ;; 'gnu-build-system'.
+ (standard-cross-packages target 'host)
+ '())
+ ;; Keep the standard inputs of 'gnu-build-system'.
+ ,@(standard-packages)))
+ (host-inputs inputs)
+
+ ;; The cross-libc is really a target package, but for bootstrapping
+ ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
+ ;; native package, so it would end up using a "native" variant of
+ ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
+ ;; would use a target variant (built with 'gnu-cross-build'.)
+ (target-inputs (standard-cross-packages target 'target))
+ (outputs outputs)
+ (build (if target cmake-cross-build cmake-build))
+ (arguments (strip-keyword-arguments private-keywords arguments))))
(define* (cmake-build store name inputs
#:key (guile #f)
@@ -145,6 +158,115 @@ provides a 'CMakeLists.txt' file as its build system."
#:outputs outputs
#:guile-for-build guile-for-build))
+\f
+;;;
+;;; Cross-compilation.
+;;;
+
+(define* (cmake-cross-build store name
+ #:key
+ target native-drvs target-drvs
+ (guile #f)
+ (outputs '("out"))
+ (configure-flags ''())
+ (search-paths '())
+ (native-search-paths '())
+ (make-flags ''())
+ (out-of-source? #t)
+ (build-type "RelWithDebInfo")
+ (tests? #f) ; nothing can be done
+ (test-target "test")
+ (parallel-build? #t) (parallel-tests? #f)
+ (validate-runpath? #t)
+ (patch-shebangs? #t)
+ (strip-binaries? #t)
+ (strip-flags ''("--strip-debug"
+ "--enable-deterministic-archives"))
+ (strip-directories ''("lib" "lib64" "libexec"
+ "bin" "sbin"))
+ (phases '(@ (guix build cmake-build-system)
+ %standard-phases))
+ (system (%current-system))
+ (build (nix-system->gnu-triplet system))
+ (imported-modules %cmake-build-system-modules)
+ (modules '((guix build cmake-build-system)
+ (guix build utils))))
+ "Cross-build NAME using CMAKE for TARGET, where TARGET is a GNU triplet and
+with INPUTS. This assumes that SOURCE provides a 'CMakeLists.txt' file as its
+build system."
+ (define builder
+ `(begin
+ (use-modules ,@modules)
+ (let ()
+ (define %build-host-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name path)
+ `(,name . ,path)))
+ native-drvs))
+
+ (define %build-target-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name (? package? pkg) sub ...)
+ (let ((drv (package-cross-derivation store pkg
+ target system)))
+ `(,name . ,(apply derivation->output-path drv sub))))
+ ((name path)
+ `(,name . ,path)))
+ target-drvs))
+
+ (cmake-build #:source ,(match (assoc-ref native-drvs "source")
+ (((? derivation? source))
+ (derivation->output-path source))
+ ((source)
+ source)
+ (source
+ source))
+ #:system ,system
+ #:build ,build
+ #:target ,target
+ #:outputs %outputs
+ #:inputs %build-target-inputs
+ #:native-inputs %build-host-inputs
+ #:search-paths ',(map search-path-specification->sexp
+ search-paths)
+ #:native-search-paths ',(map
+ search-path-specification->sexp
+ native-search-paths)
+ #:phases ,phases
+ #:configure-flags ,configure-flags
+ #:make-flags ,make-flags
+ #:out-of-source? ,out-of-source?
+ #:build-type ,build-type
+ #:tests? ,tests?
+ #:test-target ,test-target
+ #:parallel-build? ,parallel-build?
+ #:parallel-tests? ,parallel-tests?
+ #:validate-runpath? ,validate-runpath?
+ #:patch-shebangs? ,patch-shebangs?
+ #:strip-binaries? ,strip-binaries?
+ #:strip-flags ,strip-flags
+ #:strip-directories ,strip-directories))))
+
+ (define guile-for-build
+ (match guile
+ ((? package?)
+ (package-derivation store guile system #:graft? #f))
+ (#f ; the default
+ (let* ((distro (resolve-interface '(gnu packages commencement)))
+ (guile (module-ref distro 'guile-final)))
+ (package-derivation store guile system #:graft? #f)))))
+
+ (build-expression->derivation store name builder
+ #:system system
+ #:inputs (append native-drvs target-drvs)
+ #:outputs outputs
+ #:modules imported-modules
+ #:guile-for-build guile-for-build))
+
(define cmake-build-system
(build-system
(name 'cmake)
diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm
index 7cf0cafc0..047ace7e6 100644
--- a/guix/build-system/gnu.scm
+++ b/guix/build-system/gnu.scm
@@ -30,6 +30,7 @@
gnu-build
gnu-build-system
standard-packages
+ standard-cross-packages
package-with-explicit-inputs
package-with-extra-configure-variable
static-libgcc-package
diff --git a/guix/build/cmake-build-system.scm b/guix/build/cmake-build-system.scm
index 27f2b5c87..b5a3ff2ab 100644
--- a/guix/build/cmake-build-system.scm
+++ b/guix/build/cmake-build-system.scm
@@ -32,7 +32,7 @@
;; Code:
(define* (configure #:key outputs (configure-flags '()) (out-of-source? #t)
- build-type
+ build-type target
#:allow-other-keys)
"Configure the given package."
(let* ((out (assoc-ref outputs "out"))
@@ -59,6 +59,15 @@
,(string-append "-DCMAKE_INSTALL_RPATH=" out "/lib")
;; enable verbose output from builds
"-DCMAKE_VERBOSE_MAKEFILE=ON"
+
+ ;; Cross-build
+ ,@(if target
+ (list (string-append "-DCMAKE_C_COMPILER="
+ target "-gcc")
+ ;; XXX: Use "Windows" when this is a cross-build
+ ;; for Windows.
+ "-DCMAKE_SYSTEM_NAME=Linux")
+ '())
,@configure-flags)))
(format #t "running 'cmake' with arguments ~s~%" args)
(zero? (apply system* "cmake" args)))))
--
2.12.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* bug#27076: [PATCH] build-system/cmake: Add support for cross compilation.
2017-05-25 21:05 bug#27076: Cross-build support for cmake-build-system Ricardo Wurmus
2017-05-25 21:16 ` bug#27076: [PATCH] build-system/cmake: Add support for cross compilation Ricardo Wurmus
@ 2017-05-25 21:26 ` Ricardo Wurmus
2017-05-26 8:21 ` Ricardo Wurmus
2017-05-28 19:57 ` Ludovic Courtès
1 sibling, 2 replies; 7+ messages in thread
From: Ricardo Wurmus @ 2017-05-25 21:26 UTC (permalink / raw)
To: 27076; +Cc: Ricardo Wurmus
* guix/build-system/gnu.scm: Export standard-cross-packages.
* guix/build-system/cmake.scm (cmake-cross-build): New procedure.
(lower): Add support for cross-builds.
* guix/build/cmake-build-system.scm (configure): Handle "target" argument.
---
guix/build-system/cmake.scm | 160 +++++++++++++++++++++++++++++++++-----
guix/build-system/gnu.scm | 1 +
guix/build/cmake-build-system.scm | 11 ++-
3 files changed, 153 insertions(+), 19 deletions(-)
diff --git a/guix/build-system/cmake.scm b/guix/build-system/cmake.scm
index 25ac262d5..ee116c5a4 100644
--- a/guix/build-system/cmake.scm
+++ b/guix/build-system/cmake.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com>
+;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -56,24 +57,38 @@
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:source #:target #:cmake #:inputs #:native-inputs))
-
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs
-
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (build-inputs `(("cmake" ,cmake)
- ,@native-inputs))
- (outputs outputs)
- (build cmake-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ `(#:source #:cmake #:inputs #:native-inputs #:outputs
+ ,@(if target '() '(#:target))))
+
+ (bag
+ (name name)
+ (system system)
+ (target target)
+ (build-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+ ,@`(("cmake" ,cmake))
+ ,@native-inputs
+ ,@(if target
+ ;; Use the standard cross inputs of
+ ;; 'gnu-build-system'.
+ (standard-cross-packages target 'host)
+ '())
+ ;; Keep the standard inputs of 'gnu-build-system'.
+ ,@(standard-packages)))
+ (host-inputs inputs)
+
+ ;; The cross-libc is really a target package, but for bootstrapping
+ ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
+ ;; native package, so it would end up using a "native" variant of
+ ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
+ ;; would use a target variant (built with 'gnu-cross-build'.)
+ (target-inputs (if target
+ (standard-cross-packages target 'target)
+ '()))
+ (outputs outputs)
+ (build (if target cmake-cross-build cmake-build))
+ (arguments (strip-keyword-arguments private-keywords arguments))))
(define* (cmake-build store name inputs
#:key (guile #f)
@@ -145,6 +160,115 @@ provides a 'CMakeLists.txt' file as its build system."
#:outputs outputs
#:guile-for-build guile-for-build))
+\f
+;;;
+;;; Cross-compilation.
+;;;
+
+(define* (cmake-cross-build store name
+ #:key
+ target native-drvs target-drvs
+ (guile #f)
+ (outputs '("out"))
+ (configure-flags ''())
+ (search-paths '())
+ (native-search-paths '())
+ (make-flags ''())
+ (out-of-source? #t)
+ (build-type "RelWithDebInfo")
+ (tests? #f) ; nothing can be done
+ (test-target "test")
+ (parallel-build? #t) (parallel-tests? #f)
+ (validate-runpath? #t)
+ (patch-shebangs? #t)
+ (strip-binaries? #t)
+ (strip-flags ''("--strip-debug"
+ "--enable-deterministic-archives"))
+ (strip-directories ''("lib" "lib64" "libexec"
+ "bin" "sbin"))
+ (phases '(@ (guix build cmake-build-system)
+ %standard-phases))
+ (system (%current-system))
+ (build (nix-system->gnu-triplet system))
+ (imported-modules %cmake-build-system-modules)
+ (modules '((guix build cmake-build-system)
+ (guix build utils))))
+ "Cross-build NAME using CMAKE for TARGET, where TARGET is a GNU triplet and
+with INPUTS. This assumes that SOURCE provides a 'CMakeLists.txt' file as its
+build system."
+ (define builder
+ `(begin
+ (use-modules ,@modules)
+ (let ()
+ (define %build-host-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name path)
+ `(,name . ,path)))
+ native-drvs))
+
+ (define %build-target-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name (? package? pkg) sub ...)
+ (let ((drv (package-cross-derivation store pkg
+ target system)))
+ `(,name . ,(apply derivation->output-path drv sub))))
+ ((name path)
+ `(,name . ,path)))
+ target-drvs))
+
+ (cmake-build #:source ,(match (assoc-ref native-drvs "source")
+ (((? derivation? source))
+ (derivation->output-path source))
+ ((source)
+ source)
+ (source
+ source))
+ #:system ,system
+ #:build ,build
+ #:target ,target
+ #:outputs %outputs
+ #:inputs %build-target-inputs
+ #:native-inputs %build-host-inputs
+ #:search-paths ',(map search-path-specification->sexp
+ search-paths)
+ #:native-search-paths ',(map
+ search-path-specification->sexp
+ native-search-paths)
+ #:phases ,phases
+ #:configure-flags ,configure-flags
+ #:make-flags ,make-flags
+ #:out-of-source? ,out-of-source?
+ #:build-type ,build-type
+ #:tests? ,tests?
+ #:test-target ,test-target
+ #:parallel-build? ,parallel-build?
+ #:parallel-tests? ,parallel-tests?
+ #:validate-runpath? ,validate-runpath?
+ #:patch-shebangs? ,patch-shebangs?
+ #:strip-binaries? ,strip-binaries?
+ #:strip-flags ,strip-flags
+ #:strip-directories ,strip-directories))))
+
+ (define guile-for-build
+ (match guile
+ ((? package?)
+ (package-derivation store guile system #:graft? #f))
+ (#f ; the default
+ (let* ((distro (resolve-interface '(gnu packages commencement)))
+ (guile (module-ref distro 'guile-final)))
+ (package-derivation store guile system #:graft? #f)))))
+
+ (build-expression->derivation store name builder
+ #:system system
+ #:inputs (append native-drvs target-drvs)
+ #:outputs outputs
+ #:modules imported-modules
+ #:guile-for-build guile-for-build))
+
(define cmake-build-system
(build-system
(name 'cmake)
diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm
index 7cf0cafc0..047ace7e6 100644
--- a/guix/build-system/gnu.scm
+++ b/guix/build-system/gnu.scm
@@ -30,6 +30,7 @@
gnu-build
gnu-build-system
standard-packages
+ standard-cross-packages
package-with-explicit-inputs
package-with-extra-configure-variable
static-libgcc-package
diff --git a/guix/build/cmake-build-system.scm b/guix/build/cmake-build-system.scm
index 27f2b5c87..b5a3ff2ab 100644
--- a/guix/build/cmake-build-system.scm
+++ b/guix/build/cmake-build-system.scm
@@ -32,7 +32,7 @@
;; Code:
(define* (configure #:key outputs (configure-flags '()) (out-of-source? #t)
- build-type
+ build-type target
#:allow-other-keys)
"Configure the given package."
(let* ((out (assoc-ref outputs "out"))
@@ -59,6 +59,15 @@
,(string-append "-DCMAKE_INSTALL_RPATH=" out "/lib")
;; enable verbose output from builds
"-DCMAKE_VERBOSE_MAKEFILE=ON"
+
+ ;; Cross-build
+ ,@(if target
+ (list (string-append "-DCMAKE_C_COMPILER="
+ target "-gcc")
+ ;; XXX: Use "Windows" when this is a cross-build
+ ;; for Windows.
+ "-DCMAKE_SYSTEM_NAME=Linux")
+ '())
,@configure-flags)))
(format #t "running 'cmake' with arguments ~s~%" args)
(zero? (apply system* "cmake" args)))))
--
2.12.2
^ permalink raw reply related [flat|nested] 7+ messages in thread