forked from alisw/AliRoot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeALICE.cmake
414 lines (340 loc) · 16 KB
/
CMakeALICE.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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# **************************************************************************
# * Copyright(c) 1998-2014, ALICE Experiment at CERN, All rights reserved. *
# * *
# * Author: The ALICE Off-line Project. *
# * Contributors are mentioned in the code where appropriate. *
# * *
# * Permission to use, copy, modify and distribute this software and its *
# * documentation strictly for non-commercial purposes is hereby granted *
# * without fee, provided that the above copyright notice appears in all *
# * copies and that both the copyright notice and this permission notice *
# * appear in the supporting documentation. The authors make no claims *
# * about the suitability of this software for any purpose. It is *
# * provided "as is" without express or implied warranty. *
# **************************************************************************
# General purpose functions
#########################
# ROOT utilities
#########################
# Generation of the dictionaries
# @DNAME Dictionary name
# @LDNAME LinkDef file name, ex: LinkDef.h
# @DHDRS Dictionary headers
# @DHDRS_DEPS Dictionary header files used as dependencies to the rootmap target
# @DINCDIR Include folders that need to be passed to cint/cling
# @EXTRADEFINITIONS - optional, extra compile flags specific to library
# - used as ${ARGV5}
macro(_generate_dictionary DNAME LDNAME DHDRS DHDRS_DEPS DINCDIRS)
# Creating the INCLUDE path for cint/cling
foreach(_dir ${DINCDIRS})
set(INCLUDE_PATH -I${_dir} ${INCLUDE_PATH})
endforeach()
# Get the list of definitions from the directory to be sent to CINT
get_directory_property(tmpdirdefs COMPILE_DEFINITIONS)
foreach(dirdef ${tmpdirdefs})
string(REPLACE "\"" "\\\"" dirdef_esc ${dirdef})
set(GLOBALDEFINITIONS -D${dirdef_esc} ${GLOBALDEFINITIONS})
endforeach()
# Custom definitions specific to library
# Received as the forth optional argument
separate_arguments(EXTRADEFINITIONS UNIX_COMMAND "${ARGV5}")
if (ROOT_VERSION_MAJOR LESS 6)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.h
COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_CINT}
ARGS -f ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx -c -p
${GLOBALDEFINITIONS} ${EXTRADEFINITIONS} ${INCLUDE_PATH}
${DHDRS} ${LDNAME}
DEPENDS ${DHDRS_DEPS} ${LDNAME} ${ROOT_CINT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
else (ROOT_VERSION_MAJOR LESS 6)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib${DNAME}.rootmap ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}_rdict.pcm
COMMAND
LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_CINT}
ARGS
-f ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx
-rmf ${CMAKE_CURRENT_BINARY_DIR}/lib${DNAME}.rootmap -rml lib${DNAME}
${GLOBALDEFINITIONS} ${EXTRADEFINITIONS} ${INCLUDE_PATH} ${DHDRS} ${LDNAME}
DEPENDS
${DHDRS_DEPS} ${LDNAME} ${ROOT_CINT}
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${DNAME}.rootmap" DESTINATION lib)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}_rdict.pcm" DESTINATION lib)
endif (ROOT_VERSION_MAJOR LESS 6)
endmacro(_generate_dictionary)
# Standard generate_dictionary function for non-flattened header files
macro(generate_dictionary DNAME LDNAME DHDRS DINCDIRS)
_generate_dictionary("${DNAME}" "${LDNAME}" "${DHDRS}" "${DHDRS}" "${DINCDIRS}" "${ARGV4}")
endmacro(generate_dictionary)
# Same as generate_dictionary, but flattens the list of headers and sets additional include paths
# with include_directories
macro(generate_dictionary_flat DNAME LDNAME DHDRS DINCDIRS)
set(_dhdrs "")
set(_daddincdirs "")
foreach(_itm ${DHDRS})
string(FIND "${_itm}" "/" _idx)
if(_idx GREATER -1)
# Has a subdirectory specified
get_filename_component(_itmdir "${_itm}" DIRECTORY)
get_filename_component(_itmbase "${_itm}" NAME)
list(APPEND _dhdrs "${_itmbase}")
list(APPEND _daddincdirs "${CMAKE_CURRENT_SOURCE_DIR}/${_itmdir}")
else()
# No subdirectory specified
list(APPEND _dhdrs "${_itm}")
endif()
endforeach()
list(REMOVE_DUPLICATES _daddincdirs)
if(NOT "${_daddincdirs}" STREQUAL "")
foreach(_dir "${_daddincdirs}")
include_directories("${_dir}")
endforeach()
endif()
_generate_dictionary("${DNAME}" "${LDNAME}" "${_dhdrs}" "${DHDRS}" "${DINCDIRS};${_daddincdirs}" "${ARGV4}")
endmacro(generate_dictionary_flat)
# Generate the ROOTmap files
# @LIBNAME - library name: libAnalysis.so -> Analysis.rootmap
# @LIBDEPS - library dependencies
# @LINKDEF - LinkDef header
macro(generate_rootmap LIBNAME LIBDEPS LINKDEF)
# message(STATUS "LIBNAME = ${LIBNAME}")
# message(STATUS "LIBDEPS = ${LIBDEPS}")
# message(STATUS "LINKDEF = ${LINKDEF}")
# message(STATUS "ROOT_LIBMAP=${ROOT_LIBMAP}")
if (ROOT_VERSION_MAJOR LESS 6)
set(LOCAL_DEPS)
foreach(file ${LIBDEPS})
get_filename_component(ext ${file} EXT)
if(ext)
set(LOCAL_DEPS ${LOCAL_DEPS} ${file})
else()
set(LOCAL_DEPS ${LOCAL_DEPS} lib${file})
endif()
endforeach()
# message(STATUS "Generating ROOT map for ${LIBNAME}")
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap
COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_LIBMAP}
ARGS -o ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap -l lib${LIBNAME} -d ${LOCAL_DEPS} -c ${LINKDEF}
DEPENDS ${LIBNAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM
)
add_custom_target(lib${LIBNAME}.rootmap ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap DESTINATION lib)
endif (ROOT_VERSION_MAJOR LESS 6)
endmacro(generate_rootmap)
#########################
# Static utilities
#########################
# Generate the static dependecies from dynamic list
# @ shared_list - list of shared libraries
# @ static_list - the name of the variable that will contain the list of static libraries
macro(generate_static_dependencies shared_list static_list)
set(static_list_tmp "")
foreach(shared_lib ${shared_list})
set(static_list_tmp ${static_list_tmp} "${shared_lib}-static")
endforeach()
# create the variable with the name received by the macro
set(${static_list} ${static_list_tmp})
# set the scope to parent in order to be visible in the parent
set(${static_list} PARENT_SCOPE)
endmacro(generate_static_dependencies)
#########################
# DA utilities
#########################
# Extract the first comment from a DA file
# Find the position for first /* and */ and extract the substring
macro(getDAdescription _detector _daname)
# Reading the file into a string
file(READ "${_detector}${_daname}da.cxx" tmpinfo)
# Find the first occurance of /* */
string(FIND "${tmpinfo}" "/*" _first_position)
string(FIND "${tmpinfo}" "*/" _second_position)
# Adding and removing 2 characters to remove /* */
math(EXPR _first_position ${_first_position}+2)
math(EXPR _second_position ${_second_position}-2)
# Generating the length of the comment in order to take out the description
math(EXPR _desc_length ${_second_position}-${_first_position})
if(${_desc_length} EQUAL 0 OR ${_desc_length} LESS 0)
message(FATAL_ERROR "{_detector}${_daname}da.cxx does not contain a description. Please add the description as the first /*comment*/ in the file")
else()
string(SUBSTRING "${tmpinfo}" ${_first_position} ${_second_position} _da_description)
string(STRIP "${_da_description}" _da_description)
# The variable can be accesed by the parent
set(RPM_DESCRIPTION ${_da_description})
endif()
endmacro()
# Set the compilation flags
macro(setDAflags)
# DIM
link_directories(${DIMDIR}/${ODIR})
#daqDA flags
include_directories(${daqDA})
link_directories(${daqDA})
# AMORE definitions
add_definitions(${AMORE_DEFINITIONS})
include_directories(${AMORE_INCLUDE_DIR})
endmacro()
# Generate a DA
macro(generateDA DETECTOR ALGORITHM STATIC_DEPENDENCIES)
setDAflags()
# Generating the DA executable
add_executable(${DETECTOR}${ALGORITHM}da.exe ${DETECTOR}${ALGORITHM}da.cxx)
# DA flags and linking information
set(MODULE_COMPILE_FLAGS)
set(MODULE_LINK_FLAGS)
target_link_libraries(${DETECTOR}${ALGORITHM}da.exe
${STATIC_DEPENDENCIES}
${AMORE_AUXLIBS}
daqDA
${DATE_MONLIBRARIES} ${DATE_RCPROXYLIBRARIES}
Root RootExtra)
# Link AMORE and DATE libraries statically
set(MODULE_COMPILE_FLAGS "-Wl,--no-as-needed ${DATE_CFLAGS} ${AMORE_CFLAGS}")
set(MODULE_LINK_FLAGS "-Wl,-Bstatic ${DATE_LDFLAGS} ${AMORE_STATICLIBS} -Wl,-Bdynamic")
set_target_properties(${DETECTOR}${ALGORITHM}da.exe PROPERTIES
COMPILE_FLAGS ${MODULE_COMPILE_FLAGS})
set_target_properties(${DETECTOR}${ALGORITHM}da.exe PROPERTIES
LINK_FLAGS "${MODULE_LINK_FLAGS}")
# Installation
install(TARGETS ${DETECTOR}${ALGORITHM}da.exe RUNTIME DESTINATION bin)
# Append to the list of DA RPMs to generate in one go
list(APPEND ALIDARPMS "${DETECTOR}${ALGORITHM}da.rpm")
set(ALIDARPMS ${ALIDARPMS} CACHE INTERNAL "ALIDARPMS")
if(DARPM)
createDArpm("${DETECTOR}" "${ALGORITHM}")
endif(DARPM)
endmacro()
# DA rpm creation
macro(createDArpm DETECTOR ALGORITHM)
getDAdescription("${DETECTOR}" "${ALGORITHM}")
set(DA_EXECUTABLE "${DETECTOR}${ALGORITHM}da.exe")
set(DETECTOR "${DETECTOR}")
set(ALGORITHM "${ALGORITHM}")
set(RPM_DESCRIPTION ${RPM_DESCRIPTION})
if(ALGORITHM STREQUAL "")
set(_ALGORITHM "none")
set(DA_PREFIX "opt/daqDA-${DETECTOR}")
set(DA_NAME "daqDA-${DETECTOR}")
else()
set(_ALGORITHM ${ALGORITHM})
set(DA_PREFIX "opt/daqDA-${DETECTOR}-${ALGORITHM}")
set(DA_NAME "daqDA-${DETECTOR}-${ALGORITHM}")
endif()
configure_file("${AliRoot_SOURCE_DIR}/cmake/da.spec.in" "${DETECTOR}${_ALGORITHM}-da.spec" @ONLY)
add_custom_target("${DETECTOR}${ALGORITHM}da.rpm"
COMMAND mkdir -p
da-${DETECTOR}${_ALGORITHM}-rpm/root/${DA_PREFIX}/
${CMAKE_CURRENT_BINARY_DIR}/rpmbuild.tmp
COMMAND cp ${DETECTOR}${ALGORITHM}da.exe
da-${DETECTOR}${_ALGORITHM}-rpm/root/${DA_PREFIX}/
COMMAND env
TMPDIR=${CMAKE_CURRENT_BINARY_DIR}/rpmbuild.tmp
rpmbuild --verbose
--define "_topdir ${CMAKE_CURRENT_BINARY_DIR}/da-${DETECTOR}${_ALGORITHM}-rpm"
--define "%buildroot ${CMAKE_CURRENT_BINARY_DIR}/da-${DETECTOR}${_ALGORITHM}-rpm/root"
-bb ${DETECTOR}${_ALGORITHM}-da.spec
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Creating RPM for DA ${DETECTOR}${ALGORITHM}da.exe"
)
add_dependencies("${DETECTOR}${ALGORITHM}da.rpm" "${DETECTOR}${ALGORITHM}da.exe")
# make clean will remove also the rpm folder
# Retrive the current list of file to be deleted - set_directory_property is overwriting, not adding to the list
get_directory_property(_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
set(_clean_files da-${DETECTOR}${_ALGORITHM}-rpm ${_clean_files})
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_clean_files}")
# install RPM into $CMAKE_INSTALL_PREFIX/darpms
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/da-${DETECTOR}${_ALGORITHM}-rpm/RPMS/
DESTINATION darpms
OPTIONAL
PATTERN "\\.rpm")
endmacro()
# Prepend prefix to every element in the list. Note: this function modifies the input variable: this
# does not work for macros in CMake, only for functions. Also note that it does NOT automatically
# add a / between prefix and list item as it does not assume that we are dealing with directories
function(prepend_prefix INLIST PREFIX)
foreach(_ITEM ${${INLIST}})
list(APPEND _OUTLIST ${PREFIX}${_ITEM})
endforeach()
set(${INLIST} ${_OUTLIST} PARENT_SCOPE)
endfunction()
# This function is a drop-in replacement for the following CMake command:
#
# install(FILES ... DESTINATION ... [OTHER_ARGS])
#
# The above command takes every single file and puts it in the destination directory, but relative
# paths are not taken into consideration, i.e. files a/b/c/file.h and boo.h will be both installed
# in dest.
#
# By replacing install() with install_relative(), boo.h will end in dest, and a/b/c/file.h will end
# in dest/a/b/c/file.h, i.e. relative paths are taken into account.
#
# If an absolute path was specified for an input file, a fatal error will be raised: only relative
# paths can be specified.
#
# Since it is a drop-in command, its syntax is identical to install():
#
# install_relative(FILES ... DESTINATION ... [OTHER_ARGS])
#
# where OTHER_ARGS is passed as-is to the underlying install() command
function(install_relative)
set(_EXPECT_FILE TRUE)
set(_EXPECT_DEST FALSE)
set(_EXPECT_REST FALSE)
foreach(_ARG ${ARGN})
if(_EXPECT_FILE)
if(${_ARG} STREQUAL "FILES")
set(_EXPECT_FILE FALSE)
else()
message(FATAL_ERROR "You may only use install_relative() in place of install(FILES ...)")
endif()
elseif(_EXPECT_REST)
# Remaining arguments
list(APPEND _REST ${_ARG})
elseif(_EXPECT_DEST)
# Destination prefix
set(_DEST ${_ARG})
set(_EXPECT_DEST FALSE)
set(_EXPECT_REST TRUE)
elseif(_ARG STREQUAL "DESTINATION")
# From now on, copy the arguments ditto to the install() command
set(_EXPECT_DEST TRUE)
else()
# Append files to install
list(APPEND _FILES ${_ARG})
endif()
endforeach()
# Print out our results (debug)
#message(STATUS "[install_relative] FILES: ${_FILES}")
#message(STATUS "[install_relative] DEST: ${_DEST}")
#message(STATUS "[install_relative] REST: ${_REST}")
# Prepare a distinct install command for each file, depending on its path
foreach(_FILE ${_FILES})
if(CMAKE_VERSION VERSION_LESS "2.8.12")
get_filename_component(_FILEPREFIX ${_FILE} PATH)
else()
get_filename_component(_FILEPREFIX ${_FILE} DIRECTORY)
endif()
#message(STATUS "[install_relative] ${_FILE} --> ${_FILEPREFIX}")
string(SUBSTRING ${_FILE} 0 1 _FILE_FIRST)
if(${_FILE_FIRST} STREQUAL "/")
# An absolute path was found: not supported, error
message(FATAL_ERROR "Absolute paths are not supported by install_relative(): ${_FILE}")
endif()
install(FILES ${_FILE} DESTINATION ${_DEST}/${_FILEPREFIX} ${_REST})
endforeach()
endfunction()
# Treat warnings as errors. This is applied at module level: just add the line:
#
# ali_warnings_as_errors()
#
# to the relevant CMakeLists.txt.
macro(ali_warnings_as_errors)
if(${CMAKE_CXX_COMPILER_ID} MATCHES Clang OR CMAKE_COMPILER_IS_GNUCXX)
if(NOT ${CMAKE_SYSTEM_VERSION} MATCHES el5 AND NOT ${ROOT_VERSION_MAJOR} LESS 6)
message(STATUS "Treating warnings as errors under ${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
endif()
endmacro()