quartz-utils documentation

Build

Dynamic

Install dependencies:

shards install --production

Build with shards:

shards build --production --release --no-debug

Build with crystal (warning: binaries will be output in the current directory, not in bin/):

crystal build src/*.cr --release --no-debug

Static

Install dependencies:

shards install --production

As the Crystal documentations says:

Building fully statically linked executables is currently only supported on Alpine Linux.

For that purpose, the documentation recommends using musl-libc:

Official Docker Images based on Alpine Linux are available on Docker Hub at crystallang/crystal. The latest release is tagged as crystallang/crystal:latest-alpine.

As an example replace the local build:

# With Shards (in bin/)
shards build --production --release --static --no-debug
# With Crystal (in ./)
crystal build src/*.cr --release --static --no-debug

with

# With Shards (in bin/)
docker run --rm -it -v $PWD:/workspace -w /workspace crystallang/crystal:1.12.1-alpine \
    shards build --production --release --static --no-debug

# With Crystal (in ./)
docker run --rm -it -v $PWD:/workspace -w /workspace crystallang/crystal:1.12.1-alpine \
    crystal build src/*.cr --release --static --no-debug

Since you are cross-compiling from a docker container, it would be wiser to ensure to provide the correct cross compilation flags.

Find your platform with llvm-config --host-target (examples: x86_64-pc-linux-gnu on a modern Linux host) on your host or the target (see platform support and LLVM - Cross-compilation using Clang).

So change from (unfortunately shards doesn’t support cross-compilation)

crystal build src/*.cr --release --static --no-debug --cross-compile --target x86_64-pc-linux-gnu

cc *.o -o * -rdynamic -static -L/usr/bin/../lib/crystal -lpcre2-8 -lgc -lpthread -ldl -lpthread -levent -lrt -lpthread -ldl

to

docker run --rm -it -v $PWD:/workspace -w /workspace crystallang/crystal:1.12.1-alpine \
    crystal build src/*.cr --release --static --no-debug \
   -o bin/*-x86_64-pc-linux-gnu --cross-compile --target x86_64-pc-linux-gnu

cc bin/*-x86_64-pc-linux-gnu.o -o bin/*-x86_64-pc-linux-gnu -rdynamic -static -L/usr/bin/../lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl

Note: the second line must be executed on the target platform.

Finally, check your binary is fully static:

ldd bin/*-x86_64-pc-linux-gnu
        not a dynamic executable

Note: of course, you need to replace * with the name of a utility. For more convenience, cross_compile_objects.cr (crystal run cross_compile_objects.cr) script will compile all pre-compiled objects for all tier 1 & 2 platforms.

Release

With this we can compile a pre-compiled object without needing Crystal, Docker or managing the dependencies.

64-bit Linux (kernel 2.6.18+, GNU libc)

cc *-x86_64-linux-gnu.o -o *-x86_64-linux-gnu -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl

ARM 64-bit Linux (GNU libc, hardfloat)

cc *-aarch64-linux-gnu.o -o *-aarch64-linux-gnu -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl

ARM 64-bit Linux (MUSL libc, hardfloat)

cc *-aarch64-linux-musl.o -o *-aarch64-linux-musl -rdynamic -static -L/usr/lib/crystal -lpcre -lgc -levent

ARM 32-bit Linux (GNU libc, hardfloat)

Dependencies Debian 11: apt install libpcre3-dev libgc-dev libevent-dev

cc *-arm-linux-gnueabihf.o -o *-arm-linux-gnueabihf -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc -lpthread -levent -lpthread -ldl

32-bit Linux (kernel 2.6.18+, GNU libc)

cc *-i386-linux-gnu.o -o *-i386-linux-gnu -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl

32-bit Linux (MUSL libc)

cc *-i386-linux-musl.o -o *-i386-linux-musl -rdynamic -static -L/usr/lib/crystal -lpcre -lgc -levent

64-bit Linux (MUSL libc)

cc *-x86_64-linux-musl.o -o *-x86_64-linux-musl -rdynamic -static -L/usr/lib/crystal -lpcre -lgc -levent

64-bit OpenBSD (6.x)

cc *-x86_64-openbsd.o -o *-x86_64-openbsd -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc -lpthread -levent_extra -levent_core -lc++abi -lpthread -liconv

64-bit FreeBSD (12.x)

cc *-x86_64-freebsd.o -o *-x86_64-freebsd -rdynamic -static -L/usr/lib/crystal -lpcre -lm -lgc-threaded -lpthread -levent -lpthread

64-bit OSX (10.7+, Lion+)

cc *-x86_64-darwin.o -o *-x86_64-darwin -rdynamic -static -L/usr/lib/crystal -lpcre -lgc -levent -liconv

ARM 64-bit OSX (Apple Silicon)

cc *-aarch64-darwin.o -o *-aarch64-darwin -rdynamic -static -L/usr/lib/crystal -lpcre -lgc -levent -liconv