2 # These two functions together allow greater control of propagating flags within
3 # a target on a per-source basis with the ability to "inherit" those properties
4 # from the target if not set. This allows a target to defing its own flags, but
5 # then if a file needs different settings those can be directly overridden without
6 # relying on compiler-specific flag order precedence. Additionally this allows a
7 # project to organize grouping of flags within a target
9 # Note that for compile defines on source files they are not used in the autogen
10 # dependency scanning. See :
11 # https://gitlab.kitware.com/cmake/cmake/-/issues/22519
13 # https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmDependsFortran.cxx#L84
14 # functions cmDependsFortran::cmDependsFortran() and cmDependsFortran::WriteDependencies()
16 # The solution is to either use Ninja or preprocess the files (what Ninja internally does)
17 # This is probably the way to go as well since CMake native preprocessor directive
18 # parsing is... subpar and simplified :
19 # https://gitlab.kitware.com/cmake/cmake/-/issues/17398
21 # Alternatively, set critical flags at the target level
27 # A simple function to create properties for targets and sources quickly
29 function( define_target_source_properties )
32 set( multiValueArgs PROPERTIES )
34 cmake_parse_arguments(
36 "${options}" "${oneValueArgs}" "${multiValueArgs}"
40 foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
44 # INHERITED # they will be "inherited" via target to source
50 # INHERITED # they will be "inherited" via target to source
57 # The bulk of the functionality exists in this function. It will loop over each
58 # provided target, gathering sources and their respective properties listed, using
59 # the target's property if not defined for this source else nothing, and finally
60 # applies it to that source.
62 function( apply_target_source_properties )
63 set( options DISCARD_PREVIOUS DEBUG )
64 set( oneValueArgs AS_PROPERTY )
65 set( multiValueArgs TARGETS PROPERTIES )
67 cmake_parse_arguments(
69 "${options}" "${oneValueArgs}" "${multiValueArgs}"
73 foreach( TARGET ${FUNC_PROP_TARGETS} )
75 get_target_property( TARGET_SOURCES ${TARGET} SOURCES )
77 # get default "inherited" value from target
78 foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
79 get_target_property( TARGET_PROPERTY_${PROPERTY} ${TARGET} ${PROPERTY} )
80 if ( "${TARGET_PROPERTY_${PROPERTY}}" STREQUAL "TARGET_PROPERTY_${PROPERTY}-NOTFOUND" )
82 set( TARGET_PROPERTY_${PROPERTY} )
86 foreach( SOURCE ${TARGET_SOURCES} )
88 # We need to accumulate properties since a call to set property will
89 # override what was there before
90 set( SOURCE_PROPERTY_ALL )
92 foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
94 get_source_file_property(
95 SOURCE_PROPERTY_${PROPERTY}
97 TARGET_DIRECTORY ${TARGET}
100 if ( "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "NOTFOUND" )
102 set( SOURCE_PROPERTY_${PROPERTY} ${TARGET_PROPERTY_${PROPERTY}} )
105 # Now apply these as prop
106 if ( NOT "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "" )
107 if ( ${FUNC_PROP_DEBUG} )
108 message( STATUS "DEBUG : Adding '${SOURCE_PROPERTY_${PROPERTY}}' as SOURCE_PROPERTY_${PROPERTY}")
110 list( APPEND SOURCE_PROPERTY_ALL ${SOURCE_PROPERTY_${PROPERTY}} )
112 endforeach() # properties
114 # Apply properties to source
115 if ( NOT "${SOURCE_PROPERTY_ALL}" STREQUAL "" )
116 if ( NOT ${FUNC_PROP_DISCARD_PREVIOUS} )
117 # get old value and append
118 get_source_file_property(
121 TARGET_DIRECTORY ${TARGET}
122 ${FUNC_PROP_AS_PROPERTY}
124 if ( "${SOURCE_PROPERTY_ORIG}" STREQUAL "NOTFOUND" )
125 set( SOURCE_PROPERTY_ORIG )
129 if ( ${FUNC_PROP_DEBUG} )
130 message( STATUS "DEBUG : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'")
133 set_source_files_properties(
135 TARGET_DIRECTORY ${TARGET}
137 ${FUNC_PROP_AS_PROPERTY} "${SOURCE_PROPERTY_ORIG};${SOURCE_PROPERTY_ALL}"
140 endforeach() # sources
141 endforeach() # targets