在cmake中使用特定于平台的分隔符的正确方法

时间:2015-09-15 12:19:36

标签: cmake cross-platform

您好亲爱的stackoverflowers!

我想知道我的问题是否有更好的解决方案。我正在开发一个独立于平台的软件项目,并希望将基于python的单元测试添加到cmake。我现在遇到的问题是,在配置ctest测试并设置正确的PYTHONPATH环境变量以运行我的测试时,我最终会为每个测试提供大量的样板代码:

add_test(my_awesome_test ${PYTHON_EXECUTABLE} my_awesome_test.py)

if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
  set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath\;anotherpath")
else() # e.g. Linux
  set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath:anotherpath")
endif()

# more tests like this after this...

这里的问题是分支,这只是因为平台相关的列表分隔符才需要。

有没有更简洁的方法来实现这一目标?

是否有一个常量指定平台分隔符或允许我构建这些列表的函数?

如果没有“正确”的答案,我也想分享我明显但不那么好的解决方案:

if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
  set(SEP "\\;")
else() # e.g. Linux
  set(SEP ":")
endif()

add_test(my_awesome_test ${PYTHON_EXECUTABLE} my_awesome_test.py)
set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=somepath${SEP}anotherpath")

# more tests like this after this...

在Windows上“;”必须进行双重转义,否则它将在add_test行中稍后替换为单个“;”再次,然后将其解释为导致错误结果的cmake-list分隔符。但是,让cmake报告哪个字符应该用作列表分隔符仍然会更好......

3 个答案:

答案 0 :(得分:1)

很遗憾,file(TO_NATIVE_PATH ...不能在Unix平台上将;转换为:。我认为最简单的方法就是这样:

set(PATH "/usr/bin" "/bin")

if (UNIX)
  string(REPLACE ";" ":" PATH "${PATH}")
endif()

之所以可行,是因为CMake列表实际上是由;分隔的字符串,因此在Windows上,您可以按原样使用它们作为路径列表。它不适用于包含;:的路径,但是无论如何它都会使99%的Unix软件跳闸,所以我不用担心。

答案 1 :(得分:0)

您可以定义函数/宏,将某些选择的分隔符转换为特定于平台的分隔符。例如,下面的函数将CMake列表转换为特定于平台的路径列表:

function(to_path_list var path1)
    if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
        set(sep "\\;")
    else()
        set(sep ":")
    endif()
    set(result "${path1}") # First element doesn't require separator at all...
    foreach(path ${ARGN})
        set(result "${result}${sep}${path}") # .. but other elements do.
    endforeach()
    set(${var} "${result}" PARENT_SCOPE)
endfunction()

用法:

to_path_list(pythonpath "somepath" "anotherpath")
set_tests_properties(my_awesome_test PROPERTIES ENVIRONMENT "PYTHONPATH=${pythonpath}")

答案 2 :(得分:0)

您可以使用以下文件功能:

file(TO_CMAKE_PATH "<path>" <variable>)
file(TO_NATIVE_PATH "<path>" <variable>)

https://cmake.org/cmake/help/v3.9/command/file.html