[CMake] Possible to dynamically construct macro/function names to invoke?

Petr Kmoch petr.kmoch at gmail.com
Mon Aug 10 09:51:18 EDT 2015


Hi, Eric.

On Mon, Jul 20, 2015 at 12:52 AM, Eric Wing <ewmailing at gmail.com> wrote:

> I would like to dynamically construct a macro or function name to
> invoke. I basically have a core CMake system I want users to be able
> to extend/plug stuff into without knowing about a lot of the core
> CMake implementation. Callback functions would be an easy way for me
> to accomplish this.
>
> As an example,
>
> # In my core code, I have a macro designed to callback other macros
> macro(DO_PACKAGE _TARGET_NAME)
>         foreach(callback ${DO_PACKAGE_CALLBACK_LIST})
>                 DO_PACKAGE_FOR_${callback}(${_TARGET_NAME})
>         endforeach()
> endmacro(BLURRR_PACKAGE_EXTRAS)
>
>
> ### Also in my core code, I pick an appropriate time to trigger my
> macro to call user callbacks
> DERIVE_SOME_NAME()
> ADD_EXECUTABLE(${SOME_NAME} ...)
> DO_PACKAGE(${SOME_NAME})
>
>
>
> # So in user modules provided by others, they follow a convention where
> # they define a macro DO_PACKAGE_ appended by their module name.
> macro(DO_PACKAGE_FOR_MYMODULE _TARGET_NAME)
>         MESSAGE("in mymod callback")
>         # do stuff
> endmacro()
>
> # And I make them add their module name to a global list so I can call
> it back at the right time
> list(APPEND DO_PACKAGE_CALLBACK_LIST "MYMODULE")
>
>
> So in my attempts to do this, I'm getting errors like:
> Parse error.  Expected a command name, got unquoted argument with text
>
> Is there way to do this (or something similar)?
>
> Thanks,
> Eric
>

We had need for something similar in our system, and the best we could come
up with was to write the dynamically-named function invocation into a file
and include() it. Something like this:

foreach(callback ${DO_PACKAGE_CALLBACK_LIST})
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/invocation.${callback}.cmake
"DO_PACKAGE_FOR_${callback}(${_TARGET_NAME})\n")
  include(${CMAKE_CURRENT_BINARY_DIR}/invocation.${callback}.cmake)
endforeach()

It feels hacky (and would probably scale poorly for performance reasons),
but it gets the job done.

Petr
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20150810/a6d5fc75/attachment.html>


More information about the CMake mailing list