【问题标题】:CMake generator expression with duplicated compile flags具有重复编译标志的 CMake 生成器表达式
【发布时间】:2021-05-22 18:24:29
【问题描述】:

我正在尝试使用 CMake generator expressions 进行编译器相关配置。此配置的一部分是使用包含目录列表设置编译器标志,类似于CMake has in their documentation。但是由于某种原因,在这种情况下,JOIN 表达式对我来说不能正常工作。这是一个简化的例子:

cmake_minimum_required(VERSION 3.6)
project(NinjaPlayground)

add_executable(NinjaPlayground main.cpp)
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libraryOne/include")
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/librartTwo/include")

target_compile_options(NinjaPlayground PRIVATE
                        $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-isystem $<JOIN:${LIB_INCLUDE_DIRS}, -isystem >>
                        $<$<CXX_COMPILER_ID:MSVC>:-experimental:external -external:w -external:I $<JOIN:${LIB_INCLUDE_DIRS}, -external:I >>)

如果我在 UNIX 系统中构建它,此配置生成的命令如下所示:

/usr/bin/c++ <b>-isystem /home/the-dreams-wind/Documents/Ninja/libraryOne/include /home/the-dreams-wind/Documents/Ninja/librartTwo/include</b> -MD -MT CMakeFiles/NinjaPlayground.dir/main.cpp.o -MF CMakeFiles/NinjaPlayground.dir/main.cpp.o.d -o CMakeFiles/NinjaPlayground.dir/main.cpp.o -c ../main.cpp

如您所见,列表已展开,但连接表达式忽略了它。我还尝试引用这些论点:

target_compile_options(NinjaPlayground PRIVATE
                        "$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-isystem $<JOIN:${LIB_INCLUDE_DIRS}, -isystem >>"
                        "$<$<CXX_COMPILER_ID:MSVC>:-experimental:external -external:w -external:I $<JOIN:${LIB_INCLUDE_DIRS}, -external:I >>")

它正确地连接字符串,但在参数列表中保留引号:

/usr/bin/c++ <b>"-isystem /home/the-dreams-wind/Documents/Ninja/libraryOne/include -isystem /home/the-dreams-wind/Documents/Ninja/librartTwo/include"</b> -MD -MT CMakeFiles/NinjaPlayground.dir/main.cpp.o -MF CMakeFiles/NinjaPlayground.dir/main.cpp.o.d -o CMakeFiles/NinjaPlayground.dir/main.cpp.o -c ../main.cpp

MSVC 也会出现同样的问题。为了清楚起见,我期望的结果应该是这样的:

/usr/bin/c++ <b>-isystem /home/the-dreams-wind/Documents/Ninja/libraryOne/include -isystem /home/the-dreams-wind/Documents/Ninja/librartTwo/include</b> -MD -MT CMakeFiles/NinjaPlayground.dir/main.cpp.o -MF CMakeFiles/NinjaPlayground.dir/main.cpp.o.d -o CMakeFiles/NinjaPlayground.dir/main.cpp.o -c ../main.cpp

我知道我可以遍历列表并一一添加选项,但是我想了解我在这里缺少什么?

【问题讨论】:

  • 据我最近对$&lt;JOIN&gt; 的测试记得,它不适用于显式 列表或变量 中的列表.这是因为列表“破坏”了正则表达式本身。 $&lt;JOIN&gt;的用法是处理properties-I$&lt;JOIN:$&lt;TARGET_PROPERTY:INCLUDE_DIRECTORIES&gt;, -I&gt;。对于常规列表,请使用 string(JOIN) 命令流。

标签: c++ cmake


【解决方案1】:

玩了一段时间后,发现问题归结为空格和参数重复数据删除。部分可以通过删除选项(例如-systemi)与其参数(路径)之间的空格来处理。然而,有些标志无法避免重复(如-Xclang 选项)。为了抑制重复数据删除the prefix SHELL: was introduced in CMake 3.12。它保留空格,正确解析参数,可以像这样使用:

target_compile_options(NinjaPlayground PRIVATE
                        "$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:SHELL:-isystem$<JOIN:${LIB_INCLUDE_DIRS}, -isystem>>"
                        "$<$<CXX_COMPILER_ID:MSVC>:SHELL:-experimental:external -external:w -external:I$<JOIN:${LIB_INCLUDE_DIRS}, -external:I>>")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多