【发布时间】:2019-12-06 22:57:32
【问题描述】:
在大型项目上运行cmake时,是否可以并行调用给定的cmake函数?
我担心的是,当这个(用户定义的)函数在缓存中存储一些东西时,会与并行执行发生冲突;当函数确实是并行执行时,cmake 如何处理这个问题,或者我是否必须确保即使对同一函数的调用也永远不会使用具有不同值的相同(缓存)变量名?
编辑(见 cmets):
我写了以下函数,
function(CW_SYS_CACHELINE_SIZE)
if (NOT DEFINED CACHE{cw_cv_sys_cacheline_size})
set(CMAKE_TRY_COMPILE_CONFIGURATION "Release")
try_run(RUN_WORKS
COMPILE_WORKS
${CMAKE_CURRENT_BINARY_DIR}/cw_utils_sys_cacheline_size
${CW_SYS_CACHELINE_SIZE_MODULE_PATH}/CW_SYS_CACHELINE_SIZE.c
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
RUN_OUTPUT_VARIABLE RUN_OUTPUT)
if (NOT COMPILE_WORKS)
message(FATAL_ERROR "Failed to compile test program
CW_SYS_CACHELINE_SIZE.c: ${COMPILE_OUTPUT}")
elseif (NOT RUN_WORKS EQUAL 0)
message(FATAL_ERROR "Failed to run test program CW_SYS_CACHELINE_SIZE.c: ${RUN_OUTPUT}")
else ()
set(cw_cv_sys_cacheline_size ${RUN_OUTPUT} CACHE INTERNAL "")
endif ()
endif()
endfunction()
由于此函数不带参数,因此每次使用的变量的内部值都应相同;但我还有其他非常相似的函数,它们做的事情几乎完全相同,只是它们编译和测试不同的.c 文件。
因此,这些函数中的每一个都可以有不同的值RUN_WORKS,它(事实证明)作为INTERNAL 写入缓存。假设我没有终止程序,而是在此处使用 RUN_WORKS 的值执行其他操作。那么可能是我首先运行RUN_WORKS 为真的这个函数,然后运行另一个将RUN_WORKS 设置为假的函数。
如果然后我再次运行 cmake(或无意中再次调用第一个函数),
那么它无法知道缓存中RUN_WORKS 的当前值是否与之前运行的 THIS 函数(和/或相同的参数,如果有的话)有任何关系。因此,它不能使用缓存变量的值。但是 - cmake 正在缓存它。这让我很担心;如果它不打算以后重用它的值,它为什么要缓存任何东西?如果不考虑这些变量,我会感觉好多了。
所以,我的理由是:如果有任何东西被缓存(INTERNAL 或没有),我必须确保它是 100% 唯一的(也就是说,cmake 将始终将相同的值写入同一个变量,否则它不会首先缓存它是没有意义的)。但是如何使用这个RUN_WORKS 变量来做到这一点?我只是对如何编写这样的安全代码感到非常困惑:/
【问题讨论】:
-
我不认为我遵循.. cmake 脚本不同时执行,cmake 脚本按顺序执行。 Cmake 不“处理”并行执行的函数,因为他不并行执行它们。这能回答你的问题吗?
-
是的,如果你确定……我读到某处确实发生了并行执行(我想加快速度)。那么为何不?理论上是可以的。我能想到这永远不会发生的唯一原因是,当明确记录所有 cmake 执行都是单线程时。
-
它发生在构建阶段以及在 execute_process 中执行多个命令时。这两件事都不是功能,也不会修改缓存。
And why not?- 因为 cmake 与速度无关,它应该运行一次。 -
也许考虑切换你的构建系统,例如bazel.build - 即使在集群上也可以并行运行
-
@KamilCuk 好的,我更新了我的问题,解释了为什么我担心某些仅“本地”设置然后使用(然后可能被丢弃)的变量不是唯一的:cmake 确实缓存了它们。为什么??
标签: cmake