@@ 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.