Skip to content

Compile-time flags

Types, methods and generally any part of your code can be conditionally defined based on some flags available at compile time. These flags are by default read from the hosts LLVM Target Triple, split on -. To get the target you can execute llvm-config --host-target.

$ llvm-config --host-target
x86_64-unknown-linux-gnu

# so the flags are: x86_64, unknown, linux, gnu

To define a flag, simply use the --define or -D option, like so:

crystal some_program.cr -Dflag

Additionally, if a program is compiled with --release, the release flag will be set.

You can check if a flag is defined with the flag? macro method:

{% if flag?(:x86_64) %}
  # some specific code for 64 bits platforms
{% else %}
  # some specific code for non-64 bits platforms
{% end %}

flag? returns a boolean, so you can use it with && and ||:

{% if flag?(:linux) && flag?(:x86_64) %}
  # some specific code for linux 64 bits
{% end %}

These flags are generally used in C bindings to conditionally define types and functions. For example, the very well known size_t type is defined like this in Crystal:

lib C
  {% if flag?(:x86_64) %}
    alias SizeT = UInt64
  {% else %}
    alias SizeT = UInt32
  {% end %}
end

List

The following table lists all flags used in the standard library or compiler:

Meaning Flags
Architectures aarch64, arm, armhf, i386, x86_64
Word Sizes bits32, bits64
Compiler modes release, static, debug, debug_raise, docs
Operating Systems android, bsd, darwin, dragonfly, linux, freebsd, freebsd12.0, netbsd, openbsd, openbsd6.2, unix, windows
C APIs musl, gnu, win32
Stdlib features preview_mt, skip_crystal_compiler_rt, gc_none
Compiler features i_know_what_im_doing, without_openssl, without_playground, without_zlib