From 70a2087d244f757bec823f67380f9d46a0e8d915 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 6 Jul 2025 17:12:57 +0800 Subject: [PATCH] docs: Add initial readme --- README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f69055b80a83393e515ae110bc9f4ea6db046f20 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# cross-shells - get a cross compilation environment in your guix shell! + + +One problem I have been facing with Guix, as opposed to Nix, is using +shells for cross compilation. The problem with Guix in this regard is +that Guix doesn't really expose easy ways to have a shell with native +and target inputs. (and not just shells! I cannot find a good way to say +compile this natively, and cross compile something else. I utilized this +a lot on Nix where I deployed the system mostly natively compiled, since +there were substitutes, but when I had something custom, I cross +compiled it to save time. With guix this is easier as guix makes cross +compiled substitutes available as well). Moreover even though you +can use cross-gcc and cross-libc, it is not easy to just tell Guix to +give you development inputs of a package in Guix for a different target. +There seems to be a procedure that is supposed to somewhat take care of +this, 'package->development-maifest', but this procedure doesn't really +do everything necessary. First of all, even if target is supplied, for +whatever reason the inputs you get aren't cross compiled for the target +system, and secondly, there aren't search paths necessary for the build. +Maybe this is a bug that ought to be solved. When I began thinking of +this idea, my skills definitely weren't enough for that and I had to +iteratively make my initial ideas work. + +Apart from this issue there is, in my opinion, also another deeper +issue of having all the binaries and libraries for the target system in +the same place as the native libraries, if one used a profile and put +both the types in the profile itself. This complicates the case when you +would need to compile something natively during a build. When I am +dveloping for embedded systems, I sometimes need to compile something +natively in the same environment. For example some +tests can be made run natively, no need to cross compile. Switching +shells isn't something that one would like to do for that. + +# Solution + +With these limitations in mind, I came up with a solution and +implemented a proof of concept of this solution. That is to say it might +still be evolving in the future, it is definitely not complete. + +The idea was to make sort of a profile-like functionality, but instead +of making something completely new, since all the hard work for profiles +has already been done, I decided to implement a way to just take this +profile and make a package out of it. This package is just a union of +build inputs, target inputs and host inputs. The target and host inputs +are put to a subfolder `#$output/cross/{target}/{name}`, while the build inputs +are directly in #$output. Additionally search-paths of target and host +inputs are taken, the prefix cross/{target}/{name} is appended, and put +to native-search-paths, as the search paths now make sense for this +package 'natively'. + +The splitting of the host inputs to a +different folder, it is possible to have the same libraries natively and +for the target system. Additionally it could be possible to use multiple +cross shells at once in the future, but this would probably require +wrapping instead of relying on search paths. + +There is cross-profile record that has these fields: native-inputs, +inputs, target-inputs, inputs-from. inputs-from are probably the most +interesting. This is a list of packages, and their inputs are taken as +inputs of the cross-profile. So that if you want to compile bash, you +just put bash to inputs-from, sort of like +package->development-manifest, but for cross compilation. + +To overcome the limitation where it is not easy to say to cross compile +a package, I made a new record that I call 'cross-package-job', and I +just made a gexp compiler for it that calls 'package->cross-derivation'. +Please do let me know if there is already a way to make a cross +derivation in gexps in Guix and I just missed it. + +# Example + +Here is an example for an environment to compile bash for aarch64-linux-gnu +``` +(define profile + (cross-profile + (target-system "aarch64-linux-gnu") + (inputs-from (list bash)))) + +(define profile-package (make-cross-profile-package + profile)) ; this makes the package that you put to profile +``` + +The idea is then to take this package and put it to a regular guix shell.