如何在名称存储在变量中的CMake中调用函数

Rus*_*ene 4 cmake

有没有办法使用存储在变量中的名称(用于将函数传递给函数等)在CMake中调用函数?

这是我尝试过的:

cmake_minimum_required(VERSION 3.0)

function(doThing)
endfunction()

set(FuncVar doThing)

${FuncVar}()
Run Code Online (Sandbox Code Playgroud)

哪个失败了这个错误:

Parse error.  Expected a command name, got unquoted argument with text "${FuncVar}".
-- Configuring incomplete, errors occurred!
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这不起作用,但我又是新来的CMake所以我知道什么.

感谢您的任何帮助!

ben*_*enb 9

只是一个快速更新:似乎 CMake 通过 cmake_language 命令在当前 3.18 版本中添加了此功能,语法:

cmake_language(CALL <command> [<args>...])
cmake_language(EVAL CODE <code>...)
Run Code Online (Sandbox Code Playgroud)

cmake_语言参考 https://cmake.org/cmake/help/v3.18/command/cmake_language.html#command:cmake_language


小智 8

我已经使用文件解决了这个问题.

让我们说你有:

function(do what)
  ...
endfunction()
Run Code Online (Sandbox Code Playgroud)

您想根据"什么"调用不同的专业.然后你可以这样做:

function(do what)
  include("do-${what}.cmake")
  do_dynamic()
endfunction()
Run Code Online (Sandbox Code Playgroud)

在文件do-something.cmake中:

function(do_dynamic)
  ...
endfunction()
Run Code Online (Sandbox Code Playgroud)

您可以根据需要创建任意数量的专业化文件...


小智 6

您好我已经写eval了cmake的(和它是一样快,我可以把它), 在这里这里是代码,因为它是我的一部分cmakepp库。

我写了两个版本的eval(eval并且eval_ref因为第一个不能让你访问PARENT_SCOPE而后者可以)

但是,这只会在您使用 cmakepp 时有所帮助,因为这对您来说可能是一个破坏者,我将其修改为与 vanilla cmake 一起使用:

## evals the specified cmake code.
## WARNING: there is no way to set(<var> <value> PARENT_SCOPE) 
## because of the extra function scope defined by eval.
## WARNING: allowing eval can of course be dangerous.
function(eval __eval_code)

  # one file per execution of cmake (if this file were in memory it would probably be faster...)
  # this is where the temporary eval file will be stored.  it will only be used once per eval
  # and since cmake is not multihreaded no race conditions should occure.  however if you start 
  # two cmake processes in the same project this could lead to collisions
  set(__eval_temp_file "${CMAKE_CURRENT_BINARY_DIR}/__eval_temp.cmake")


  # write the content of temp file and include it directly, this overwrite the 
  # eval function you are currently defining (initializer function pattern)
  file(WRITE "${__eval_temp_file}" "
function(eval __eval_code)
  file(WRITE ${__eval_temp_file} \"\${__eval_code}\")
  include(${__eval_temp_file})
endfunction()
  ")

include("${__eval_temp_file}")
## now eval is defined as what was just written into __eval_temp_file


## since we are still in first definition we just need to execute eval now
## (which calls the second definition of eval).
eval("${__eval_code}")


endfunction()
Run Code Online (Sandbox Code Playgroud)

  • 我还没有测试过它,但最新的 CMake 3.18 具有 eval 函数: `cmake_language(EVAL CODE &lt;code&gt;...)` https://cmake.org/cmake/help/latest/command/cmake_language.html?highlight=cmake_language (3认同)