]> git.uio.no Git - u/mrichter/AliRoot.git/blob - cmake/CMakeALICE.cmake
generate_shared_library and generate_static_library macros
[u/mrichter/AliRoot.git] / cmake / CMakeALICE.cmake
1 # **************************************************************************
2 # * Copyright(c) 1998-2014, ALICE Experiment at CERN, All rights reserved. *
3 # *                                                                        *
4 # * Author: The ALICE Off-line Project.                                    *
5 # * Contributors are mentioned in the code where appropriate.              *
6 # *                                                                        *
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 # **************************************************************************
15
16 # General purpose functions
17
18 ###########################################################################
19 # ROOT utilities
20 ###########################################################################
21
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 macro(generate_dictionary DNAME LDNAME DHDRS DINCDIRS)
28     # Creating the INCLUDE path for cint/cling
29     foreach( dir ${DINCDIRS})
30         set(INCLUDE_PATH -I${dir} ${INCLUDE_PATH})
31     endforeach()
32     
33     # Generate the dictionary
34 #    message(STATUS "Generating dictionary ${DNAME} for ${LDNAME}")
35     
36 #    message(STATUS "${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx")
37 #    message(STATUS "${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.h")
38 #    message(STATUS "bbb${INCLUDE_PATH}bbb")
39 #    message(STATUS "${DHDRS} ${LDNAME}")
40 #    message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}")
41     
42     # Get the definitions from the directory to be sent to CINT
43     get_directory_property(tmpdirdefs DEFINITIONS)
44     string(REPLACE " " ";" tmpdirdefs ${tmpdirdefs})
45
46     add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.h
47                        COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_CINT}
48                        ARGS -f ${CMAKE_CURRENT_BINARY_DIR}/G__${DNAME}.cxx -c -p 
49                        ${tmpdirdefs} ${INCLUDE_PATH} 
50                        ${DHDRS} ${LDNAME}
51                        DEPENDS ${DHDRS} ${LDNAME} ${ROOT_CINT}
52                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
53                       )
54 endmacro(generate_dictionary)
55
56 # Generate the ROOTmap files
57 # @LIBNAME - library name: libAnalysis.so -> Analysis.rootmap
58 # @LIBDEPS - library dependencies
59 # @LINKDEF - LinkDef header
60 macro(generate_rootmap LIBNAME LIBDEPS LINKDEF)
61 #    message(STATUS "LIBNAME = ${LIBNAME}")
62 #    message(STATUS "LIBDEPS = ${LIBDEPS}")
63 #    message(STATUS "LINKDEF = ${LINKDEF}")
64 #    message(STATUS "ROOT_LIBMAP=${ROOT_LIBMAP}")
65
66     set(LOCAL_DEPS)
67     foreach(file ${LIBDEPS})
68         get_filename_component(ext ${file} EXT)
69         if(ext)
70             set(LOCAL_DEPS ${LOCAL_DEPS} ${file})
71         else()
72             set(LOCAL_DEPS ${LOCAL_DEPS} lib${file}.so)
73         endif()
74     endforeach()
75
76 #    message(STATUS "Generating ROOT map for ${LIBNAME}")
77     add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap
78                        COMMAND LD_LIBRARY_PATH=${ROOT_LIBDIR}:$ENV{LD_LIBRARY_PATH} ${ROOT_LIBMAP}
79                        ARGS -o ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap -l lib${LIBNAME}.so -d ${LOCAL_DEPS} -c ${LINKDEF}
80                        DEPENDS ${LIBNAME}
81                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM
82                       )
83     add_custom_target(lib${LIBNAME}.rootmap ALL DEPENDS  ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap)
84     install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}.rootmap DESTINATION lib)
85     
86 endmacro(generate_rootmap)
87
88 ###########################################################################
89 # Shared librarires utilities
90 ###########################################################################
91 macro(generate_shared_library)
92     # Generate the dictionary
93     # It will create G_ARG1.cxx and G_ARG1.h / ARG1 = function first argument
94     get_directory_property(incdirs INCLUDE_DIRECTORIES)
95     set(incdirs ${MODULE_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${incdirs})
96     generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${MODULE_HDRS}" "${incdirs}")
97
98     # Generate the ROOT map
99     # Dependecies
100     set(MODULE_LIBDEPS ${MODULE_ALIROOT_DEPENDENCIES} ${MODULE_ROOT_DEPENDENCIES})
101     generate_rootmap("${MODULE}" "${MODULE_LIBDEPS}" "${MODULE}LinkDef.h")
102
103     # Create an object to be reused in case of static libraries 
104     # Otherwise the sources will be compiled twice
105     add_library(${MODULE}-object OBJECT ${SRCS} G__${MODULE}.cxx)
106     # Add a library to the project using the object
107     add_library(${MODULE} SHARED $<TARGET_OBJECTS:${MODULE}-object>)
108     target_link_libraries(${MODULE} ${MODULE_LIBDEPS})
109
110     # Setting the correct headers for the object as gathered from the dependencies
111     target_include_directories(${MODULE}-object PUBLIC $<TARGET_PROPERTY:${MODULE},INCLUDE_DIRECTORIES>)
112     set_target_properties(${MODULE}-object PROPERTIES COMPILE_DEFINITIONS $<TARGET_PROPERTY:${MODULE},COMPILE_DEFINITIONS>)
113
114     # Public include folders that will be propagated to the dependecies
115     target_include_directories(${MODULE} PUBLIC ${incdirs})
116
117     # Setting compilation flags for the object
118     set_target_properties(${MODULE}-object PROPERTIES COMPILE_FLAGS "${MODULE_COMPILE_FLAGS}")
119     # Setting the linking flags for the library
120     set_target_properties(${MODULE} PROPERTIES LINK_FLAGS "${MODULE_LINK_FLAGS}")
121
122     # Installation
123     install(TARGETS ${MODULE}
124             ARCHIVE DESTINATION lib
125             LIBRARY DESTINATION lib)
126
127     install(FILES ${MODULE_HDRS_INSTALL} DESTINATION include)
128 endmacro()
129
130 ###########################################################################
131 # Static libraries utilities
132 ###########################################################################
133
134 # Generate the static dependecies from dynamic list
135 # @ shared_list - list of shared libraries
136 # @ static_list - the name of the variable that will contain the list of static libraries
137 macro(generate_static_dependencies shared_list static_list)
138     set(static_list_tmp "")
139     foreach(shared_lib ${shared_list})
140         set(static_list_tmp ${static_list_tmp} "${shared_lib}-static")
141     endforeach()
142     
143     # create the variable with the name received by the macro
144     set(${static_list} ${static_list_tmp})
145     # set the scope to parent in order to be visible in the parent
146     set(${static_list} PARENT_SCOPE)
147 endmacro(generate_static_dependencies)
148
149 macro(generate_static_library)
150     add_library(${MODULE}-static STATIC $<TARGET_OBJECTS:${MODULE}-object>)
151     
152     # list of shared dependencies / the name of the variable containing the list of static ones
153     generate_static_dependencies("${MODULE_ALIROOT_DEPENDENCIES}" "STATIC_ALIROOT_DEPENDENCIES")
154     target_link_libraries(${MODULE}-static ${STATIC_ALIROOT_DEPENDENCIES} Root RootExtra)
155     
156     # Public include folders that will be propagated to the dependecies
157     target_include_directories(${MODULE}-static PUBLIC ${incdirs})
158
159     set_target_properties(${MODULE}-static PROPERTIES OUTPUT_NAME ${MODULE})
160     set_target_properties(${MODULE}-static PROPERTIES LINK_FLAGS "-Wl,--whole-archive")
161
162     # Installation
163     install(TARGETS ${MODULE}-static
164             ARCHIVE DESTINATION lib
165             LIBRARY DESTINATION lib)
166 endmacro()
167
168 ###########################################################################
169 # DA utilities
170 ###########################################################################
171
172 # Extract the first comment from a DA file
173 # Find the position for first /* and */ and extract the substring
174 macro(getDAdescription _detector _daname)
175     # Reading the file into a string
176     file(READ "${_detector}${_daname}da.cxx" tmpinfo)
177     
178     # Find the first occurance of /* */
179     string(FIND "${tmpinfo}" "/*" _first_position)
180     string(FIND "${tmpinfo}" "*/" _second_position)
181     
182     # Adding and removing 2 characters to remove /* */
183     math(EXPR _first_position ${_first_position}+2)
184     math(EXPR _second_position ${_second_position}-2)
185     
186     # Generating the length of the comment in order to take out the description
187     math(EXPR _desc_length ${_second_position}-${_first_position})
188     
189     if(${_desc_length} EQUAL 0 OR ${_desc_length} LESS 0)
190         message(FATAL_ERROR "{_detector}${_daname}da.cxx does not contain a description. Please add the description as the first /*comment*/ in the file")
191     else()
192         string(SUBSTRING "${tmpinfo}" ${_first_position}  ${_second_position} _da_description)
193         string(STRIP ${_da_description} _da_description)
194         
195         # The variable can be accesed by the parent
196         set(RPM_DESCRIPTION ${_da_description})
197     endif()
198 endmacro()
199
200 # Set the compilation flags
201 macro(setDAflags)
202     # DIM
203     link_directories(${DIMDIR}/${ODIR})
204
205     #daqDA flags
206     include_directories(${daqDA})
207     link_directories(${daqDA})
208
209     # AMORE definitions
210     add_definitions(${AMORE_DEFINITIONS})
211     include_directories(${AMORE_INCLUDE_DIR})
212
213 endmacro()
214
215 # Generate a DA
216 macro(generateDA DETECTOR ALGORITHM STATIC_DEPENDENCIES)
217     setDAflags()
218
219     # Generating the DA executable
220     add_executable(${DETECTOR}${ALGORITHM}da ${DETECTOR}${ALGORITHM}da.cxx) #
221
222     # DA flags and linking information
223     set(MODULE_COMPILE_FLAGS)
224     set(MODULE_LINK_FLAGS)
225
226     target_link_libraries(${DETECTOR}${ALGORITHM}da ${STATIC_DEPENDENCIES} ${AMORE_AUXLIBS} daqDA ${DATE_MONLIBRARIES} ${DATE_RCPROXYLIBRARIES} Root RootExtra) # 1
227
228     # different flags
229     set(MODULE_COMPILE_FLAGS "  ${DATE_CFLAGS} ${AMORE_CFLAGS}")
230     set(MODULE_LINK_FLAGS "${DATE_LDFLAGS} ${AMORE_STATICLIBS}")
231
232     set_target_properties(${DETECTOR}${ALGORITHM}da PROPERTIES COMPILE_FLAGS ${MODULE_COMPILE_FLAGS})
233     set_target_properties(${DETECTOR}${ALGORITHM}da PROPERTIES LINK_FLAGS "${MODULE_LINK_FLAGS}")
234
235     # Installation
236     install(TARGETS ${DETECTOR}${ALGORITHM}da RUNTIME DESTINATION bin)
237     
238     if(DARPM)
239         createDArpm("${DETECTOR}" "${ALGORITHM}")
240     endif(DARPM)
241 endmacro()
242
243 # DA rpm creation
244 macro(createDArpm DETECTOR ALGORITHM)
245     getDAdescription("${DETECTOR}" "${ALGORITHM}")
246
247     set(DA_EXECUTABLE "${DETECTOR}${ALGORITHM}da")
248     set(DETECTOR "${DETECTOR}")
249     set(ALGORITHM "${ALGORITHM}")
250     set(RPM_DESCRIPTION ${RPM_DESCRIPTION})
251     
252     if(ALGORITHM STREQUAL "")
253         set(_ALGORITHM "none")
254         set(DA_PREFIX "opt/daqDA-${DETECTOR}")
255         set(DA_NAME "daqDA-${DETECTOR}")
256     else()
257         set(_ALGORITHM ${ALGORITHM})
258         set(DA_PREFIX "opt/daqDA-${DETECTOR}-${ALGORITHM}")
259         set(DA_NAME "daqDA-${DETECTOR}-${ALGORITHM}")
260     endif()
261
262     configure_file("${AliRoot_SOURCE_DIR}/cmake/da.spec.in" "${_ALGORITHM}-da.spec" @ONLY)
263
264     add_custom_command(TARGET ${DETECTOR}${ALGORITHM}da POST_BUILD
265                        COMMAND mkdir ARGS -p da-${_ALGORITHM}-rpm/root/${DA_PREFIX}/
266                        COMMAND cp ARGS ${DETECTOR}${ALGORITHM}da da-${_ALGORITHM}-rpm/root/${DA_PREFIX}/
267                        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
268                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM
269                        COMMENT "RPM creation for ${DETECTOR}-${_ALGORITHM}"
270     )
271     
272     # make clean will remove also the rpm folder
273     # Retrive the current list of file to be deleted - set_directory_property is overwriting, not adding to the list
274     get_directory_property(_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
275     set(_clean_files da-${_ALGORITHM}-rpm  ${_clean_files})
276     set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_clean_files}")
277     
278     # install RPM into $CMAKE_INSTALL_PREFIX/darpms
279     install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/da-${_ALGORITHM}-rpm/RPMS/ DESTINATION darpms PATTERN "\\.rpm")
280 endmacro()