如何将所有变量传递给单独的CMake实例?

时间:2014-02-14 00:36:31

标签: variables cmake parameter-passing execution

我想弄清楚如何有效地将所有CMake变量传递给CMake的另一个执行步骤。 有一种方法get all the variables,但我希望有一个有效的选择,除了循环每个变量并将字符串与set()一起追加如下:

 get_cmake_property(_variableNames VARIABLES)
 foreach (_variableName ${_variableNames})
    if(NOT ${_variablename} STREQUAL BASIS_PROPERTIES_ON_TESTS_RE)
      set(ALL_VARIABLES_COMMAND_LINE "${ALL_VARIABLES_COMMAND_LINE} -D ${_variableName}=\"${${_variableName}}\"\n")
    endif()
 endforeach()

 execute_process (
    COMMAND "${CMAKE_COMMAND}" ${COMMON_ARGS}
            -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}"
            -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}"
            -D "EXTENSIONS=${EXTENSIONS}"
            ${ALL_VARIABLES_COMMAND_LINE}
            -D "CMAKE_FILE=${CMAKE_FILE}"
            -P "${BASIS_MODULE_PATH}/ConfigureIncludeFiles.cmake"
    RESULT_VARIABLE RT
  )

该方法的问题在于它会使转义字符混乱,并且在某些情况下无法执行程序。

注意:我目前将所有变量写入磁盘并从那里重新加载,但该操作需要1/2秒。由于我需要为超过100个独立包运行此脚本,因此该技术的额外配置时间过长。

2 个答案:

答案 0 :(得分:0)

好吧,我不是将整个变量列表作为命令行参数传递,而是形成一个新的(临时)CMake脚本(带file(WRITE...)),它设置所有必需的变量,然后用另一个实例执行该脚本CMAke(execute_process(COMMAND ${CMAKE_COMMAND} -P /path/to/script...))。因此,你可以避免与bash逃避作斗争的必要性。

当然,在编写文件时,您也需要转义变量值,但在CMake的情况下,这是一个更简单的任务。似乎基本的逃避应该如下:

 set(VAR "A String with \" and \\ ")
 message(STATUS "VAR=[${VAR}]")

 string(REPLACE "\\" "\\\\" VAR_ ${VAR}) # escape \
 string(REPLACE "\"" "\\\"" VAR_ ${VAR_}) # escape "

 file(WRITE file.cmake "SET(VAR \"${VAR_}\")\n" )
 file(APPEND file.cmake "message(STATUS \"VAR=[\${VAR}]\")\n")

此cmake脚本创建另一个名为file.cmake的cmake脚本,该脚本打印与第一个脚本相同的变量。

答案 1 :(得分:0)

我假设您正在使用CMake BASIS项目中的ConfigureIncludeFiles模块。改善项目配置时间的一种方法是将ConfigureIncludeFiles作为包含脚本运行。

不是在使用ConfigureIncludeFiles启动的CMake子进程中运行execute_process,而是将主CMake进程中的模块作为CMake脚本运行,并使用include命令为每个需要的包启动配置,即:

# set up parameters for package 1
set (PROJECT_INCLUDE_DIRS ${PACKAGE1_INCLUDE_DIRS})
set (BINARY_INCLUDE_DIR ${PACKAGE1_BINARY_INCLUDE_DIR})
set (EXTENSIONS ${PACKAGE1_EXTENSIONS})
set (CMAKE_FILE ${PACKAGE1_CMAKE_FILE})
include(ConfigureIncludeFiles)
...
# set up parameters for package 2
set (PROJECT_INCLUDE_DIRS ${PACKAGE2_INCLUDE_DIRS})
set (BINARY_INCLUDE_DIR ${PACKAGE2_BINARY_INCLUDE_DIR})
set (EXTENSIONS ${PACKAGE2_EXTENSIONS})
set (CMAKE_FILE ${PACKAGE2_CMAKE_FILE})
include(ConfigureIncludeFiles)

因为模块在主CMake过程中运行,它将隐式访问定义的所有CMake变量,并且不需要显式传递变量。