The gray Command
gray compiles, runs, checks, formats and documents Grayscale code. Run gray --help for the full command list.
Start a project
Section titled “Start a project”gray new scaffolds a project. Pick a template with -t: basic (the default), cli, lib, multi, server or client.
gray new myappgray new tool -t cligray new api -t server -s minimal-s minimal or -s normal applies to the server and client templates. With no arguments, gray new asks for the name and template interactively.
Run, build, check
Section titled “Run, build, check”gray main.gray # compile and rungray main.gray -- --port 8080 # arguments after -- go to your programgray build main.gray -o myapp # native binarygray build main.gray --emit-c # write main.c and stopgray check main.gray # type check onlygray watch main.gray # re-run whenever a file changesgray watch also watches the files your program imports.
These flags work on gray <file>, build, check and watch:
| Flag | Effect |
|---|---|
-q, --quiet <codes> |
Hide warnings: all, or a list like W1001,W1003 |
--no-color |
Plain diagnostics |
--arena-limit=<size> |
Cap arena memory, for example 256MB. The default is 1GB |
gray build --time prints how long compilation took.
Choosing the C compiler
Section titled “Choosing the C compiler”Grayscale generates C and hands it to the first of $GRAY_CC, $CC, cc, gcc or clang it finds. TinyCC (tcc) compiles faster, which suits a tight edit-run loop.
GRAY_CC=tcc gray main.grayMark functions with #test and run them with gray test.
#doc("Adds two numbers")do add(a i64, b i64) -> i64 { return a + b}
#testdo test_add() { assert(add(2, 3) == 5) assert(add(0, 0) == 0)}
do main() { println(add(1, 2))}gray test # every #test under the current directorygray test math.gray # one filegray test ./src/... # a directory, recursivelyFormatting
Section titled “Formatting”gray fmt rewrites files in place: 4-space indentation, no trailing whitespace, one final newline, and no more than two blank lines in a row. --check changes nothing and exits non-zero if a file would change, which suits CI.
gray fmt main.graygray fmt ./...gray fmt --check ./...A path is a file, a directory (not recursive), or dir/... and ./... (recursive). gray doc and gray test take the same patterns.
Documentation
Section titled “Documentation”gray doc reads #doc attributes and writes a markdown file, DOCS.md unless you pass -o.
gray doc main.graygray doc ./... -o API.mdgray man shows built-in documentation from the terminal. Leave off () when naming a function, and leave off the # when naming an attribute.
gray man # usage and the list of modulesgray man math # everything in one modulegray man println # one functiongray man strings.containsgray man keywordsgray man flags # the #flags attributeCross-compiling
Section titled “Cross-compiling”gray cross build uses Zig as the C compiler, so Zig must be on your PATH. Native builds do not need it.
gray cross targetsgray cross build main.gray --target linux-arm64 -o myappSupported targets are linux-amd64, linux-arm64, windows-amd64, mac-arm64 and mac-amd64.
Maintaining the toolchain
Section titled “Maintaining the toolchain”gray version # installed version and whether an update existsgray update # upgrade to the latest releasegray update --pre # latest pre-release insteadgray install 3.0.0 # install an exact versiongray verify # compile and run a built-in self-testgray report # system details to paste into a bug report