如何在自定义CMake命令中包含文字双引号?

Dev*_*ane 8 quotes escaping cmake literals

我正在尝试创建一个与某些环境变量一起运行的自定义命令,例如LDFLAGS,如果它包含空格,则需要引用它的值:

LDFLAGS="-Lmydir -Lmyotherdir"
Run Code Online (Sandbox Code Playgroud)

由于CMake的转义规则,我无法找到将此参数包含在CMake自定义命令中的方法.这是我到目前为止所尝试的:

COMMAND LDFLAGS="-Ldir -Ldir2" echo blah VERBATIM)
Run Code Online (Sandbox Code Playgroud)

产量 "LDFLAGS=\"-Ldir -Ldir2\"" echo blah

COMMAND LDFLAGS=\"-Ldir -Ldir2\" echo blah VERBATIM)
Run Code Online (Sandbox Code Playgroud)

产量 LDFLAGS=\"-Ldir -Ldir2\" echo blah

似乎我要么引用整个字符串,要么在作为命令的一部分使用时,转义的引号不会解析.

我希望既可以包含文字双引号,也可以作为为命令设置环境变量的更好方法.请注意,我仍然使用CMake 2.8,因此我没有在3.2中使用新的"env"命令.

请注意,这与何时引用变量不重复因为这些引用方法都不适用于这种特殊情况.

ula*_*ekh 11

您需要三个反斜杠。我最近需要这个来从 PkgConfig 获取预处理器定义并将其应用到我的 C++ 标志:

pkg_get_variable(SHADERDIR movit shaderdir)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSHADERDIR=\\\"${SHADERDIR}\\\"")
Run Code Online (Sandbox Code Playgroud)

  • @spawn:不,我只是搞乱了它,直到它达到了我想要的效果。 (3认同)

Flo*_*ian 6

显而易见的选择 - 通常建议在遇到COMMAND特别是旧版本的CMake 的边界时- 使用外部脚本.

我只是想添加一些简单的COMMAND变体,它们可以正常运行而且不需要shell,但是 - 我必须承认 - 仍然部分依赖于平台.

  • 一个例子是只将引用的部分放入变量中:

    set(vars_as_string "-Ldir -Ldir2")
    add_custom_target(
        QuotedEnvVar
        COMMAND env LD_FLAGS=${vars_as_string} | grep LD_FLAGS
    )
    
    Run Code Online (Sandbox Code Playgroud)

    这实际上逃脱了空间而不是引号.

  • 另一个例子是使用转义引号作为"启动器"规则添加它:

    add_custom_target(
        LauncherEnvVar
        COMMAND env | grep LD_FLAGS
    )
    set_target_properties(
        LauncherEnvVar 
        PROPERTIES RULE_LAUNCH_CUSTOM "env LD_FLAGS=\"-Ldir -Ldir2\""
    )
    
    Run Code Online (Sandbox Code Playgroud)

编辑:添加多个引用参数的示例,而无需转义引号

  • 另一个例子是在函数中"隐藏一些复杂性" - 如果要将其添加到所有自定义命令调用中 - 请使用global/directory RULE_LAUNCH_CUSTOM属性:

    function(set_env)
        get_property(_env GLOBAL PROPERTY RULE_LAUNCH_CUSTOM)
        if (NOT _env)
            set_property(GLOBAL PROPERTY RULE_LAUNCH_CUSTOM "env")
        endif()
        foreach(_arg IN LISTS ARGN)
            set_property(GLOBAL APPEND_STRING PROPERTY RULE_LAUNCH_CUSTOM " ${_arg}")
        endforeach()
    endfunction(set_env)
    
    set_env(LDFLAGS="-Ldir1 -Ldir2" CFLAGS="-Idira -Idirb")
    
    add_custom_target(
        MultipleEnvVar
        COMMAND env | grep -E 'LDFLAGS|CFLAGS'
    )
    
    Run Code Online (Sandbox Code Playgroud)

替代方案(对于CMake> = 3.0)

  • 我认为我们实际上在这里寻找的(除了cmake -E env ...)名为Bracket Argument并且允许任何角色而不需要添加反斜杠:

    set_property(
        GLOBAL PROPERTY 
            RULE_LAUNCH_CUSTOM [=[env LDFLAGS="-Ldir1 -Ldir2" CFLAGS="-Idira -Idirb"]=]
    )
    add_custom_target(
        MultipleEnvVarNew
        COMMAND env | grep -E 'LDFLAGS|CFLAGS'
    )
    
    Run Code Online (Sandbox Code Playgroud)

参考