From a0f9ccbdbf9aebb64ac82b68e303a12bc7523773 Mon Sep 17 00:00:00 2001 From: Sergiu Deitsch Date: Sat, 24 Oct 2026 21:40:47 +0200 Subject: [PATCH] Help: Clarify target of source property genexes The documentation did not say which target generator expressions in source file properties refer to. They are evaluated separately for each target compiling the source, so a source shared by several targets can be compiled differently by each. Document this with an example and test a source shared by two targets. --- Help/include/GENEX_NOTE_SOURCE_TARGET.rst | 3 +++ Help/manual/cmake-generator-expressions.7.rst | 4 ++++ Help/prop_sf/COMPILE_DEFINITIONS.rst | 15 +++++++++++++++ Help/prop_sf/COMPILE_FLAGS.rst | 1 + Help/prop_sf/COMPILE_OPTIONS.rst | 1 + Help/prop_sf/INCLUDE_DIRECTORIES.rst | 1 + Tests/GeneratorExpression/CMakeLists.txt | 9 +++++++++ Tests/GeneratorExpression/srcgenex_shared.c | 12 ++++++++++++ 8 files changed, 46 insertions(+) create mode 100644 Help/include/GENEX_NOTE_SOURCE_TARGET.rst create mode 100644 Tests/GeneratorExpression/srcgenex_shared.c diff --git a/Help/include/GENEX_NOTE_SOURCE_TARGET.rst b/Help/include/GENEX_NOTE_SOURCE_TARGET.rst new file mode 100644 index 0000000000..e4ea1a5a2f --- /dev/null +++ b/Help/include/GENEX_NOTE_SOURCE_TARGET.rst @@ -0,0 +1,3 @@ + +Generator expressions in |genex_subject| are evaluated separately for each +target that compiles the source file. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index fdfc4da47f..ce9b17a6b8 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -2858,6 +2858,10 @@ These expressions look up the values of Note that for generator expressions in :ref:`Target Usage Requirements` this is the consuming target rather than the target specifying the requirement. + For generator expressions in + :ref:`source file properties `, this is the target + compiling the source file, so a source file shared by several targets can + be compiled differently by each. The expressions have special evaluation rules for some properties: diff --git a/Help/prop_sf/COMPILE_DEFINITIONS.rst b/Help/prop_sf/COMPILE_DEFINITIONS.rst index f0a8262c4d..4094508f41 100644 --- a/Help/prop_sf/COMPILE_DEFINITIONS.rst +++ b/Help/prop_sf/COMPILE_DEFINITIONS.rst @@ -23,6 +23,21 @@ definitions on source files. .. |genex_subject| replace:: ``COMPILE_DEFINITIONS`` .. include:: ../include/GENEX_NOTE_PER_SOURCE.rst +.. include:: ../include/GENEX_NOTE_SOURCE_TARGET.rst + +For example, ``foo.cpp`` is compiled with ``FOO=1`` in target ``A`` and with +``FOO=2`` in target ``B``, while ``bar.cpp`` is compiled without ``FOO``: + +.. code-block:: cmake + + add_library(A OBJECT foo.cpp bar.cpp) + add_library(B OBJECT foo.cpp bar.cpp) + + set_property(TARGET A PROPERTY FOO_VALUE 1) + set_property(TARGET B PROPERTY FOO_VALUE 2) + + set_property(SOURCE foo.cpp PROPERTY COMPILE_DEFINITIONS + "FOO=$") Prefer using generator expressions in :prop_sf:`!COMPILE_DEFINITIONS` over the deprecated :prop_sf:`COMPILE_DEFINITIONS_` property. diff --git a/Help/prop_sf/COMPILE_FLAGS.rst b/Help/prop_sf/COMPILE_FLAGS.rst index 7d48776395..e89ed2ec6d 100644 --- a/Help/prop_sf/COMPILE_FLAGS.rst +++ b/Help/prop_sf/COMPILE_FLAGS.rst @@ -11,6 +11,7 @@ Use :prop_sf:`COMPILE_DEFINITIONS` to pass additional preprocessor definitions. .. |genex_subject| replace:: ``COMPILE_FLAGS`` .. include:: ../include/GENEX_NOTE_PER_SOURCE.rst +.. include:: ../include/GENEX_NOTE_SOURCE_TARGET.rst .. note:: diff --git a/Help/prop_sf/COMPILE_OPTIONS.rst b/Help/prop_sf/COMPILE_OPTIONS.rst index e51ede33d1..91d67e55bc 100644 --- a/Help/prop_sf/COMPILE_OPTIONS.rst +++ b/Help/prop_sf/COMPILE_OPTIONS.rst @@ -11,6 +11,7 @@ file builds. The options will be added after target-wide options. .. |genex_subject| replace:: ``COMPILE_OPTIONS`` .. include:: ../include/GENEX_NOTE_PER_SOURCE.rst +.. include:: ../include/GENEX_NOTE_SOURCE_TARGET.rst Usage example: diff --git a/Help/prop_sf/INCLUDE_DIRECTORIES.rst b/Help/prop_sf/INCLUDE_DIRECTORIES.rst index a58b4a2fb9..1ad325fe4f 100644 --- a/Help/prop_sf/INCLUDE_DIRECTORIES.rst +++ b/Help/prop_sf/INCLUDE_DIRECTORIES.rst @@ -15,3 +15,4 @@ Relative paths should not be added to this property directly. .. |genex_subject| replace:: ``INCLUDE_DIRECTORIES`` .. include:: ../include/GENEX_NOTE_PER_SOURCE.rst +.. include:: ../include/GENEX_NOTE_SOURCE_TARGET.rst diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 18b545ba36..92cf3129ed 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -412,6 +412,15 @@ if (CMAKE_GENERATOR MATCHES "Makefiles|Ninja|Watcom WMake|FASTBuild") PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}" $<$:${CMAKE_CURRENT_BINARY_DIR}/sf_includes_COMPILE_LANGUAGE>) endif() +# Evaluate source file properties separately for each target compiling a shared source. +foreach (id IN ITEMS 1 2) + add_executable(srcgenex_shared_${id} srcgenex_shared.c) + set_property(TARGET srcgenex_shared_${id} PROPERTY SRCGENEX_SHARED_ID ${id}) + target_compile_definitions(srcgenex_shared_${id} PRIVATE EXPECTED_ID=${id}) +endforeach() +set_property(SOURCE srcgenex_shared.c + PROPERTY COMPILE_DEFINITIONS SHARED_ID=$) + #----------------------------------------------------------------------------- # Cover test properties with generator expressions. add_executable(echo echo.c) diff --git a/Tests/GeneratorExpression/srcgenex_shared.c b/Tests/GeneratorExpression/srcgenex_shared.c new file mode 100644 index 0000000000..2b48edc57a --- /dev/null +++ b/Tests/GeneratorExpression/srcgenex_shared.c @@ -0,0 +1,12 @@ +#ifndef SHARED_ID +# error SHARED_ID not defined +#endif + +#if SHARED_ID != EXPECTED_ID +# error SHARED_ID does not match EXPECTED_ID of the compiled target +#endif + +int main(void) +{ + return 0; +}