forked from AMReX-Codes/amrex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAMReXBuildInfo.cmake
241 lines (193 loc) · 7.98 KB
/
AMReXBuildInfo.cmake
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#[=======================================================================[
AMReXBuildInfo
----------------
Provides the function "generate_buildinfo(_target _git_dir)".
generate_buildinfo(_target _git_dir) adds AMReXBuildInfo.H and
AMReXBuildInfo.cpp to the source list of ${_target}.
AMReXBuildInfo.H is a header file located in /path/to/amrex/Tools/C_Scripts
and contains the signatures of functions designed to retrieve build info
like compiler used, source directory paths, compilation flags and so on.
AMReXBuildInfo.cpp is a source file containing the implementations of
the prototypes defined in AMReXBuildInfo.H.
AMReXBuildInfo.cpp is created from AMReXBuildInfo.cpp.in by
generate_buildinfo(_target _git_dir) via the CMake function
configure_file().
AMReXBuildInfo.cpp.in is located in /path/to/amrex/Tools/CMake.
This module
* sets internal variables AMREX_C_SCRIPTS_DIR, AMREX_BUILDINFO_IFILE,
and AMREX_TOP_DIR
* defines cache variable AMREX_BUILD_DATETIME
* provides the function "generate_buildinfo(_target _git_dir)"
#]=======================================================================]
#
# This include brings in function "get_target_properties_flattened()"
#
include(AMReXTargetHelpers)
#
# Set paths
#
string(REPLACE "/Tools/CMake" "" AMREX_TOP_DIR ${CMAKE_CURRENT_LIST_DIR})
set( AMREX_TOP_DIR ${AMREX_TOP_DIR} CACHE INTERNAL "Top level AMReX directory")
set( AMREX_BUILDINFO_IFILE ${CMAKE_CURRENT_LIST_DIR}/AMReX_buildInfo.cpp.in
CACHE INTERNAL "Full path and name of AMReX_buildInfo.cpp.in")
set( AMREX_C_SCRIPTS_DIR "${AMREX_TOP_DIR}/Tools/C_scripts"
CACHE INTERNAL "Path to AMReX' C_scripts dir")
set(AMREX_BUILD_DATETIME "" CACHE STRING
"User defined build date and time. Set ONLY for reproducibly built binary distributions")
#
# FUNCTION: generate_buildinfo(_target _git_dir)
#
# Adds AMReXBuildInfo.H and AMReXBuildInfo.cpp to the source
# list of ${_target}.
#
# If ${_git_dir} is a path to a valid git directory, pass
# this info to the build info script for GIT version retrieval.
#
function (generate_buildinfo _target _git_dir)
#
# check if _target is a valid target
#
if (NOT TARGET ${_target} )
message(FATAL_ERROR "Target ${_target} does not exists")
endif ()
#
# Set variables to be used in generated source file
#
# Date and time -- C++ preprocessor macros
# If AMREX_BUILD_DATETIME is not set, use macros __DATE__ and __TIME__
if (AMREX_BUILD_DATETIME)
set(BUILD_DATE "\"${AMREX_BUILD_DATETIME}\"")
else()
set(BUILD_DATE "__DATE__ \" \" __TIME__" )
endif ()
# Target build directory
get_target_property(BUILD_DIR ${_target} BINARY_DIR)
# Build machine
cmake_host_system_information( RESULT BUILD_MACHINE
QUERY OS_NAME HOSTNAME OS_RELEASE OS_VERSION OS_PLATFORM )
string(REPLACE ";" " " BUILD_MACHINE "${BUILD_MACHINE}")
#
# Build flags
#
get_target_properties_flattened(${_target} _includes _defines _flags _link_line)
get_property(_lang GLOBAL PROPERTY ENABLED_LANGUAGES)
set(_prop _includes _defines _flags _link_line )
# Loop over all combinations of language and property and extract
# what we need
foreach( _l IN LISTS _lang )
foreach( _p IN LISTS _prop )
# _${_l}${_p} is a variable named as _lang_property,
set(_${_l}${_p} "${${_p}}")
eval_genex( _${_l}${_p} ${_l} ${CMAKE_${_l}_COMPILER_ID}
COMP_VERSION ${CMAKE_${_l}_COMPILER_VERSION}
CONFIG ${CMAKE_BUILD_TYPE}
INTERFACE BUILD)
if (_${_l}${_p})
list(REMOVE_DUPLICATES _${_l}${_p})
if ("${_p}" STREQUAL "_defines")
string(REPLACE ";" " -D" _${_l}${_p} "-D${_${_l}${_p}}")
elseif ("${_p}" STREQUAL "_includes")
string(REPLACE ";" " -I" _${_l}${_p} "-I${_${_l}${_p}}")
else()
string(REPLACE ";" " " _${_l}${_p} "${_${_l}${_p}}")
endif ()
endif ()
# Manually escape quotes
string(REPLACE "\"" "\\\"" _${_l}${_p} "${_${_l}${_p}}")
endforeach()
# The configure file needs ${_l}_FLAGS: we set these variables here
set(${_l}_FLAGS "${CMAKE_${_l}_FLAGS} ${_${_l}_flags}")
if (CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} _ubuild_type)
set(${_l}_FLAGS "${CMAKE_${_l}_FLAGS_${_ubuild_type}} ${${_l}_FLAGS}")
endif ()
set(${_l}_FLAGS "${_${_l}_defines} ${_${_l}_includes} ${${_l}_FLAGS}")
string(STRIP "${${_l}_FLAGS}" ${_l}_FLAGS)
endforeach ()
# Link flags (we leave it empty and just provide the full link
# line later
set(LINK_FLAGS "")
# Provide full link line instead of just libraries
# Use c++ link line
set(LIBRARIES "${_CXX_link_line}")
# Number of modules -- set to zero for now
set(NUM_MODULES "int num_modules = 0;")
#
# Git hashes for both app code and AMReX if available
#
find_package(Git)
# App code hash
if (Git_FOUND AND (EXISTS ${_git_dir}/.git))
# Check the hash of the app code first
execute_process(
COMMAND git describe --abbrev=12 --dirty --always --tags
WORKING_DIRECTORY ${_git_dir}
OUTPUT_VARIABLE _hash )
string(STRIP "${_hash}" _hash)
set(GIT_DECLS "static const char HASH1[] = \"${_hash}\";\n")
set(GIT_CASE "case 1: return HASH1;\n")
endif ()
# AMReX app code
if (AMReX_GIT_VERSION) # If using AMReX as a library
set(GIT_DECLS "${GIT_DECLS} static const char HASH2[] = ${AMReX_GIT_VERSION};")
set(GIT_CASE "${GIT_CASE} case 2: return HASH2;")
elseif (AMREX_GIT_VERSION) # If using AMReX via add_subdirectory()
set(GIT_DECLS "${GIT_DECLS} static const char HASH2[] = \"${AMREX_GIT_VERSION}\";")
set(GIT_CASE "${GIT_CASE} case 2: return HASH2;")
elseif ( Git_FOUND AND (EXISTS ${AMREX_TOP_DIR}/.git) ) # Backup case
execute_process(
COMMAND git describe --abbrev=12 --dirty --always --tags
WORKING_DIRECTORY ${AMREX_TOP_DIR}
OUTPUT_VARIABLE _hash )
string(STRIP "${_hash}" _hash)
set(GIT_DECLS "${GIT_DECLS} static const char HASH2[] = \"${_hash}\";")
set(GIT_CASE "${GIT_CASE} case 2: return HASH2;")
endif ()
# Other variables to be left unfilled for now
set(BUILDGIT_DECLS "static const char HASH[] = \"\";")
set(BUILDGIT_NAME "static const char NAME[] = \"\";")
# Generate AMReX_buildInfo.cpp
configure_file( ${AMREX_BUILDINFO_IFILE}
${PROJECT_BINARY_DIR}/${_target}/AMReX_buildInfo.cpp @ONLY)
# add a re-usable target
add_library(buildInfo${_target} STATIC)
add_library(buildInfo::${_target} ALIAS buildInfo${_target})
target_sources(buildInfo${_target}
PRIVATE
${PROJECT_BINARY_DIR}/${_target}/AMReX_buildInfo.cpp
)
target_sources(buildInfo${_target}
PRIVATE
${AMREX_C_SCRIPTS_DIR}/AMReX_buildInfo.H
)
target_include_directories(buildInfo${_target}
PUBLIC
$<BUILD_INTERFACE:${AMREX_C_SCRIPTS_DIR}>
)
# Make AMReX_buildInfo.cpp always out of date before building
add_custom_command(TARGET buildInfo${_target}
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E touch_nocreate AMReX_buildInfo.cpp
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${_target}/
)
target_link_libraries(${_target}
PUBLIC
$<BUILD_INTERFACE:buildInfo${_target}> )
# Set PIC property to be consistent with AMReX'
get_target_property(_pic AMReX::amrex POSITION_INDEPENDENT_CODE)
get_target_property(_sym AMReX::amrex WINDOWS_EXPORT_ALL_SYMBOLS)
set_target_properties(buildInfo${_target} PROPERTIES
POSITION_INDEPENDENT_CODE ${_pic}
WINDOWS_EXPORT_ALL_SYMBOLS ${_sym} )
# IPO/LTO
if (AMReX_IPO)
include(CheckIPOSupported)
check_ipo_supported(RESULT is_IPO_available)
if(is_IPO_available)
set_target_properties(buildInfo${_target} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(FATAL_ERROR "Interprocedural optimization is not available, set AMReX_IPO=OFF")
endif()
endif()
endfunction ()