diff --git a/README.md b/README.md index d661fc9..a113e8f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,112 @@ # forge -A toolchain to forge your multi-platform `nim` binaries. +A basic toolchain to forge (cross-compile) your multi-platform `nim` binaries. -## install +## Why? + +`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 sharable native executable binaries + +## Installation + +In order to use `forge` you must first install [`zig`](https://ziglang.org/) as all compilation +is done using a thin wrapper around `zig cc`. + +> [!NOTE] +> Future versions may use an automated/isolated `zig` installation. ```sh nimble install https://github.com/daylinmorgan/forge ``` +## Usage + +`Forge` provide 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: + +```sh +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 `.nimble` + +You can either specify all commands on the CLI or use a config file. + +Example: +```sh +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`: + +```dosini +# 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: +```sh +forge release --verbose --dryrun +``` + +Output: +``` +forge release -V --dryrun +forge || config = +| nimble true +| outdir forge-dist +| format ${name}-${target} +| version 2023.1001 +| targets: +| x86_64-linux-musl|--debugInfo:on +| x86_64-linux-gnu +| bins: +| src/forge +| src/forgecc|--opt:size +forge || dry run...see below for commands +forge || compiling 2 binaries for 2 targets +nimble c --cpu:amd64 --os:Linux --cc:clang --clang.exe='forgecc' --clang.linkerexe='forgecc' --passC:'-target x86_64-linux-musl' --passL:'-target x86_64-linux-musl' -d:release --outdir:'dist/forge-x86_64-linux-musl' --debugInfo:on src/forge +nimble c --cpu:amd64 --os:Linux --cc:clang --clang.exe='forgecc' --clang.linkerexe='forgecc' --passC:'-target x86_64-linux-musl' --passL:'-target x86_64-linux-musl' -d:release --outdir:'dist/forge-x86_64-linux-musl' --debugInfo:on --opt:size src/forgecc +nimble c --cpu:amd64 --os:Linux --cc:clang --clang.exe='forgecc' --clang.linkerexe='forgecc' --passC:'-target x86_64-linux-gnu' --passL:'-target x86_64-linux-gnu' -d:release --outdir:'dist/forge-x86_64-linux-gnu' src/forge +nimble c --cpu:amd64 --os:Linux --cc:clang --clang.exe='forgecc' --clang.linkerexe='forgecc' --passC:'-target x86_64-linux-gnu' --passL:'-target x86_64-linux-gnu' -d:release --outdir:'dist/forge-x86_64-linux-gnu' --opt:size src/forgecc + +``` + +## Acknowledgements + +Thanks to [Andrew Kelley](https://github.com/andrewrk) and the many `zig` [contributors](https://github.com/ziglang/zig/graphs/contributors).