Idea: Generator Scripts
Generator expressions with non-trivial logic are very difficult to write, and even harder to debug. If they have a lot of logic, they often end up looking like complicated C++ templates:
target_link_libraries(target $<IF:$<AND:$<NOT:$<STREQUAL:$<TARGET_PROPERTY:foo>,bar>>,$<NOT:$<STREQUAL:$<TARGET_PROPERTY:baz>,>>>,a,b>)
These are really annoying to write. What if you could put it in the form of a CMake script instead?
genscript.cmake:
evaluate_generator_expression(foo_value $<TARGET_PROPERTY:foo>)
evaluate_generator_expression(baz_value $<TARGET_PROPERTY:baz>)
if(NOT foo_value STREQUAL "bar" AND NOT baz_value STREQUAL "")
set(return_value "a")
else()
set(return_value "b")
endif()
And then your CMakeLists.txt might look like:
target_link_libraries(target $<SCRIPT:${CMAKE_CURRENT_LIST_DIR}/genscript.cmake,return_value>)
We could even add the ability to add one of these generator scripts without being in the context of evaluating an expression, like so:
target_generator_scripts(target ${CMAKE_CURRENT_LIST_DIR}/writefile.cmake)
writefile.cmake:
evaluate_generator_expression(dir $<TARGET_FILE_DIR:$<TARGET_PROPERTY:name>>)
file(WRITE "${dir}/stuff.txt" "stuff")
target_generator_scripts()
could also have the usual PUBLIC
/PRIVATE
/INTERFACE
specifiers:
add_library(foo IMPORTED)
target_generator_scripts(foo INTERFACE ${CMAKE_CURRENT_LIST_DIR}/writefile.cmake)
So then any target that links against foo
would automatically run this generator script in its own context.
This feature would add a target_generator_scripts()
command, which can only be run at configure-time, an evaluate_generator_expression()
command, which can only be run in a generator script, and a $<SCRIPT:scriptname,retvar>
generator expression. A generator script would be identical to script mode except for the addition of the evaluate_generator_expression()
command.