跳至内容

编译时标志

编译时标志是通过宏方法通过编译器提供的布尔值。它们允许根据编译时条件有条件地包含或排除代码。

编译器提供了一些默认标志,这些标志包含有关编译器选项和目标平台的信息。用户提供的标志传递给编译器,这允许它们用作特性标志。

查询标志

标志只是一个命名标识符,它要么被设置,要么没有被设置。可以通过宏方法从代码中查询状态 flag?。它接收标志的名称作为字符串或符号字面量,并返回一个布尔字面量,指示标志的状态。

以下程序展示了通过打印目标操作系统系列来使用编译时标志。

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

还有一个宏方法 host_flag?,它返回标志是否针对主机平台设置,在交叉编译期间,这可能与目标平台(通过 flag? 查询)不同。

编译器提供的标志

编译器定义了一些隐式标志。它们描述了目标平台或编译器选项。

目标平台标志

特定于平台的标志来自 目标三元组。有关支持的目标平台列表,请参见 平台支持

crystal --version 显示编译器的默认目标三元组。它可以通过 --target 选项更改。

以下每个表中的标志都是互斥的,除了标记为(派生)的那些。

体系结构

目标体系结构是目标三元组的第一个组件。

标志名称 描述
aarch64 AArch64 体系结构
avr AVR 体系结构
arm ARM 体系结构
i386 x86 体系结构(32 位)
wasm32 WebAssembly
x86_64 x86-64 体系结构
bits32 (derived) 32 位体系结构
bits64 (derived) 64 位体系结构

供应商

供应商是目标三元组的第二个组件。这通常未使用,因此最常见的供应商是 unknown

标志名称 描述
macosx Apple
portbld FreeBSD 变体
unknown 未知供应商

操作系统

操作系统是从目标三元组的第三个组件派生的。

标志名称 描述
bsd (derived) BSD 家族 (DragonFlyBSD、FreeBSD、NetBSD、OpenBSD)
darwin Darwin (MacOS)
dragonfly DragonFlyBSD
freebsd FreeBSD
linux Linux
netbsd NetBSD
openbsd OpenBSD
solaris Solaris/illumos
unix (derived) 类 Unix (BSD、Darwin、Linux、Solaris)
windows Windows

ABI

ABI 从目标三元组的最后一个组件派生。

标志名称 描述
android Android (Bionic C 运行时)
armhf (derived) 带硬浮点的 ARM EABI
gnu GNU
gnueabihf 带硬浮点的 GNU EABI
msvc Microsoft Visual C++
musl musl
wasi Web Assembly System Interface
win32 (derived) Windows API

编译器选项

编译器根据编译器配置设置这些标志。

标志名称 描述
release 编译器以发布模式运行 (--release-O3 --single-module CLI 选项)
debug 编译器生成调试符号(不使用 --no-debug CLI 选项)
static 编译器创建一个静态链接的可执行文件 (--static CLI 选项)
docs 代码被处理以生成 API 文档 (crystal docs 命令)
interpreted 在解释器中运行 (crystal i)

用户提供的标志

用户提供的标志不会自动定义。它们可以通过 --define-D 命令行选项传递给编译器。

这些标志通常启用某些功能,这些功能会激活突破性的新功能或旧功能,新功能的预览,或者完全不同的行为(例如,用于调试目的)。

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

标准库功能

这些标志在构建 Crystal 程序时启用或禁用标准库中的功能。

标志名称 描述
gc_none 禁用垃圾回收 (#5314)
debug_raise raise 逻辑的调试标志。在抛出异常之前打印回溯。
preview_mt 启用多线程预览。在 0.28.0 中引入 (#7546)
skip_crystal_compiler_rt 排除 Crystal 的本机 compiler-rt 实现。
tracing 构建时支持 运行时跟踪
use_libiconv 使用 libiconv 而不是 iconv 系统库
use_pcre2 使用 PCRE2 作为正则表达式引擎(而不是旧的 PCRE)。在 1.7.0 中引入。
use_pcre 使用 PCRE 作为正则表达式引擎(而不是 PCRE2)。在 1.8.0 中引入。
win7 对 Windows 7 使用 Win32 WinNT API
without_iconv 不要链接 iconv/libiconv
without_openssl 在没有 OpenSSL 支持的情况下构建
without_zlib 在没有 Zlib 支持的情况下构建

编译器功能

这些标志在构建 Crystal 程序时启用或禁用编译器功能。

标志名称 描述
no_number_autocast 不会 自动转换 数字表达式,只转换字面量
no_restrictions_augmenter 禁用增强的限制增强器。在 1.5 中引入 (#12103).
preview_dll 在 Windows 上启用动态链接;实验性
preview_overload_order 启用更健壮的 def 重载之间的排序。在 1.6 中引入 (#10711).
preview_win32_delay_load 延迟加载 Windows 上的所有 DLL;实验性
strict_multi_assign 启用对 一对多赋值 的严格语义。在 1.3.0 中引入 (#11145#11545)

编译器构建功能

这些标志在构建 Crystal 编译器时启用或禁用功能。

标志名称 描述
without_ffi 在没有 libffi 的情况下构建编译器
without_interpreter 在没有解释器支持的情况下构建编译器
without_playground 在没有 playground(crystal play)的情况下构建编译器
i_know_what_im_doing 防止无意中构建编译器的安全保护

用户代码功能

只要不与编译器提供的标志或其他用户定义的标志冲突,用户代码中就可以自由使用自定义标志。使用特定于 shard 的标志时,建议使用 shard 名称作为前缀。