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.

  1. $ llvm-config --host-target
  2. x86_64-unknown-linux-gnu
  3. # so the flags are: x86_64, unknown, linux, gnu

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

  1. $ 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:

  1. {% if flag?(:x86_64) %}
  2. # some specific code for 64 bits platforms
  3. {% else %}
  4. # some specific code for non-64 bits platforms
  5. {% end %}

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

  1. {% if flag?(:linux) && flag?(:x86_64) %}
  2. # some specific code for linux 64 bits
  3. {% 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:

  1. lib C
  2. {% if flag?(:x86_64) %}
  3. alias SizeT = UInt64
  4. {% else %}
  5. alias SizeT = UInt32
  6. {% end %}
  7. end