[CMake] Generator expressions and rule variables

Kuba Ober kuba at mareimbrium.org
Fri Feb 15 23:30:32 EST 2019


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190215/9962bace/attachment.html>


More information about the CMake mailing list