CMake – 将列表作为字符串传递给CMake脚本的add_custom_target函数

huangapple go评论59阅读模式
英文:

CMake - Pass a list as a string to add_custom_target for CMake script

问题

add_custom_target 似乎在我不希望的情况下'解包'了列表。看看我正在使用的 add_custom_target 以调用一个 CMake 脚本:

message(STATUS "Sources: ${ARGS_SOURCES}")
add_custom_target(${ARGS_TARGET}
    COMMAND ${CMAKE_COMMAND}
            -DSOURCES="${ARGS_SOURCES}"
            -DOUTPUT_DIR="${ARGS_OUTPUT_DIR}"
            -P "${CMAKE_SOURCE_DIR}/cmake/translation_generator/translation_generator_script.cmake"
    SOURCES ${ARGS_SOURCES}
            "${CMAKE_SOURCE_DIR}/cmake/translation_generator/translation_generator_script.cmake")

消息输出是我期望的,一个由分号分隔的路径列表。

-- Sources: /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml;/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml;/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml

然而,当脚本被调用时,我得到了这个:

/usr/bin/cmake -DSOURCES="/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml" ...

它将列表解包成了以空格分隔的字符串 - 这不是我想要的。

我尝试使用 VERBATIM 标志,但它完全搞乱了调用:

/usr/bin/cmake -DSOURCES=\""/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml\" ...

它转义了双引号。如果我将它们删除:

/usr/bin/cmake -DSOURCES=/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml ...

它保留了空格,破坏了调用脚本。我还尝试过:

list(JOIN ARGS_SOURCES ";" ARGS_SOURCES)

但是似乎解包发生在 add_custom_target 处理中,所以这没有任何区别。

所以我的问题是:如何将一个列表作为分号分隔的字符串传递给 add_custom_target 命令?

英文:

add_custom_target seems to be 'unpacking' lists when I don't want it to. Take this add_custom_target that I'm using to invoke a CMake script:

message(STATUS "Sources: ${ARGS_SOURCES}")
add_custom_target(${ARGS_TARGET}
    COMMAND ${CMAKE_COMMAND}
            -DSOURCES="${ARGS_SOURCES}"
            -DOUTPUT_DIR="${ARGS_OUTPUT_DIR}"
            -P "${CMAKE_SOURCE_DIR}/cmake/translation_generator/translation_generator_script.cmake"
    SOURCES ${ARGS_SOURCES}
            "${CMAKE_SOURCE_DIR}/cmake/translation_generator/translation_generator_script.cmake")

The message output is what I'm expecting, a list of paths separated by semi-colons.

-- Sources: /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml;/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml;/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml

However when the script is invoked, I get this:

/usr/bin/cmake -DSOURCES="/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml" ...

It's unpacked the list into a space separated string - this is not what I want.

I attempted to use the VERBATIM flag but it completely mangled the invocation:

/usr/bin/cmake -DSOURCES=\"/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml\" ...

It's escaping the double quotes. If I remove them:

/usr/bin/cmake -DSOURCES=/home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/en_GB.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/fr.toml /home/cmannett85/workspace/arg_router/examples/resources/simple_ml_gen/ja.toml ...

It keeps the spaces, breaking the called script. I also tried:

list(JOIN ARGS_SOURCES ";" ARGS_SOURCES)

But the unpacking appears to happen in the add_custom_target processing, so this made no difference.

So my question is: How do I pass a list to a add_custom_target command, as a semi-colon separated string?

答案1

得分: 1

CMake引号的使用有些令人困惑。例如:"this" 被引用。例如:th"is" 没有 被引用,而 " 被照字面解释。

在你的示例中,-DSOURCES="${ARGS_SOURCES}" 中的 " 是字面的。因此,ARGS_SOURCES 被拆分,因为它是一个数组,你的程序会接收多个参数,如 '-DSOURCES="elem1' 'elem2' 'elem3' 'elem4"' 带有 " 引号

如果你想在CMake中引用,第一个字符必须是 ",而最后一个字符必须是 "。就像你在 "Sources: ${ARGS_SOURCES}" 中所做的一样。

"-DSOURCES=${ARGS_SOURCES}"

英文:

CMake quoting is confusing. For example: "this" is quoted. For example: th"is" is not quoted, and " are taken literally.

In your example, -DSOURCES="${ARGS_SOURCES}" " are literal. So ARGS_SOURCES is split, as it is an array, and your program receives multiple arguments like '-DSOURCES="elem1' 'elem2' 'elem3' 'elem4"' with the " quotes.

If you want to quote in CMake, the first character has to be " and the last character has to be ". Just like you did with "Sources: ${ARGS_SOURCES}".

"-DSOURCES=${ARGS_SOURCES}"

huangapple
  • 本文由 发表于 2023年6月29日 00:22:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76575057.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定