1 # **************************************************************************
2 # * Copyright(c) 1998-2014, ALICE Experiment at CERN, All rights reserved. *
4 # * Author: The ALICE Off-line Project. *
5 # * Contributors are mentioned in the code where appropriate. *
7 # * Permission to use, copy, modify and distribute this software and its *
8 # * documentation strictly for non-commercial purposes is hereby granted *
9 # * without fee, provided that the above copyright notice appears in all *
10 # * copies and that both the copyright notice and this permission notice *
11 # * appear in the supporting documentation. The authors make no claims *
12 # * about the suitability of this software for any purpose. It is *
13 # * provided "as is" without express or implied warranty. *
14 # **************************************************************************
16 # General purpose functions
18 #########################
20 #########################
22 # Generation of the dictionaries
23 # @DNAME Dictionary name
24 # @LDNAME LinkDef file name, ex: LinkDef.h
25 # @DHDRS Dictionary headers
26 # @DINCDIR Include folders that need to be passed to cint/cling
27 # @EXTRADEFINITIONS - optional, extra compile flags specific to library
29 macro(generate_dictionary DNAME LDNAME DHDRS DINCDIRS)
31 # Creating the INCLUDE path for cint/cling
32 foreach( dir ${DINCDIRS})
33 set(INCLUDE_PATH -I${dir} ${INCLUDE_PATH})
36 # Get the list of definitions from the directory to be sent to CINT
37 get_directory_property(tmpdirdefs COMPILE_DEFINITIONS)
38 foreach(dirdef ${tmpdirdefs})
39 set(GLOBALDEFINITIONS -D${dirdef} ${GLOBALDEFINITIONS})
42 # Custom definitions specific to library
43 # Received as the forth optional argument
44 separate_arguments(EXTRADEFINITIONS UNIX_COMMAND "${ARGV4}")
46 if (ROOT_VERSION_MAJOR LESS 6)
47 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.h
48 COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_CINT}
49 ARGS -f ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx -c -p
50 ${GLOBALDEFINITIONS} ${EXTRADEFINITIONS} ${INCLUDE_PATH}
52 DEPENDS ${DHDRS} ${LDNAME} ${ROOT_CINT}
53 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
55 else (ROOT_VERSION_MAJOR LESS 6)
56 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib${DNAME}.rootmap ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx
58 LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_CINT}
60 -f ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx
61 -rmf ${CMAKE_CURRENT_BINARY_DIR}/lib${DNAME}.rootmap -rml lib${DNAME}
62 ${GLOBALDEFINITIONS} ${EXTRADEFINITIONS} ${INCLUDE_PATH} ${DHDRS} ${LDNAME}
64 ${DHDRS} ${LDNAME} ${ROOT_CINT}
66 ${CMAKE_CURRENT_BINARY_DIR}
68 endif (ROOT_VERSION_MAJOR LESS 6)
70 endmacro(generate_dictionary)
72 # Generate the ROOTmap files
73 # @LIBNAME - library name: libAnalysis.so -> Analysis.rootmap
74 # @LIBDEPS - library dependencies
75 # @LINKDEF - LinkDef header
76 macro(generate_rootmap LIBNAME LIBDEPS LINKDEF)
77 # message(STATUS "LIBNAME = ${LIBNAME}")
78 # message(STATUS "LIBDEPS = ${LIBDEPS}")
79 # message(STATUS "LINKDEF = ${LINKDEF}")
80 # message(STATUS "ROOT_LIBMAP=${ROOT_LIBMAP}")
82 if (ROOT_VERSION_MAJOR LESS 6)
85 foreach(file ${LIBDEPS})
86 get_filename_component(ext ${file} EXT)
88 set(LOCAL_DEPS ${LOCAL_DEPS} ${file})
90 set(LOCAL_DEPS ${LOCAL_DEPS} lib${file})
94 # message(STATUS "Generating ROOT map for ${LIBNAME}")
95 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap
96 COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_LIBMAP}
97 ARGS -o ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap -l lib${LIBNAME} -d ${LOCAL_DEPS} -c ${LINKDEF}
99 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM
101 add_custom_target(lib${LIBNAME}.rootmap ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap)
102 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap DESTINATION lib)
104 endif (ROOT_VERSION_MAJOR LESS 6)
106 endmacro(generate_rootmap)
108 #########################
110 #########################
112 # Generate the static dependecies from dynamic list
113 # @ shared_list - list of shared libraries
114 # @ static_list - the name of the variable that will contain the list of static libraries
115 macro(generate_static_dependencies shared_list static_list)
116 set(static_list_tmp "")
117 foreach(shared_lib ${shared_list})
118 set(static_list_tmp ${static_list_tmp} "${shared_lib}-static")
121 # create the variable with the name received by the macro
122 set(${static_list} ${static_list_tmp})
123 # set the scope to parent in order to be visible in the parent
124 set(${static_list} PARENT_SCOPE)
125 endmacro(generate_static_dependencies)
127 #########################
129 #########################
131 # Extract the first comment from a DA file
132 # Find the position for first /* and */ and extract the substring
133 macro(getDAdescription _detector _daname)
134 # Reading the file into a string
135 file(READ "${_detector}${_daname}da.cxx" tmpinfo)
137 # Find the first occurance of /* */
138 string(FIND "${tmpinfo}" "/*" _first_position)
139 string(FIND "${tmpinfo}" "*/" _second_position)
141 # Adding and removing 2 characters to remove /* */
142 math(EXPR _first_position ${_first_position}+2)
143 math(EXPR _second_position ${_second_position}-2)
145 # Generating the length of the comment in order to take out the description
146 math(EXPR _desc_length ${_second_position}-${_first_position})
148 if(${_desc_length} EQUAL 0 OR ${_desc_length} LESS 0)
149 message(FATAL_ERROR "{_detector}${_daname}da.cxx does not contain a description. Please add the description as the first /*comment*/ in the file")
151 string(SUBSTRING "${tmpinfo}" ${_first_position} ${_second_position} _da_description)
152 string(STRIP "${_da_description}" _da_description)
154 # The variable can be accesed by the parent
155 set(RPM_DESCRIPTION ${_da_description})
159 # Set the compilation flags
162 link_directories(${DIMDIR}/${ODIR})
165 include_directories(${daqDA})
166 link_directories(${daqDA})
169 add_definitions(${AMORE_DEFINITIONS})
170 include_directories(${AMORE_INCLUDE_DIR})
175 macro(generateDA DETECTOR ALGORITHM STATIC_DEPENDENCIES)
178 # Generating the DA executable
179 add_executable(${DETECTOR}${ALGORITHM}da.exe ${DETECTOR}${ALGORITHM}da.cxx) #
181 # DA flags and linking information
182 set(MODULE_COMPILE_FLAGS)
183 set(MODULE_LINK_FLAGS)
185 target_link_libraries(${DETECTOR}${ALGORITHM}da.exe ${STATIC_DEPENDENCIES} ${AMORE_AUXLIBS} daqDA ${DATE_MONLIBRARIES} ${DATE_RCPROXYLIBRARIES} Root RootExtra) # 1
188 set(MODULE_COMPILE_FLAGS " ${DATE_CFLAGS} ${AMORE_CFLAGS}")
189 set(MODULE_LINK_FLAGS "${DATE_LDFLAGS} ${AMORE_STATICLIBS}")
191 set_target_properties(${DETECTOR}${ALGORITHM}da.exe PROPERTIES COMPILE_FLAGS ${MODULE_COMPILE_FLAGS})
192 set_target_properties(${DETECTOR}${ALGORITHM}da.exe PROPERTIES LINK_FLAGS "${MODULE_LINK_FLAGS}")
195 install(TARGETS ${DETECTOR}${ALGORITHM}da.exe RUNTIME DESTINATION bin)
198 createDArpm("${DETECTOR}" "${ALGORITHM}")
203 macro(createDArpm DETECTOR ALGORITHM)
204 getDAdescription("${DETECTOR}" "${ALGORITHM}")
206 set(DA_EXECUTABLE "${DETECTOR}${ALGORITHM}da.exe")
207 set(DETECTOR "${DETECTOR}")
208 set(ALGORITHM "${ALGORITHM}")
209 set(RPM_DESCRIPTION ${RPM_DESCRIPTION})
211 if(ALGORITHM STREQUAL "")
212 set(_ALGORITHM "none")
213 set(DA_PREFIX "opt/daqDA-${DETECTOR}")
214 set(DA_NAME "daqDA-${DETECTOR}")
216 set(_ALGORITHM ${ALGORITHM})
217 set(DA_PREFIX "opt/daqDA-${DETECTOR}-${ALGORITHM}")
218 set(DA_NAME "daqDA-${DETECTOR}-${ALGORITHM}")
221 configure_file("${AliRoot_SOURCE_DIR}/cmake/da.spec.in" "${_ALGORITHM}-da.spec" @ONLY)
223 add_custom_command(TARGET ${DETECTOR}${ALGORITHM}da.exe POST_BUILD
224 COMMAND mkdir ARGS -p da-${_ALGORITHM}-rpm/root/${DA_PREFIX}/
225 COMMAND cp ARGS ${DETECTOR}${ALGORITHM}da.exe da-${_ALGORITHM}-rpm/root/${DA_PREFIX}/
226 COMMAND rpmbuild ARGS --verbose --define "_topdir ${CMAKE_CURRENT_BINARY_DIR}/da-${_ALGORITHM}-rpm" --define "%buildroot ${CMAKE_CURRENT_BINARY_DIR}/da-${_ALGORITHM}-rpm/root" -bb ${_ALGORITHM}-da.spec
227 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM
228 COMMENT "RPM creation for ${DETECTOR}-${_ALGORITHM}"
231 # make clean will remove also the rpm folder
232 # Retrive the current list of file to be deleted - set_directory_property is overwriting, not adding to the list
233 get_directory_property(_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
234 set(_clean_files da-${_ALGORITHM}-rpm ${_clean_files})
235 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_clean_files}")
237 # install RPM into $CMAKE_INSTALL_PREFIX/darpms
238 install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/da-${_ALGORITHM}-rpm/RPMS/ DESTINATION darpms PATTERN "\\.rpm")
242 # Prepend prefix to every element in the list. Note: this function modifies the input variable: this
243 # does not work for macros in CMake, only for functions. Also note that it does NOT automatically
244 # add a / between prefix and list item as it does not assume that we are dealing with directories
245 function(prepend_prefix INLIST PREFIX)
246 foreach(_ITEM ${${INLIST}})
247 list(APPEND _OUTLIST ${PREFIX}${_ITEM})
249 set(${INLIST} ${_OUTLIST} PARENT_SCOPE)
253 # This function is a drop-in replacement for the following CMake command:
255 # install(FILES ... DESTINATION ... [OTHER_ARGS])
257 # The above command takes every single file and puts it in the destination directory, but relative
258 # paths are not taken into consideration, i.e. files a/b/c/file.h and boo.h will be both installed
261 # By replacing install() with install_relative(), boo.h will end in dest, and a/b/c/file.h will end
262 # in dest/a/b/c/file.h, i.e. relative paths are taken into account.
264 # If an absolute path was specified for an input file, a fatal error will be raised: only relative
265 # paths can be specified.
267 # Since it is a drop-in command, its syntax is identical to install():
269 # install_relative(FILES ... DESTINATION ... [OTHER_ARGS])
271 # where OTHER_ARGS is passed as-is to the underlying install() command
272 function(install_relative)
274 set(_EXPECT_FILE TRUE)
275 set(_EXPECT_DEST FALSE)
276 set(_EXPECT_REST FALSE)
278 foreach(_ARG ${ARGN})
282 if(${_ARG} STREQUAL "FILES")
283 set(_EXPECT_FILE FALSE)
285 message(FATAL_ERROR "You may only use install_relative() in place of install(FILES ...)")
289 # Remaining arguments
290 list(APPEND _REST ${_ARG})
294 set(_EXPECT_DEST FALSE)
295 set(_EXPECT_REST TRUE)
296 elseif(_ARG STREQUAL "DESTINATION")
297 # From now on, copy the arguments ditto to the install() command
298 set(_EXPECT_DEST TRUE)
300 # Append files to install
301 list(APPEND _FILES ${_ARG})
306 # Print out our results (debug)
307 #message(STATUS "[install_relative] FILES: ${_FILES}")
308 #message(STATUS "[install_relative] DEST: ${_DEST}")
309 #message(STATUS "[install_relative] REST: ${_REST}")
311 # Prepare a distinct install command for each file, depending on its path
312 foreach(_FILE ${_FILES})
314 if(CMAKE_VERSION VERSION_LESS "2.8.12")
315 get_filename_component(_FILEPREFIX ${_FILE} PATH)
317 get_filename_component(_FILEPREFIX ${_FILE} DIRECTORY)
319 #message(STATUS "[install_relative] ${_FILE} --> ${_FILEPREFIX}")
321 string(SUBSTRING ${_FILE} 0 1 _FILE_FIRST)
322 if(${_FILE_FIRST} STREQUAL "/")
323 # An absolute path was found: not supported, error
324 message(FATAL_ERROR "Absolute paths are not supported by install_relative(): ${_FILE}")
327 install(FILES ${_FILE} DESTINATION ${_DEST}/${_FILEPREFIX} ${_REST})