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

CMake中set_property设置COMPILE_FLAGS时分号替代空格问题解决

解决CMake中SOURCE属性COMPILE_FLAGS选项分号分隔问题

问题场景

为文件夹内部分C文件设置特殊编译选项,尝试用set_property的两种方式配置(列表定义、直接写入),但生成的Make命令中编译选项被分号分隔,导致编译异常:

原始CMake代码

cmake_minimum_required(VERSION 3.16)

file(GLOB_RECURSE all_sources "./*.c" "./*.S")

set(CURRENT_LIB_NAME my_c_library)
enable_language(ASM)
set(c_flags
    -msse4.1
    # some other flags
)

set(c_sandybridge_flags
    -O2
    -march=sandybridge
    -mtune=sandybridge
)
file(GLOB SANDYBRIDGE_SRC_FILES
    "*_slow.c"
    "*_dispatcher.c"
    "arion.c"
)
set_property(SOURCE ${SANDYBRIDGE_SRC_FILES} PROPERTY COMPILE_FLAGS ${c_sandybridge_flags})

file(GLOB HASWELL_SRC_FILES
    "./*_ab2.c"
)
set_property(SOURCE ${HASWELL_SRC_FILES} PROPERTY COMPILE_FLAGS -O2 -mavx2 )

add_compile_options(
    "$<$<COMPILE_LANGUAGE:C>:${c_flags}>"
)

add_library(${CURRENT_LIB_NAME} STATIC
    ${all_sources}
)

target_include_directories(${CURRENT_LIB_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/mylibrary/include)

生成的错误编译命令示例

/usr/bin/clang -Isomeinclude -msse4.1 -O2;-march=sandybridge;-mtune=sandybridge -MD -MT CMakeFiles/c_file.c.o -MF CMakeFiles/c_file.c.o.d -o CMakeFiles/c_file.c.o -c lib/c_file.c

问题原因

CMake的COMPILE_FLAGS属性接收的是单个字符串,而非列表。当直接传入列表变量(如${c_sandybridge_flags})时,CMake会将列表元素用分号拼接成字符串;直接写多个参数(如-O2 -mavx2)时,会被识别为多个列表元素,最终同样被分号连接。

解决方法

1. 列表定义的编译选项:转为空格分隔字符串

使用CMake的$<JOIN:...>生成器表达式,将列表元素用空格连接后传入:

set_property(SOURCE ${SANDYBRIDGE_SRC_FILES} PROPERTY COMPILE_FLAGS "$<JOIN:${c_sandybridge_flags}, >")

或者提前用string(JOIN)处理列表:

string(JOIN " " c_sandybridge_flags_str ${c_sandybridge_flags})
set_property(SOURCE ${SANDYBRIDGE_SRC_FILES} PROPERTY COMPILE_FLAGS ${c_sandybridge_flags_str})

2. 直接写入的编译选项:包裹为单个字符串

将多个编译选项放在双引号内,作为单个字符串传递:

set_property(SOURCE ${HASWELL_SRC_FILES} PROPERTY COMPILE_FLAGS "-O2 -mavx2")

修改后的完整CMake代码

cmake_minimum_required(VERSION 3.16)

file(GLOB_RECURSE all_sources "./*.c" "./*.S")

set(CURRENT_LIB_NAME my_c_library)
enable_language(ASM)
set(c_flags
    -msse4.1
    # some other flags
)

set(c_sandybridge_flags
    -O2
    -march=sandybridge
    -mtune=sandybridge
)
file(GLOB SANDYBRIDGE_SRC_FILES
    "*_slow.c"
    "*_dispatcher.c"
    "arion.c"
)
# 使用JOIN将列表转为空格分隔字符串
set_property(SOURCE ${SANDYBRIDGE_SRC_FILES} PROPERTY COMPILE_FLAGS "$<JOIN:${c_sandybridge_flags}, >")

file(GLOB HASWELL_SRC_FILES
    "./*_ab2.c"
)
# 直接将选项包裹为单个字符串
set_property(SOURCE ${HASWELL_SRC_FILES} PROPERTY COMPILE_FLAGS "-O2 -mavx2")

add_compile_options(
    "$<$<COMPILE_LANGUAGE:C>:${c_flags}>"
)

add_library(${CURRENT_LIB_NAME} STATIC
    ${all_sources}
)

target_include_directories(${CURRENT_LIB_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/mylibrary/include)

内容的提问来源于stack exchange,提问作者Tomáš Zato

相关产品推荐
方舟 Agent Plan

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

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