From 71b98b9de9d2658f4787d2fb77609a95b09ff3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 9 Jan 2018 16:48:35 +0100 Subject: [PATCH] services: qemu-binfmt: Extend guix-daemon with extra chroot directories. Fixes . * gnu/services/virtualization.scm ()[guix-support?]: New field. (qemu-binfmt-guix-chroot): New procedure. (qemu-binfmt-service-type)[extensions]: Add GUIX-SERVICE-TYPE. * doc/guix.texi (Virtualization Services): Document 'guix-support?'. (Additional Build Options): Mention binfmt_misc and offloading under '--system'. --- doc/guix.texi | 46 ++++++++++++++++++++++++++++++++- gnu/services/virtualization.scm | 21 +++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index f0618e39f0..6245d54e8d 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -5621,11 +5621,26 @@ The following derivations will be built: Attempt to build for @var{system}---e.g., @code{i686-linux}---instead of the system type of the build host. +@quotation Note +The @code{--system} flag is for @emph{native} compilation and must not +be confused with cross-compilation. See @code{--target} below for +information on cross-compilation. +@end quotation + An example use of this is on Linux-based systems, which can emulate different personalities. For instance, passing -@code{--system=i686-linux} on an @code{x86_64-linux} system allows users +@code{--system=i686-linux} on an @code{x86_64-linux} system allows you to build packages in a complete 32-bit environment. +Similarly, when transparent emulation with QEMU and @code{binfmt_misc} +is enabled (@pxref{Virtualization Services, +@code{qemu-binfmt-service-type}}), you can build for any system for +which a QEMU @code{binfmt_misc} handler is installed. + +Builds for a system other than that of the machine you are using can +also be offloaded to a remote machine of the right architecture. +@xref{Daemon Offload Setup}, for more information on offloading. + @item --target=@var{triplet} @cindex cross-compilation Cross-build for @var{triplet}, which must be a valid GNU triplet, such @@ -17698,6 +17713,35 @@ This is the configuration for the @code{qemu-binfmt} service. The list of emulated QEMU platforms. Each item must be a @dfn{platform object} as returned by @code{lookup-qemu-platforms} (see below). +@item @code{guix-support?} (default: @code{#f}) +When it is true, QEMU and all its dependencies are added to the build +environment of @command{guix-daemon} (@pxref{Invoking guix-daemon, +@code{--chroot-directory} option}). This allows the @code{binfmt_misc} +handlers to be used within the build environment, which in turn means +that you can transparently build programs for another architecture. + +For example, let's suppose you're on an x86_64 machine and you have this +service: + +@example +(service qemu-binfmt-service-type + (qemu-binfmt-configuration + (platforms (lookup-qemu-platforms "arm")) + (qemu-support? #t))) +@end example + +You can run: + +@example +guix build -s armhf-linux inkscape +@end example + +@noindent +and it will build Inkscape for ARMv7 @emph{as if it were a native +build}, transparently using QEMU to emulate the ARMv7 CPU. Pretty handy +if you'd like to test a package build for an architecture you don't have +access to! + @item @code{qemu} (default: @code{qemu}) The QEMU package to use. @end table diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm index 0a8f67fb8e..bf71e7f26a 100644 --- a/gnu/services/virtualization.scm +++ b/gnu/services/virtualization.scm @@ -662,7 +662,9 @@ potential infinite waits blocking libvirt.")) (qemu qemu-binfmt-configuration-qemu (default qemu)) (platforms qemu-binfmt-configuration-platforms - (default '()))) ;safest default + (default '())) ;safest default + (guix-support? qemu-binfmt-configuration-guix-support? + (default #f))) (define (qemu-platform->binfmt qemu platform) "Return a gexp that evaluates to a binfmt string for PLATFORM, using the @@ -724,6 +726,19 @@ given QEMU package." '#$(map qemu-platform-name platforms)) #f))))))) +(define qemu-binfmt-guix-chroot + (match-lambda + ;; Add QEMU and its dependencies to the guix-daemon chroot so that our + ;; binfmt_misc handlers work in the chroot (otherwise 'execve' would fail + ;; with ENOENT.) + ;; + ;; The 'F' flag of binfmt_misc is meant to address this problem by loading + ;; the interpreter upfront rather than lazily, but apparently that is + ;; insufficient (perhaps it loads the 'qemu-ARCH' binary upfront but looks + ;; up its dependencies lazily?). + (($ qemu platforms guix?) + (if guix? (list qemu) '())))) + (define qemu-binfmt-service-type ;; TODO: Make a separate binfmt_misc service out of this? (service-type (name 'qemu-binfmt) @@ -732,7 +747,9 @@ given QEMU package." (const (list %binary-format-file-system))) (service-extension shepherd-root-service-type - qemu-binfmt-shepherd-services))) + qemu-binfmt-shepherd-services) + (service-extension guix-service-type + qemu-binfmt-guix-chroot))) (default-value (qemu-binfmt-configuration)) (description "This service supports transparent emulation of binaries