From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id xRPlHGnWzGBCZQAAgWs5BA (envelope-from ) for ; Fri, 18 Jun 2021 19:22:49 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id UGISGGnWzGC5dQAAB5/wlQ (envelope-from ) for ; Fri, 18 Jun 2021 17:22:49 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id B97581DDA6 for ; Fri, 18 Jun 2021 19:22:48 +0200 (CEST) Received: from localhost ([::1]:55922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luICd-0003zd-Nh for larch@yhetil.org; Fri, 18 Jun 2021 13:22:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37838) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luIAF-0008DW-F9 for guix-patches@gnu.org; Fri, 18 Jun 2021 13:20:19 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:46576) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luIAF-0004ME-6S for guix-patches@gnu.org; Fri, 18 Jun 2021 13:20:19 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1luIAF-0004vo-3J for guix-patches@gnu.org; Fri, 18 Jun 2021 13:20:19 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#49025] [PATCH v3 core-updates 37/37] meson: Support cross-compilation. Resent-From: Maxime Devos Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 18 Jun 2021 17:20:19 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 49025 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 49025@debbugs.gnu.org Cc: othacehe@gnu.org, Maxime Devos Received: via spool by 49025-submit@debbugs.gnu.org id=B49025.162403679718663 (code B ref 49025); Fri, 18 Jun 2021 17:20:19 +0000 Received: (at 49025) by debbugs.gnu.org; 18 Jun 2021 17:19:57 +0000 Received: from localhost ([127.0.0.1]:58084 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1luI9s-0004qq-QG for submit@debbugs.gnu.org; Fri, 18 Jun 2021 13:19:57 -0400 Received: from andre.telenet-ops.be ([195.130.132.53]:34838) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1luI9I-0004j5-9n for 49025@debbugs.gnu.org; Fri, 18 Jun 2021 13:19:21 -0400 Received: from localhost.localdomain ([213.119.219.214]) by andre.telenet-ops.be with bizsmtp id JhK5250094e8Tal01hKKem; Fri, 18 Jun 2021 19:19:20 +0200 From: Maxime Devos Date: Fri, 18 Jun 2021 19:16:31 +0200 Message-Id: <20210618171631.20534-37-maximedevos@telenet.be> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210618171631.20534-1-maximedevos@telenet.be> References: <20210618171631.20534-1-maximedevos@telenet.be> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telenet.be; s=r21; t=1624036760; bh=9QgLcPXJWK9iabqmcx9sqfvov3avBGvRjKPIpMrusAg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:Reply-To; b=M3kPZfuq1nBYyL4Ag+XwuaJ1RRIuDH/WAYpXTOV5bj2Ewzte0gvVxgWxzJADj8OWt /hNGIcNW/g/qBp6trAgmaZKwjJsZK5En8bYI0PKk39hUkpDf1BpqKPYGbboACXBCi5 6k01HSmGrR0vD0bfchhxy6kyUKJKCD92fxdif8zA43PbW3S7q8M/nMOWpM0SKnpUNE d0bWulh0ZZNKQbALeB9Za26yLMvQN6GLcmA+veB5SmTJJ8bPBRcbERqM+xZd44eBey J+809uZZQPD2mkGLKiZDAqbBDAiZCT8JqL38y1SLoLYo6RWUSvo8tVkGvvjzDae5WG gxDRblpunsuAg== X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: 49025@debbugs.gnu.org Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1624036969; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=9QgLcPXJWK9iabqmcx9sqfvov3avBGvRjKPIpMrusAg=; b=RxoLTpJN6cB8sJsCjn73SbXSFOd92vtv78+QEczQBE+ijncDIK/FhLi7hNucudeyFh12xq ei070BzCcElw0fe24WPBirs4lnMwlqhcI+e//DOWKlaPAnpepTsNd/4vAdhWBXiy0logab rE/yXyZaREn+1aAteMCMWkyAm2qeRPG5CS17UJP0q3eMGnwx/jDM0aZnwz4yjbsUMJlX5/ kmRD52hztHO52ZmjYC7zH95xhqILZx9iiuzw31y8GPiS0NoZrmLn1DgG6c/VRPtJn20tx7 811l9Bm+v1UOoSdgoJFhmuA2+/40OacTUZF4XaKTbQL8TcUDUH+6yyBwpp5DzA== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1624036969; a=rsa-sha256; cv=none; b=QsAlyd6vuPX16TZRG70og1pGWqpvdyhzA+tTgbWTDb0lHVOol7rbGTi5U2z9W3p4Ej/1ml V4kg82UAJn6l7sSdEAJZKJ1tjP70HTd1mpNADCm2bIKzP3cb3IRJkGX4kKxs/8S9eO/WZL CUcZnLstI4+T/HWXciiTP68FOzBimSTYsMu9vbFs/Xaif6RmD9szf8kwuTQ3hex+pk78Wd Sd++r67ZZoh1wvHHcr8/V+xI3LJBmyU5B7UK88+blVwG5TLvLlHNPVjpM58wtztGo8bmAL VeL+miMsbQF+ufdVrpeMFot2PFk/kqnyUfCctuWBHMVyRyPiTXkgv3XstSIe1A== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=telenet.be header.s=r21 header.b=M3kPZfuq; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Spam-Score: 1.17 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=telenet.be header.s=r21 header.b=M3kPZfuq; dmarc=fail reason="SPF not aligned (relaxed)" header.from=telenet.be (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Queue-Id: B97581DDA6 X-Spam-Score: 1.17 X-Migadu-Scanner: scn0.migadu.com X-TUID: jV9oYkZGNWca For cross-compilation, meson needs to be passed a ‘cross file’ with information on the architecture, CPU type, endianness and operating system, and the name of the cross-compiler binaries. The new module (guix build meson-configuration) has some utilities for writing these cross files, used by 'make-cross-file' in a G-exp. The values for the cross file are generated by 'make-machine-alist' and 'make-binaries-alist'. 'make-machine-alist' and 'make-binaries-alist' live on the host side, such that new architectures and operating systems can be added without causing rebuilds for old architectures. Currently, only GNU/Hurd, GNU/Linux, MinGW, x86-32 and x86-64 are supported by 'make-machine-alist'. For other architectures, someone needs to figure out what to use as ‘CPU type’ first. Only i686-linux-gnu has been tested. This has been tested with: $ ./pre-inst-env guix build glib --target=i686-linux-gnu on a x86_64-linux system. ‘If it compiles, it should work.’ * guix/build/meson-configuration.scm (configuration-port): New parameter. (write-section-header): New procedure. (write-assignment): New procedure. (write-assignments): New procedure. * guix/build-system/meson.scm (target-hurd?): New predicate. (make-machine-alist): New procedure. (make-binaries-alist): New procedure. (make-cross-file): New procedure. (meson-cross-build): New procedure. (lower)[build-inputs]: Add standard cross packages when cross-compiling. Do not include regular 'inputs' when cross-compiling. (lower)[host-inputs]: Include 'inputs' when cross-compiling. (lower)[target-inputs]: Add cross packages when cross-compiling. (lower)[build]: Call 'meson-cross-build' instead of 'cross-build' when cross-compiling. (lower)[target]: Set it. (lower)[private-keywords]: Do not remove #:target when cross-compiling. --- Makefile.am | 1 + guix/build-system/meson.scm | 197 ++++++++++++++++++++++++++--- guix/build/meson-configuration.scm | 71 +++++++++++ 3 files changed, 250 insertions(+), 19 deletions(-) create mode 100644 guix/build/meson-configuration.scm diff --git a/Makefile.am b/Makefile.am index a10e06e5a7..d4bf626fd5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -234,6 +234,7 @@ MODULES = \ guix/build/emacs-utils.scm \ guix/build/java-utils.scm \ guix/build/lisp-utils.scm \ + guix/build/meson-configuration.scm \ guix/build/maven/java.scm \ guix/build/maven/plugin.scm \ guix/build/maven/pom.scm \ diff --git a/guix/build-system/meson.scm b/guix/build-system/meson.scm index 5adc0f92c8..1f763af2aa 100644 --- a/guix/build-system/meson.scm +++ b/guix/build-system/meson.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2017 Peter Mikkelsen ;;; Copyright © 2018, 2019 Marius Bakke ;;; Copyright © 2021 Ludovic Courtès +;;; Copyright © 2021 Maxime Devos ;;; ;;; This file is part of GNU Guix. ;;; @@ -30,7 +31,8 @@ #:use-module (guix packages) #:use-module (ice-9 match) #:export (%meson-build-system-modules - meson-build-system)) + meson-build-system + make-cross-file)) ;; Commentary: ;; @@ -40,6 +42,62 @@ ;; ;; Code: +(define (target-hurd? triplet) + (and (string-suffix? "-gnu" triplet) + (not (string-contains triplet "linux")))) + +(define (make-machine-alist triplet) + "Make an association list describing what should go into +the ‘host_machine’ section of the cross file when cross-compiling +for TRIPLET." + `((system . ,(cond ((target-hurd? triplet) "gnu") + ((target-linux? triplet) "linux") + ((target-mingw? triplet) "windows") + (#t (error "meson: unknown operating system")))) + (cpu_family . ,(cond ((target-x86-32? triplet) "x86") + ((target-x86-64? triplet) "x86_64") + ((target-arm32? triplet) "arm") + ((target-aarch64? triplet) "aarch64") + ((target-powerpc? triplet) + (if (target-64bit? triplet) + "ppc64" + "ppc")) + (#t (error "meson: unknown architecture")))) + (cpu . ,(cond ((target-x86-32? triplet) ; i386, ..., i686 + (substring triplet 0 4)) + ((target-x86-64? triplet) "x86_64") + (#t (error "meson: unknown CPU")))) + (endian . ,(cond ((string-prefix? "powerpc64le-" triplet) "little") + ((string-prefix? "mips64el-" triplet) "little") + ((target-x86-32? triplet) "little") + ((target-x86-64? triplet) "little") + (#t (error "meson: unknown architecture")))))) + +(define (make-binaries-alist triplet) + "Make an associatoin list describing what should go into +the ‘binaries’ section of the cross file when cross-compiling for +TRIPLET." + `((c . ,(cc-for-target triplet)) + (cpp . ,(cxx-for-target triplet)) + (pkgconfig . ,(pkg-config-for-target triplet)) + (objcopy . ,(string-append triplet "-objcopy")) + (ar . ,(string-append triplet "-ar")) + (ld . ,(string-append triplet "-ld")) + (strip . ,(string-append triplet "-strip")))) + +(define (make-cross-file triplet) + (computed-file "cross-file" + (with-imported-modules '((guix build meson-configuration)) + #~(begin + (use-modules (guix build meson-configuration)) + (call-with-output-file #$output + (lambda (f) + (parameterize ((configuration-port f)) + (write-section-header "host_machine") + (write-assignments '#$(make-machine-alist triplet)) + (write-section-header "binaries") + (write-assignments '#$(make-binaries-alist triplet))))))))) + (define %meson-build-system-modules ;; Build-side modules imported by default. `((guix build meson-build-system) @@ -68,24 +126,34 @@ #:rest arguments) "Return a bag for NAME." (define private-keywords - `(#:meson #:ninja #:inputs #:native-inputs #:outputs #:target)) - - (and (not target) ;; TODO: add support for cross-compilation. - (bag - (name name) - (system system) - (build-inputs `(("meson" ,meson) - ("ninja" ,ninja) - ,@native-inputs - ,@inputs - ;; Keep the standard inputs of 'gnu-build-system'. - ,@(standard-packages))) - (host-inputs (if source - `(("source" ,source)) - '())) - (outputs outputs) - (build meson-build) - (arguments (strip-keyword-arguments private-keywords arguments))))) + `(#:meson #:ninja #:inputs #:native-inputs #:outputs + ,@(if target + '() + '(#:target)))) + + (bag + (name name) + (system system) (target target) + (build-inputs `(("meson" ,meson) + ("ninja" ,ninja) + ,@native-inputs + ,@(if target '() inputs) + ;; Keep the standard inputs of 'gnu-build-system'. + ,@(if target + (standard-cross-packages target 'host) + '()) + ,@(standard-packages))) + (host-inputs `(,@(if source + `(("source" ,source)) + '()) + ,@(if target inputs '()))) + ;; Keep the standard inputs of 'gnu-buid-system'. + (target-inputs (if target + (standard-cross-packages target 'target) + '())) + (outputs outputs) + (build (if target meson-cross-build meson-build)) + (arguments (strip-keyword-arguments private-keywords arguments)))) (define* (meson-build name inputs #:key @@ -161,6 +229,97 @@ has a 'meson.build' file." #:disallowed-references disallowed-references #:guile-for-build guile))) +(define* (meson-cross-build name + #:key + target + build-inputs host-inputs target-inputs + guile source + (outputs '("out")) + (configure-flags ''()) + (search-paths '()) + (native-search-paths '()) + + (build-type "debugoptimized") + (tests? #f) + (test-target "test") + (glib-or-gtk? #f) + (parallel-build? #t) + (parallel-tests? #f) + (validate-runpath? #t) + (patch-shebangs? #t) + (strip-binaries? #t) + (strip-flags ''("--strip-debug")) + (strip-directories ''("lib" "lib64" "libexec" + "bin" "sbin")) + (elf-directories ''("lib" "lib64" "libexec" + "bin" "sbin")) + (phases '%standard-phases) + (system (%current-system)) + (imported-modules %meson-build-system-modules) + (modules '((guix build meson-build-system) + (guix build utils))) + allowed-references + disallowed-references) + "Cross-build SOURCE for TARGET using MESON, and with INPUTS, assuming that +SOURCE has a 'meson.build' file." + (define cross-file + (make-cross-file target)) + (define inputs + (if (null? target-inputs) + (input-tuples->gexp host-inputs) + #~(append #$(input-tuples->gexp host-inputs) + #+(input-tuples->gexp target-inputs)))) + (define builder + (with-imported-modules imported-modules + #~(begin + (use-modules #$@(sexp->gexp modules)) + + (define build-phases + #$(let ((phases (if (pair? phases) (sexp->gexp phases) phases))) + (if glib-or-gtk? + phases + #~(modify-phases #$phases + (delete 'glib-or-gtk-compile-schemas) + (delete 'glib-or-gtk-wrap))))) + + ;; Do not use 'with-build-variables', as there should be + ;; no reason to use %build-inputs and friends. + (meson-build #:source #+source + #:system #$system + #:outputs #$(outputs->gexp outputs) + #:inputs #$inputs + #:native-inputs #+(input-tuples->gexp build-inputs) + #:search-paths '#$(sexp->gexp + (map search-path-specification->sexp + search-paths)) + #:native-search-paths '#$(sexp->gexp + (map search-path-specification->sexp + native-search-paths)) + #:phases build-phases + #:configure-flags `("--cross-file" #+cross-file + ,@#$(sexp->gexp configure-flags)) + #: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 #$(sexp->gexp strip-flags) + #:strip-directories #$(sexp->gexp strip-directories) + #:elf-directories #$(sexp->gexp elf-directories))))) + + (mlet %store-monad ((guile (package->derivation (or guile (default-guile)) + system #:graft? #f))) + (gexp->derivation name builder + #:system system + #:target target + #:substitutable? substitutable? + #:allowed-references allowed-references + #:disallowed-references disallowed-references + #:guile-for-build guile))) + (define meson-build-system (build-system (name 'meson) diff --git a/guix/build/meson-configuration.scm b/guix/build/meson-configuration.scm new file mode 100644 index 0000000000..81b4eaa7e1 --- /dev/null +++ b/guix/build/meson-configuration.scm @@ -0,0 +1,71 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Maxime Devos +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix build meson-configuration) + #:use-module (ice-9 match) + #:export (write-section-header write-assignment + write-assignments make-machine-alist + configuration-port)) + +;; Commentary: +;; +;; Utilities for generating a ‘Cross build definition file’ for +;; the Meson build system. Configuration values are currently +;; never escaped. In practice this is unlikely to be a problem +;; in the build environment. +;; +;; Code: + +(define configuration-port + (fluid->parameter (make-unbound-fluid))) + +(define (write-section-header section-name) + "Write a section header for section named SECTION-NAME +to the configuration port." + (format (configuration-port) "[~a]~%" section-name)) + +(define (write-assignment key value) + "Write an assignment of VALUE to KEY to the configuration +port. VALUE must be a string (without any special characters +such as quotes), a boolean or an integer. Lists are currently +not supported" + (define port (configuration-port)) + (match value + ((? string?) + (format port "~a = '~a'~%" key value)) + ((? integer?) + (format port "~a = ~a~%" key value)) + (#f + (format port "~a = true~%" key)) + (#t + (format port "~a = false~%" key)))) + +(define* (write-assignments alist) + "Write the assignments in ALIST, an association list, +to the configuration port." + (for-each (match-lambda + ((key . value) + (write-assignment key value))) + alist)) + +(define* (make-machine-alist #:key system cpu-family cpu endian) + "Make an association list for the [host_machine] section." + `((system . ,system) + (cpu-family . ,cpu-family) + (cpu . ,cpu) + (endian . ,endian))) -- 2.32.0