我想弄清楚如何有效地将所有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个独立包运行此脚本,因此该技术的额外配置时间过长。
答案 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变量,并且不需要显式传递变量。