Do not expand CMake list variable

筅森魡賤 提交于 2020-04-16 06:04:09

问题


I have a CMake script that runs some tests via add_test(), running under Windows (Server 2008, don't ask) in CMake 3.15. When these tests are called, the PYTHONPATH environment variable in the environment they run in seems to get reset to the environment default, and doesn't contain some paths that it needs to.

I therefore need to set PYTHONPATH when the tests are run to the value of the $ENV{PYTHONPATH} variable when CMake runs. This has a number of semicolon-separated paths, so CMake thinks it's a list and tries to expand it into a number of space-separated strings, which obviously ends badly.

I cannot work out how to stop CMake doing this. From everything I can see, you should be able to do just surround with quotes:

add_test(
  NAME mytest
  COMMAND cmake -E env PYTHONPATH="$ENV{PYTHONPATH}"
  run_test_here)

...but it always does the expansion. I also tried setting with set_tests_properties:

set_tests_properties(mytest PROPERTIES
    ENVIRONMENT PYTHONPATH="$ENV{PYTHONPATH}")

...but that didn't appear to do anything at all - PYTHONPATH at test time wasn't altered. I thought it was because it's an environment variable, but using a regular CMake variable via set() makes no difference, so I'm doing something wrong. Help please!


回答1:


The following should work:

COMMAND cmake -E env "PYTHONPATH=$ENV{PYTHONPATH}"

You need to quote the full part of the command line, to make properly expanded message.

Tested with:

set(tmp "C:\\Python27\\Scripts;E:\\JenkinsMIDEBLD\\workspace\\...;...")
add_test(NAME MYtest1 COMMAND cmake -S . -E env "tmp=${tmp}") 
add_test(NAME MYtest2 COMMAND cmake -S . -E env tmp="${tmp}") 

After running ctest I get:

1: Test command: /bin/cmake "-S" "." "-E" "env" "tmp=C:\Python27\Scripts;E:\JenkinsMIDEBLD\workspace\...;..."
2: Test command: /bin/cmake "-S" "." "-E" "env" "tmp="C:\Python27\Scripts" "E:\JenkinsMIDEBLD\workspace\..." "...""

The first test has proper ; passed to var, while the second one passes space separated list.

This is how cmake parses quoted arguments. An argument is either fully quoted or not quoted at all - partial quotes are interpreted as a literal ". So assumnig that:

set(var a;b;c)

The following:

var="$var"

Is not a quoted argument and " are taken literally! It expands the $var list into space separated list and the " stay, there is one " between = and a, and there is additional " on the end. The var="$var" is equal to:

var=\"a b c\"
    ^^     ^^    - the quotes stay!
^^^^^^^ ^ ^^^    - these are 3 arguments, the last one is `c"`

Without quotes is:

var=$var

is equal to (notice the missing quotes):

var=a c c

To quotes argument you have to quote it all, with first and last character of the element beeing ":

"var=$var"

will expand to:

"var=a;b;c"


来源:https://stackoverflow.com/questions/58657817/do-not-expand-cmake-list-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!