How to call a function in CMake whose name is stored in a variable
Just a quick update: It seems like CMake added this functionality in the current 3.18 Versions via the cmake_language command, the Syntax:
cmake_language(CALL <command> [<args>...])
cmake_language(EVAL CODE <code>...)
Reference for cmake_language https://cmake.org/cmake/help/v3.18/command/cmake_language.html#command:cmake_language
I have solved this with a workaround using files.
Lets say you have:
function(do what)
...
endfunction()
You want to call different specializations depending on 'what'. You can then do:
function(do what)
include("do-${what}.cmake")
do_dynamic()
endfunction()
And in file do-something.cmake:
function(do_dynamic)
...
endfunction()
You can create as many specialization files as you want...
Hi I have written eval
for cmake (and it is as fast as i can make it)
here and here is the code as it is part of my cmakepp library.
I have written two versions of eval
(eval
and eval_ref
because the first does not give you access to the PARENT_SCOPE
whereas the latter does)
however this will only help if your use cmakepp and as that might be a dealbreaker for you I modified it to work with 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()