Update version info for release v4.6.1 (#2122)
[WRF.git] / cmake / target_source_properties.cmake
blob64bd47379b73b91270821d82e1a2403865a7f5fd
1
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
12 # and 
13 # https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmDependsFortran.cxx#L84
14 # functions cmDependsFortran::cmDependsFortran() and cmDependsFortran::WriteDependencies()
15
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
20
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 )
30   set( options        )
31   set( oneValueArgs   )
32   set( multiValueArgs PROPERTIES )
34   cmake_parse_arguments(
35                         FUNC_PROP
36                         "${options}"  "${oneValueArgs}"  "${multiValueArgs}"
37                         ${ARGN}
38                         )
40   foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
41     define_property(
42                     SOURCE
43                     PROPERTY   ${PROPERTY}
44                     # INHERITED # they will be "inherited" via target to source
45                     )
47     define_property(
48                     TARGET
49                     PROPERTY   ${PROPERTY}
50                     # INHERITED # they will be "inherited" via target to source
51                     )
52   endforeach()
53 endfunction()
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(
68                         FUNC_PROP
69                         "${options}"  "${oneValueArgs}"  "${multiValueArgs}"
70                         ${ARGN}
71                         )
73   foreach( TARGET ${FUNC_PROP_TARGETS} )
74     # get target sources
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" )
81         # unset it
82         set( TARGET_PROPERTY_${PROPERTY} )
83       endif()
84     endforeach()
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} )
93         # first try source
94         get_source_file_property( 
95                                   SOURCE_PROPERTY_${PROPERTY}
96                                   ${SOURCE}
97                                   TARGET_DIRECTORY ${TARGET}
98                                   ${PROPERTY}
99                                   )
100         if ( "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "NOTFOUND" )
101           # use target
102           set( SOURCE_PROPERTY_${PROPERTY} ${TARGET_PROPERTY_${PROPERTY}} )
103         endif()
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}")
109           endif()
110           list( APPEND SOURCE_PROPERTY_ALL ${SOURCE_PROPERTY_${PROPERTY}} )
111         endif()
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(
119                                     SOURCE_PROPERTY_ORIG
120                                     ${SOURCE}
121                                     TARGET_DIRECTORY ${TARGET}
122                                     ${FUNC_PROP_AS_PROPERTY}
123                                     )
124           if ( "${SOURCE_PROPERTY_ORIG}" STREQUAL "NOTFOUND" )
125             set( SOURCE_PROPERTY_ORIG )
126           endif()
127         endif()
129         if ( ${FUNC_PROP_DEBUG} )
130           message( STATUS "DEBUG : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'")
131         endif()
133         set_source_files_properties(
134                                     ${SOURCE}
135                                     TARGET_DIRECTORY ${TARGET}
136                                     PROPERTIES
137                                       ${FUNC_PROP_AS_PROPERTY} "${SOURCE_PROPERTY_ORIG};${SOURCE_PROPERTY_ALL}"
138                                     )
139       endif()
140     endforeach()   # sources
141   endforeach()     # targets
142 endfunction()