forked from wrf-model/WRF
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtarget_source_properties.cmake
More file actions
146 lines (128 loc) · 5.69 KB
/
target_source_properties.cmake
File metadata and controls
146 lines (128 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#
# These two functions together allow greater control of propagating flags within
# a target on a per-source basis with the ability to "inherit" those properties
# from the target if not set. This allows a target to defing its own flags, but
# then if a file needs different settings those can be directly overridden without
# relying on compiler-specific flag order precedence. Additionally this allows a
# project to organize grouping of flags within a target
#
# Note that for compile defines on source files they are not used in the autogen
# dependency scanning. See :
# https://gitlab.kitware.com/cmake/cmake/-/issues/22519
# and
# https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmDependsFortran.cxx#L84
# functions cmDependsFortran::cmDependsFortran() and cmDependsFortran::WriteDependencies()
#
# The solution is to either use Ninja or preprocess the files (what Ninja internally does)
# This is probably the way to go as well since CMake native preprocessor directive
# parsing is... subpar and simplified :
# https://gitlab.kitware.com/cmake/cmake/-/issues/17398
#
# Alternatively, set critical flags at the target level
#
#
# A simple function to create properties for targets and sources quickly
#
function( define_target_source_properties )
set( options )
set( oneValueArgs )
set( multiValueArgs PROPERTIES )
cmake_parse_arguments(
FUNC_PROP
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
define_property(
SOURCE
PROPERTY ${PROPERTY}
# INHERITED # they will be "inherited" via target to source
BRIEF_DOCS "Transitive property from target to file"
FULL_DOCS "This property can override an existing property derived from a target"
)
define_property(
TARGET
PROPERTY ${PROPERTY}
# INHERITED # they will be "inherited" via target to source
BRIEF_DOCS "Transitive property from target to file"
FULL_DOCS "This property can be overridden on a per file basis"
)
endforeach()
endfunction()
#
# The bulk of the functionality exists in this function. It will loop over each
# provided target, gathering sources and their respective properties listed, using
# the target's property if not defined for this source else nothing, and finally
# applies it to that source.
#
function( apply_target_source_properties )
set( options DISCARD_PREVIOUS DEBUG )
set( oneValueArgs AS_PROPERTY )
set( multiValueArgs TARGETS PROPERTIES )
cmake_parse_arguments(
FUNC_PROP
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
foreach( TARGET ${FUNC_PROP_TARGETS} )
# get target sources
get_target_property( TARGET_SOURCES ${TARGET} SOURCES )
# get default "inherited" value from target
foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
get_target_property( TARGET_PROPERTY_${PROPERTY} ${TARGET} ${PROPERTY} )
if ( "${TARGET_PROPERTY_${PROPERTY}}" STREQUAL "TARGET_PROPERTY_${PROPERTY}-NOTFOUND" )
# unset it
set( TARGET_PROPERTY_${PROPERTY} )
endif()
endforeach()
foreach( SOURCE ${TARGET_SOURCES} )
# We need to accumulate properties since a call to set property will
# override what was there before
set( SOURCE_PROPERTY_ALL )
foreach( PROPERTY ${FUNC_PROP_PROPERTIES} )
# first try source
get_source_file_property(
SOURCE_PROPERTY_${PROPERTY}
${SOURCE}
TARGET_DIRECTORY ${TARGET}
${PROPERTY}
)
if ( "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "NOTFOUND" )
# use target
set( SOURCE_PROPERTY_${PROPERTY} ${TARGET_PROPERTY_${PROPERTY}} )
endif()
# Now apply these as prop
if ( NOT "${SOURCE_PROPERTY_${PROPERTY}}" STREQUAL "" )
if ( ${FUNC_PROP_DEBUG} )
message( STATUS "DEBUG : Adding '${SOURCE_PROPERTY_${PROPERTY}}' as SOURCE_PROPERTY_${PROPERTY}")
endif()
list( APPEND SOURCE_PROPERTY_ALL ${SOURCE_PROPERTY_${PROPERTY}} )
endif()
endforeach() # properties
# Apply properties to source
if ( NOT "${SOURCE_PROPERTY_ALL}" STREQUAL "" )
if ( NOT ${FUNC_PROP_DISCARD_PREVIOUS} )
# get old value and append
get_source_file_property(
SOURCE_PROPERTY_ORIG
${SOURCE}
TARGET_DIRECTORY ${TARGET}
${FUNC_PROP_AS_PROPERTY}
)
if ( "${SOURCE_PROPERTY_ORIG}" STREQUAL "NOTFOUND" )
set( SOURCE_PROPERTY_ORIG )
endif()
endif()
if ( ${FUNC_PROP_DEBUG} )
message( STATUS "DEBUG : ${FUNC_PROP_AS_PROPERTY} being set to '${SOURCE_PROPERTY_ORIG} ${SOURCE_PROPERTY_ALL}'")
endif()
set_source_files_properties(
${SOURCE}
TARGET_DIRECTORY ${TARGET}
PROPERTIES
${FUNC_PROP_AS_PROPERTY} "${SOURCE_PROPERTY_ORIG};${SOURCE_PROPERTY_ALL}"
)
endif()
endforeach() # sources
endforeach() # targets
endfunction()