New post about cross-compiling
This commit is contained in:
@@ -0,0 +1,158 @@
|
|||||||
|
---
|
||||||
|
title: "Sword Windows Cross Build 20241018"
|
||||||
|
date: 2024-10-18T11:05:36-05:00
|
||||||
|
draft: false
|
||||||
|
---
|
||||||
|
*[TL;DR](#tldr)* Just let me download it
|
||||||
|
|
||||||
|
I have been trying to come up with a good, reliable way to build executables for
|
||||||
|
Windows from Linux for a long time. One of the longer running problems I have had
|
||||||
|
is that the ground keeps shifting out from under me. Sometimes, you've got exactly
|
||||||
|
the set of requirements that you need, and that's all you want! But, when I have
|
||||||
|
previously used things like the [MinGW](https://sourceforge.net/projects/mingw-w64/)
|
||||||
|
toolchain from [Fedora](https://fedoraproject.org/) - I would have had to
|
||||||
|
freeze the exact machine I was building on in order to be able to reproduce the
|
||||||
|
same results as before. But, of course, this is not a feasible thing to do, especially
|
||||||
|
for an open source project that is leveraging CI.
|
||||||
|
|
||||||
|
Of course, [Nix](https://nixos.org) came along and has largely solved the problem of
|
||||||
|
pinning an entire system of libraries, executables, and compilers. But I had never
|
||||||
|
dived into how to use its pinning power to create a cross compile result. Well, it
|
||||||
|
turns out that it was simpler than I had thought. So I went about compiling my
|
||||||
|
favorite cross-build library for Windows from my Linux host. That library it
|
||||||
|
[The SWORD Project](https://www.crosswire.org/sword), available in NixPkgs as just
|
||||||
|
the package name "sword".
|
||||||
|
|
||||||
|
To build Sword for Linux hosts, all you need to do is go to a Linux machine with
|
||||||
|
Nix already installed (I use NixOS, but it can be installed on basically any distribution
|
||||||
|
of Linux) and invoke the command: `nix build "nixpkgs#sword`. Provided you have
|
||||||
|
nixpkgs setup as a flake and you have the nix command and flakes enabled (these are
|
||||||
|
pretty common options on systems), you will end up with a symlink in your current
|
||||||
|
directory named `result`. You can then run any of the tools from SWORD by invoking
|
||||||
|
them like anything else you would call. `./result/bin/diatheke`, for instance, gives
|
||||||
|
you the diatheke command from SWORD.
|
||||||
|
|
||||||
|
But how do you cross compile it? Well, that is already thought out for you! You just
|
||||||
|
need to invoke `nix build "nixpkgs#pkgsCross.mingwW64.sword`. pkgsCross has quite
|
||||||
|
a few targets available to you. `mingwW64` is the one that corresponds to Windows for
|
||||||
|
x86\_64 architectures. It also has an older target for 32-bit Windows machines, as
|
||||||
|
well as other targets for building. If you are interested, trying using nix repl to
|
||||||
|
eplore:
|
||||||
|
|
||||||
|
```
|
||||||
|
nix repl
|
||||||
|
>>> :lf nixpkgs
|
||||||
|
>>> legacyPackages.x86_64-linux.pkgsCross
|
||||||
|
```
|
||||||
|
|
||||||
|
### BUT....
|
||||||
|
|
||||||
|
Was it relaly that simple to build SWORD binaries for Windows from my NixOS machine
|
||||||
|
the first time? Of course not. The SWORD package is tagged as only supporting Unix-based
|
||||||
|
or adjacent systems. So I could have compiled for BSDs, Linux on ARM, PPC, RISC-V,
|
||||||
|
and more. But I got an error message the first time I tried to build for Windows, that
|
||||||
|
looked something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
error:
|
||||||
|
… in the condition of the assert statement
|
||||||
|
|
||||||
|
at /nix/store/lryfc8mhk1czqsa421di2y5nzz5c3b8m-source/lib/customisation.nix:365:17:
|
||||||
|
|
||||||
|
364| in commonAttrs // {
|
||||||
|
365| drvPath = assert condition; drv.drvPath;
|
||||||
|
| ^
|
||||||
|
366| outPath = assert condition; drv.outPath;
|
||||||
|
|
||||||
|
… while evaluating the attribute 'handled'
|
||||||
|
|
||||||
|
at /nix/store/lryfc8mhk1czqsa421di2y5nzz5c3b8m-source/pkgs/stdenv/generic/check-meta.nix:507:7:
|
||||||
|
|
||||||
|
506| # or, alternatively, just output a warning message.
|
||||||
|
507| handled =
|
||||||
|
| ^
|
||||||
|
508| (
|
||||||
|
|
||||||
|
(stack trace truncated; use '--show-trace' to show the full trace)
|
||||||
|
|
||||||
|
error: Package ‘sword-1.9.0’ in /nix/store/lryfc8mhk1czqsa421di2y5nzz5c3b8m-source/pkgs/by-name/sw/sword/package.nix:49 is not available on the requested hostPlatform:
|
||||||
|
hostPlatform.config = "x86_64-w64-mingw32"
|
||||||
|
package.meta.platforms = [
|
||||||
|
"i686-cygwin"
|
||||||
|
"x86_64-cygwin"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"i686-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
"armv7a-darwin"
|
||||||
|
"i686-freebsd"
|
||||||
|
"x86_64-freebsd"
|
||||||
|
"x86_64-solaris"
|
||||||
|
"aarch64-linux"
|
||||||
|
"armv5tel-linux"
|
||||||
|
"armv6l-linux"
|
||||||
|
"armv7a-linux"
|
||||||
|
"armv7l-linux"
|
||||||
|
"i686-linux"
|
||||||
|
"loongarch64-linux"
|
||||||
|
"m68k-linux"
|
||||||
|
"microblaze-linux"
|
||||||
|
"microblazeel-linux"
|
||||||
|
"mips-linux"
|
||||||
|
"mips64-linux"
|
||||||
|
"mips64el-linux"
|
||||||
|
"mipsel-linux"
|
||||||
|
"powerpc64-linux"
|
||||||
|
"powerpc64le-linux"
|
||||||
|
"riscv32-linux"
|
||||||
|
"riscv64-linux"
|
||||||
|
"s390-linux"
|
||||||
|
"s390x-linux"
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-netbsd"
|
||||||
|
"armv6l-netbsd"
|
||||||
|
"armv7a-netbsd"
|
||||||
|
"armv7l-netbsd"
|
||||||
|
"i686-netbsd"
|
||||||
|
"m68k-netbsd"
|
||||||
|
"mipsel-netbsd"
|
||||||
|
"powerpc-netbsd"
|
||||||
|
"riscv32-netbsd"
|
||||||
|
"riscv64-netbsd"
|
||||||
|
"x86_64-netbsd"
|
||||||
|
"i686-openbsd"
|
||||||
|
"x86_64-openbsd"
|
||||||
|
"x86_64-redox"
|
||||||
|
]
|
||||||
|
package.meta.badPlatforms = [ ]
|
||||||
|
, refusing to evaluate.
|
||||||
|
|
||||||
|
a) To temporarily allow packages that are unsupported for this system, you can use an environment variable
|
||||||
|
for a single invocation of the nix tools.
|
||||||
|
|
||||||
|
$ export NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1
|
||||||
|
|
||||||
|
Note: When using `nix shell`, `nix build`, `nix develop`, etc with a flake,
|
||||||
|
then pass `--impure` in order to allow use of environment variables.
|
||||||
|
|
||||||
|
b) For `nixos-rebuild` you can set
|
||||||
|
{ nixpkgs.config.allowUnsupportedSystem = true; }
|
||||||
|
in configuration.nix to override this.
|
||||||
|
|
||||||
|
c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
|
||||||
|
{ allowUnsupportedSystem = true; }
|
||||||
|
to ~/.config/nixpkgs/config.nix.
|
||||||
|
```
|
||||||
|
|
||||||
|
That's a WHOLE lot of text to tell me it can't build for Windows! But, I have opened some pull requests
|
||||||
|
for NixPkgs so that SWORD will be listed as supported. Because, indeed, there isn't anything inherent
|
||||||
|
in SWORD that requires it to be built for only Unix systems. It supports all manner of embedded, Windows,
|
||||||
|
and other environments in addition to standard Linux/Unix platforms. It only required a few tweaks to
|
||||||
|
the build formula to tell it where to find the options that it wanted.
|
||||||
|
|
||||||
|
### TLDR
|
||||||
|
|
||||||
|
Show me the goods!
|
||||||
|
|
||||||
|
OK, if you're just looking for the compiled binaries. Try [this link](../sword-nixbuild-win64-20241018.tar.xz)
|
||||||
|
to get the resulting product. Drop me an email if you have any feedback on it. I haven't had much of a
|
||||||
|
chance to test things, so it's very possible some parts of it don't work. Give me a shout if that's the case.
|
||||||
Binary file not shown.
Reference in New Issue
Block a user