Hello Ludo, Thanks for your explanation :) > This is expected: packages in ‘%final-inputs’ (those returned by > ‘canonical-package’) are rooted in the bootstrap graph and cannot be > cross-compiled. Looking at canonical-package in (gnu packages commencement), I see that there's already a switch on (%current-target-system). The given package is directly returned if (%current-target-system) is set, which appears to be what we want! --8<---------------cut here---------------start------------->8--- ;; In general we want CANON, except if we're cross-compiling: CANON ;; uses explicit inputs, so it is "anchored" in the bootstrapped ;; process, with dependencies on things that cannot be ;; cross-compiled. (if (%current-target-system) package canon)) --8<---------------cut here---------------end--------------->8--- But, this doesn't work as expected. I guess it is because of (%current-target-system) evaluation time. As I'm not fully understand everything here, I would propose to define a gexp-compiler for "canonical-packages", but there's maybe a better thing to do? Anyway, the snippet below works fine with a gexp-compiler (patch attached) and doesn't work with the current implementation of canonical-package. --8<---------------cut here---------------start------------->8--- (use-modules (guix) (gnu packages base)) (run-with-store (open-connection) (mlet* %store-monad ((gexp -> #~(#$(canonical-package grep))) (drv (gexp->script "test.scm" gexp #:target "aarch64-linux-gnu")) (build (built-derivations (list drv)))) (return #t))) --8<---------------cut here---------------end--------------->8--- WDYT? Thanks, Mathieu