Generator expressions and rule variables

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Generator expressions and rule variables

Kuba Ober
Hi, I'm trying to integrate cmake with a set of build tools whose command lines look nothing like standard gnu tools.

Unfortunately, both the generator expressions and the rule variables seem very limited: I have to do some custom massaging of the arguments that get passed to the compiler/linker. I've resorted to using cmake in script mode as a proxy to the compiler and linker, passing all the rule variables verbatim, and then having the script call the compiler or linker.

This suffers from problems with escaping of spaces, at the very least. It seems like those compilation commands would need nested lists (a hypothetical construct thus far): the outer list would be the list of commands - as it is now, the inner list would be the list of arguments, and they'd be properly escaped etc. Some of it could be solved if COMMAND_EXPAND_LISTS could be somehow applied to normal targets, and thus to the underlying CMAKE_<LANG>_COMPILE_OBJECT, etc.

Simplifying, thus far I set CMAKE_C_COMPILE_OBJECT to ${CMAKE_COMMAND} -DV1=<rulevar1> ... -DVn=<rulevarn> -P ${CMAKE_CURRENT_LIST_DIR}/helper.cmake. The helper does the rest. It's brittle because of poor escaping support. I could also use C_COMPILER_LAUNCHER with same effect but it couldn't be a cmake script, since cmake doesn't understand "cmake -D... -P script.cmake -- arbitrary arguments" (it could without any trouble - it's a small patch; would it be something worthwhile to add?).

The problem is that I don't really need the overhead of invoking cmake or another script/process for every compiled/linked output. For both make and ninja generators, all I'd need is to generate a custom target command that bypasses the result of the built-in generator. But I also want my CMakeLists to look familiar and be compatible with additional generators, thus having a custom "add_my_executable" function wouldn't work, and overriding "add_executable" to modify some targets, and pass others directly to "add_executable_" (the undocumented handle to the overridden function) seems like a big hack.

So, what I'd want to do is to have a function that can be invoked for every target, before the target is passed to the generator, and that could inspect the target and modify its properties and override variables in its scope. In my case, I'd write this function so that each target would get its own "CMAKE_C_COMPILE_OBJECT" or "CMAKE_C_LINK_EXECUTABLE", fully expanded, without any generator expressions nor rule variables.

Does cmake already offer any hook like it? A cursory examination of the source code doesn't seem to indicate so (btw: the code is clear and easy to follow, so I don't have high hopes...). And if not, would it be a worthwhile addition? It'd obviate the need for both generator expressions and rule variables - personally I think that they are half-baked hacks, with rule variables being even more limited and really only meshing with gnu-like tools. I imagine that to speed things up, a pre-filter could be applied - say that "my_function" should be invoked for all executable targets, for C language and foocc compiler: "CMAKE_ADD_FILTER(add_executable, my_function, LANGUAGE=c COMPILER_ID=foocc)". For every invocation of `add_executable`, CMAKE would check if the filters match, and if so it'd invoke the function, which then could modify target properties and variables visible to the generator (i.e. it could regenerate CMAKE_C_COMPILE_OBJECT).

Another approach could be to have said function act like COMPILER_LAUNCHER, and we'd then have something like: "CMAKE_ADD_COMPILER_LAUNCHER(my_function, LANGUAGE=c, COMPILER_ID=foocc, TYPE=executable)"

Cheers, Kuba Ober


Powered by

Please keep messages on-topic and check the CMake FAQ at:

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support:
CMake Consulting:
CMake Training Courses:

Visit other Kitware open-source projects at

Follow this link to subscribe/unsubscribe: