daylinmorgan/forge
build nim binaries for all the platforms
A basic toolchain to forge (cross-compile) your multi-platform nim
binaries.
Nim
is a great language and the code is as portable as any other code written in C.
But who wants to manage C toolchains or CI/CD DSL's to cross-compile your code into easily shareable native executable binaries
In order to use forge
you must first install zig
as all compilation
is done using a thin wrapper around zig cc
.
NOTE Future versions may use an automated/isolated
zig
installation.
nimble install forge
forge
provides two key methods to compile your nim
source forge +cc
and forge +release
.
forge +cc
To compile a single binary for a platform you can use forge +cc
.
Example:
forge +cc --target x86_64-linux-musl -- -d:release src/forge.nim -o:forge
forge +release
This command is useful for generating many compiled binaries like you may be accustomed to seeing from go
or rust
cli's.
forge +release
will make attempts to infer many values based on the assumption that it's
likely run from the root directory of a nim
project with a <project>.nimble
You can either specify all commands on the CLI or use a config file.
forge
is a wrapper around zig
and zig cc
.
If it's called without any of it's known subcommands (all prefixed by "+") then it will fall back to zig cc
.
This way we can deploy a single self-invoking binary since the clang.exe
specified to nim
can't have subcommands.
To invoke the same zig
used by forge
directly with the cc
command, see forge +zig
.
Example:
forge +release --target,=x86_64-linux-musl,x86_64-macos-none --bin src/forge.nim
Result:
dist
├── forge-v2023.1001-x86_64-linux-musl
│ └── forge
└── forge-v2023.1001-x86_64-macos-none
└── forge
The output directories used for each binary are determined
by a format string: ${name}-v${version}-${target}
.
You can modify this with additional info at runtime like using
date instead of version string: --format "\${name}-$(date +'%Y%M%d')-\${target}"
.
You can also create a config file by default at ./.forge.cfg
that controls the behavior of forge release
:
# flags are specified at the top level
nimble # key without value for booleans
format = "${name}-${target}"
outdir = forge-dist
# use sections to list targets/bins with optional args
[target]
x86_64-linux-musl = "--debugInfo:on"
x86_64-linux-gnu
[bin]
src/forge
src/forgecc = "--opt:size" # use a custom flag for this binary
Example:
forge +release --verbose --dryrun
Thanks to Andrew Kelley and the many zig
contributors.