You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅在Meson的Debug构建中启用Sanitizers?

问题描述

我希望仅在Debug构建中启用Sanitizers,且不想手动添加编译标志(手动添加无法实现跨平台/跨编译器兼容)。但使用以下配置时,Meson将b_sanitize=address,undefined当作文件路径传递给编译器,导致报错。当前环境为Linux Fedora Asahi Remix,使用Meson v1.3.1。

错误配置代码

project(
  'Foo',
  'c',
  version: '0.0.1',
  license: 'GPL-3.0-or-later',
  meson_version: '>= 0.64.0',
  default_options: [
      'c_std=c2x',
      'warning_level=everything',
  ],
)

# 问题代码段:尝试仅在Debug构建启用Sanitizer,Release构建启用-Werror
if get_option('buildtype').startswith('debug')
  message('Building a debug release')
  add_project_arguments('b_sanitize=address,undefined', language: 'c')
else
  add_project_arguments(['werror=true'], language: 'c')
endif

foo_sources = files('main.c')

executable(
  meson.project_name().to_lower(),
  foo_sources,
)

错误输出

$ LC_MESSAGES=C meson compile --verbose -C builddir
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /usr/bin/ninja -C /home/jan/Projekte/Own/Tmp/builddir -v
ninja: Entering directory `/home/jan/Projekte/Own/Tmp/builddir'
[1/2] ccache cc -Ifoo.p -I. -I.. -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -Wcast-qual -Wconversion -Wfloat-equal -Wformat=2 -Winline -Wmissing-declarations -Wredundant-decls -Wshadow -Wundef -Wuninitialized -Wwrite-strings -Wdisabled-optimization -Wpacked -Wpadded -Wmultichar -Wswitch-default -Wswitch-enum -Wunused-macros -Wmissing-include-dirs -Wunsafe-loop-optimizations -Wstack-protector -Wstrict-overflow=5 -Warray-bounds=2 -Wlogical-op -Wstrict-aliasing=3 -Wvla -Wdouble-promotion -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines -Wvector-operation-performance -Wsuggest-attribute=format -Wdate-time -Wformat-signedness -Wnormalized=nfc -Wduplicated-cond -Wnull-dereference -Wshift-negative-value -Wshift-overflow=2 -Wunused-const-variable=2 -Walloca -Walloc-zero -Wformat-overflow=2 -Wformat-truncation=2 -Wstringop-overflow=3 -Wduplicated-branches -Wcast-align=strict -Wsuggest-attribute=cold -Wsuggest-attribute=malloc -Wattribute-alias=2 -Wanalyzer-too-complex -Warith-conversion -Wbidi-chars=ucn -Wopenacc-parallelism -Wtrivial-auto-var-init -Wbad-function-cast -Wmissing-prototypes -Wnested-externs -Wstrict-prototypes -Wold-style-definition -Winit-self -Wc++-compat -Wunsuffixed-float-constants -std=c2x -O0 -g b_sanitize=address,undefined -MD -MQ foo.p/main.c.o -MF foo.p/main.c.o.d -o foo.p/main.c.o -c ../main.c
FAILED: foo.p/main.c.o 
ccache cc -Ifoo.p -I. -I.. -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -Wcast-qual -Wconversion -Wfloat-equal -Wformat=2 -Winline -Wmissing-declarations -Wredundant-decls -Wshadow -Wundef -Wuninitialized -Wwrite-strings -Wdisabled-optimization -Wpacked -Wpadded -Wmultichar -Wswitch-default -Wswitch-enum -Wunused-macros -Wmissing-include-dirs -Wunsafe-loop-optimizations -Wstack-protector -Wstrict-overflow=5 -Warray-bounds=2 -Wlogical-op -Wstrict-aliasing=3 -Wvla -Wdouble-promotion -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines -Wvector-operation-performance -Wsuggest-attribute=format -Wdate-time -Wformat-signedness -Wnormalized=nfc -Wduplicated-cond -Wnull-dereference -Wshift-negative-value -Wshift-overflow=2 -Wunused-const-variable=2 -Walloca -Walloc-zero -Wformat-overflow=2 -Wformat-truncation=2 -Wstringop-overflow=3 -Wduplicated-branches -Wcast-align=strict -Wsuggest-attribute=cold -Wsuggest-attribute=malloc -Wattribute-alias=2 -Wanalyzer-too-complex -Warith-conversion -Wbidi-chars=ucn -Wopenacc-parallelism -Wtrivial-auto-var-init -Wbad-function-cast -Wmissing-prototypes -Wnested-externs -Wstrict-prototypes -Wold-style-definition -Winit-self -Wc++-compat -Wunsuffixed-float-constants -std=c2x -O0 -g b_sanitize=address,undefined -MD -MQ foo.p/main.c.o -MF foo.p/main.c.o.d -o foo.p/main.c.o -c ../main.c
cc: warning: b_sanitize=address,undefined: linker input file unused because linking not done
cc: error: b_sanitize=address,undefined: linker input file not found: No such file or directory
ninja: build stopped: subcommand failed.
解决方案

问题根源是把Meson内置选项字符串直接传给了add_project_arguments——该函数用于传递编译器原生命令行参数,而b_sanitize、werror是Meson的全局配置选项,需用set_option()设置,Meson会自动将这些选项转换为对应编译器的正确标志,实现跨平台兼容。

修改后的配置代码:

project(
  'Foo',
  'c',
  version: '0.0.1',
  license: 'GPL-3.0-or-later',
  meson_version: '>= 0.64.0',
  default_options: [
      'c_std=c2x',
      'warning_level=everything',
  ],
)

# 根据构建类型设置对应全局选项
if get_option('buildtype').startswith('debug')
  message('Building a debug release')
  # 设置Sanitizer,Meson自动适配编译器/链接器标志
  set_option('b_sanitize', 'address,undefined')
else
  # 发布构建启用Werror
  set_option('werror', true)
endif

foo_sources = files('main.c')

executable(
  meson.project_name().to_lower(),
  foo_sources,
)

补充说明

  • set_option()是Meson修改全局配置选项的官方方式,支持所有内置选项(如b_sanitize、werror、lto等),能自动处理不同编译器的差异(比如GCC和Clang的Sanitizer标志差异)。
  • 若需为特定目标而非全项目启用Sanitizer,可使用编译器对象的get_sanitization_flags()方法,示例:
    c_compiler = meson.get_compiler('c')
    sanitizer_flags = c_compiler.get_sanitization_flags(['address', 'undefined'])
    executable(
      'foo',
      foo_sources,
      c_args: sanitizer_flags,
      link_args: sanitizer_flags,
    )
    
    这种方式需手动处理编译和链接阶段的标志,适合局部启用场景,全局set_option()则更简洁高效。

内容的提问来源于stack exchange,提问作者user23276701

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:28:12