Message ID | 20221017012843.29975-1-bauermann@kolabnow.com |
---|---|
State | New |
Headers | show |
Series | [bug#58576] system: image: Define correct docker image arch when cross building | expand |
Context | Check | Description |
---|---|---|
cbaines/comparison | success | View comparision |
cbaines/git-branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
Hello Thiago, Thanks for this patch! > + (image-target (or (%current-target-system) > + (and=> (image-platform image) platform-target) > + (nix-system->gnu-triplet))) There's the following snippet in "system-image" that is trying to do the right thing (and it is not easy) with the "target" value. --8<---------------cut here---------------start------------->8--- ;; The image platform definition may provide the appropriate "system" ;; architecture for the image. If we are already running on this system, ;; the image can be built natively. If we are running on a different ;; system, then we need to cross-compile, using the "target" provided by the ;; image definition. (define system (and=> platform platform-system)) (define target (cond ;; No defined platform, let's use the user defined ;; system/target parameters. ((not platform) (%current-target-system)) ;; The current system is the same as the platform system, no ;; need to cross-compile. ((and system (string=? system (%current-system))) #f) ;; If there is a user defined target let's override the ;; platform target. Otherwise, we can cross-compile to the ;; platform target. (else (or (%current-target-system) (and=> platform platform-target))))) --8<---------------cut here---------------end--------------->8--- The rationale is that the user supplied %current-target-system is always overriding the image platform field. Then, %current-target-system is set to the "target" value defined above. It makes me think that you could use %current-target-system directly as the "image-target" value. WDYT? Mathieu
Hello Mathieu, Thank you for reviewing my patch! Sorry for the delay, I've been traveling. Mathieu Othacehe <othacehe@gnu.org> writes: > Hello Thiago, > > Thanks for this patch! > >> + (image-target (or (%current-target-system) >> + (and=> (image-platform image) platform-target) >> + (nix-system->gnu-triplet))) > > There's the following snippet in "system-image" that is trying to do the > right thing (and it is not easy) with the "target" value. > > ;; The image platform definition may provide the appropriate "system" > ;; architecture for the image. If we are already running on this system, > ;; the image can be built natively. If we are running on a different > ;; system, then we need to cross-compile, using the "target" provided by the > ;; image definition. > (define system (and=> platform platform-system)) > (define target (cond > ;; No defined platform, let's use the user defined > ;; system/target parameters. > ((not platform) > (%current-target-system)) > ;; The current system is the same as the platform system, no > ;; need to cross-compile. > ((and system > (string=? system (%current-system))) > #f) > ;; If there is a user defined target let's override the > ;; platform target. Otherwise, we can cross-compile to the > ;; platform target. > (else > (or (%current-target-system) > (and=> platform platform-target))))) > > The rationale is that the user supplied %current-target-system is always > overriding the image platform field. Then, %current-target-system is set > to the "target" value defined above. > > It makes me think that you could use %current-target-system directly as > the "image-target" value. WDYT? I don't think “%current-target-system” can be used directly as the “image-target” value because for native builds it will be #f and my understanding is that “build-docker-image” would throw an error when receiving #f for the “#:system” argument. So I still need the or expression above, but I can drop the middle expression that calls “platform-target” because it's redundant with the snippet you posted above. Thank you for pointing it out. I'll send a v2 with the change.
diff --git a/gnu/system/image.scm b/gnu/system/image.scm index 5fc0d55d9a14..c6d7d13f6daf 100644 --- a/gnu/system/image.scm +++ b/gnu/system/image.scm @@ -652,6 +652,9 @@ (define shared-network? shared-network?) (list boot-program))) (substitutable? (image-substitutable? image)) + (image-target (or (%current-target-system) + (and=> (image-platform image) platform-target) + (nix-system->gnu-triplet))) (register-closures? (has-guix-service-type? os)) (schema (and register-closures? (local-file (search-path %load-path @@ -705,6 +708,7 @@ (define builder #:entry-point '(#$boot-program #$os) #:compressor '(#+(file-append gzip "/bin/gzip") "-9n") #:creation-time (make-time time-utc 0 1) + #:system #$image-target #:transformations `((,image-root -> "")))))))) (computed-file name builder
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org> Cross-building a docker image with: $ guix system image --image-type=docker --target=aarch64-linux-gnu os.scm results in an image where the architecture declared in its config.json is the host architecture rather than the target one. The binaries are correctly cross-compiled, so the image can be loaded and used despite the warning message shown by docker: $ docker load -i vcal7bvsqcijchifhqdvprpd1niqh8sk-docker-image.tar.gz Loaded image: guix:latest $ docker create guix:latest WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 40f06aa869ed690489c4a3824a7f7721bd4bf453b85f25ac7199266939fe2fba $ echo $? 0 This is fixed by passing the correct triplet to the build-docker-image function. * gnu/system/image.scm (system-docker-image) Add ‘image-target’ variable. [builder]: Pass ‘#:system’ argument to ‘build-docker-image’. --- gnu/system/image.scm | 4 ++++ 1 file changed, 4 insertions(+)