Compile-time flags

Compile-time flags are boolean values provided through the compiler via a macro method. They allow to conditionally include or exclude code based on compile time conditions.

There are several default flags provided by the compiler with information about compiler options and the target platform. User-provided flags are passed to the compiler, which allow them to be used as feature flags.

Querying flags

A flag is just a named identifier which is either set or not. The status can be queried from code via the macro method flag?. It receives the name of a flag as a string or symbol literal and returns a bool literal indicating the flag’s state.

The following program shows the use of compile-time flags by printing the target OS family.

  1. {% if flag?(:unix) %}
  2. puts "This program is compiled for a UNIX-like operating system"
  3. {% elsif flag?(:windows) %}
  4. puts "This program is compiled for Windows"
  5. {% else %}
  6. # Currently, all supported targets are either UNIX or Windows platforms, so
  7. # this branch is practically unreachable.
  8. puts "Compiling for some other operating system"
  9. {% end %}

There’s also the macro method host_flag? which returns whether a flag is set for the host platform, which can differ from the target platform (queried by flag?) during cross-compilation.

Compiler-provided flags

The compiler defines a couple of implicit flags. They describe either the target platform or compiler options.

Target platform flags

Platform-specific flags derive from the target triple. See Platform Support for a list of supported target platforms.

crystal --version shows the default target triple of the compiler. It can be changed with the --target option.

The flags in each of the following tables are mutually exclusive, except for those marked as (derived).

Architecture

The target architecture is the first component of the target triple.

Flag nameDescription
aarch64AArch64 architecture
armARM architecture
i386x86 architecture (32-bit)
x86_64x86-64 architecture
bits32 (derived)32-bit architecture
bits64 (derived)64-bit architecture

Vendor

The vendor is the second component of the target triple. This is typically unused, so the most common vendor is unknown.

Flag nameDescription
macosxApple
portbldFreeBSD variant
unknownUnknown vendor

Operating System

The operating system is derived from the third component of a the target triple.

Flag nameDescription
bsd (derived)BSD family (DragonFlyBSD, FreeBSD, NetBSD, OpenBSD)
darwinDarwin (MacOS)
dragonflyDragonFlyBSD
freebsdFreeBSD
linuxLinux
netbsdNetBSD
openbsdOpenBSD
unix (derived)UNIX-like (BSD, Darwin, Linux)
windowsWindows

ABI

The ABI is derived from the last component of the target triple.

Flag nameDescription
armhf (derived)ARM EABI with hard float
gnuGNU
gnueabihfGNU EABI with hard float
msvcMicrosoft Visual C++
muslmusl
win32 (derived)Windows API

Compiler options

The compiler sets these flags based on compiler configuration.

Flag nameDescription
releaseCompiler operates in release mode (—release CLI option)
debugCompiler generates debug symbols (without —no-debug CLI option)
staticCompiler creates a statically linked executable (—static CLI option)
docsCode is processed to generate API docs (crystal docs command)

User-provided flags

User-provided flags are not defined automatically. They can be passed to the compiler via the --define or -D command line options.

These flags usually enable certain features which activate breaking new or legacy functionality, a preview for a new feature, or entirely alternative behaviour (e.g. for debugging purposes).

  1. $ crystal eval -Dfoo 'puts {{ flag?(:foo) }}'
  2. true

Stdlib features

Flag nameDescription
gc_noneDisables garbage collection (#5314)
debug_raiseDebugging flag for raise logic. Prints the backtrace before raising.
preview_mtEnables multithreading preview. Introduced in 0.28.0 (#7546)
strict_multi_assignEnable strict semantics for one-to-many assignment. Introduced in 1.3.0 (#11145, #11545)
skip_crystal_compiler_rtExclude Crystal’s native compiler-rt implementation.

Compiler features

Flag nameDescription
without_opensslBuild the compiler without OpenSSL support
without_zlibBuild the compiler without Zlib support
without_playgroundBuild the compiler without playground (crystal play)
i_know_what_im_doingSafety guard against involuntarily building the compiler
no_number_autocastWill not autocast numeric expressions, only literals

User code features

Custom flags can be freely used in user code as long as they don’t collide with compiler-provided flags or other user-defined flags. When using a flag specific to a shard, it’s recommended to use the shard name as a prefix.