Cross-compile with Zig

$ uname -sm
Darwin arm64
$ tail -2 teesyslog.nimble
task cross, "Cross-compile to (CentOS 6 era) Linux, requiring zig in PATH":
  exec "CC=$PWD/zigcc.sh nimble build --cc:env -d:release --mm:orc --os:linux --cpu:amd64"
$ nimble cross; file teesyslog
teesyslog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.0.0, with debug_info, not stripped
$ grep -am1 -Eo 'GLIBC_[0-9_.]+' teesyslog
GLIBC_2.2.5

Using zigcc.sh:

#! /bin/bash
exec zig cc --target=x86_64-linux-gnu.2.12 "$@"

As compared to a build targeting x86_64-linux-gnu:

% grep -am1 -Eo 'GLIBC_[0-9_.]+' teesyslog
GLIBC_2.2.5
GLIBC_2.14
GLIBC_2.17

Note well:

  1. Nim cache is unaware of Zig's flags. If you change the target you'll need to wipe ~/.cache/nim or you'll likely mix objects inappropriately.
  2. Nim needs to agree with Zig on the OS and CPU of the target.

Alternate method for multiple targets:

$ cat zigcc.sh
#! /bin/bash
exec zig cc --target=$ZIGTARGET "$@"
$ tail hello.nimble
task crossLinux, "Cross-compile to Linux":
  exec "ZIGTARGET=x86_64-linux-gnu CC=$PWD/zigcc.sh nim c --cc:env -d:release --mm:orc --os:linux --cpu:amd64 --nimcache:.cache/linux -o:hello src/hello.nim"
task crossLinuxMusl, "Cross-compile to Linux (musl)":
  exec "ZIGTARGET=x86_64-linux-musl CC=$PWD/zigcc.sh nim c --cc:env -d:release --mm:orc --os:linux --cpu:amd64 --nimcache:.cache/linuxmusl -o:hello.musl src/hello.nim"
task crossWindows, "Cross-compile to Windows":
  exec "ZIGTARGET=x86_64-windows CC=$PWD/zigcc.sh nim c --cc:env -d:release --mm:orc --os:windows --cpu:amd64 --nimcache:.cache/windows -o:hello.exe src/hello.nim"
task cross, "Cross-compile to all targets":
  exec "nimble crossLinux"
  exec "nimble crossLinuxMusl"
  exec "nimble crossWindows"
$ nimble cross
$ file hello{,.musl,.exe}
hello:      ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.0.0, with debug_info, not stripped
hello.musl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
hello.exe:  PE32+ executable (console) x86-64, for MS Windows

Note that this version is exec'ing nim instead of nimble as the 'bin' feature of nimble configs prevents -o: from doing what's wanted here.