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