]>
Commit | Line | Data |
---|---|---|
da32329d AM |
1 | ########################################################################### |
2 | # | |
3 | # Copyright 2010 | |
4 | # | |
5 | # This file is part of Starlight. | |
6 | # | |
7 | # Starlight is free software: you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation, either version 3 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # Starlight is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with Starlight. If not, see <http://www.gnu.org/licenses/>. | |
19 | # | |
20 | ########################################################################### | |
21 | # | |
22 | # File and Version Information: | |
23 | # $Rev:: 28 $: revision of last commit | |
24 | # $Author:: bgrube $: author of last commit | |
25 | # $Date:: 2010-12-10 19:30:01 +0100 #$: date of last commit | |
26 | # | |
27 | # Description: | |
28 | # cmake module for finding ROOT installation | |
29 | # requires root-config to be in PATH | |
30 | # based on AliRoots's FindROOT.cmake (r41015) | |
31 | # in https://alisoft.cern.ch/AliRoot/trunk/cmake/modules | |
32 | # | |
33 | # following variables are defined: | |
34 | # ROOT_CONFIG_EXECUTABLE - path to root-config program | |
35 | # ROOTSYS - path to root installation directory | |
36 | # ROOT_TARGET - target architecture | |
37 | # ROOT_F77 - Fortran complier used building ROOT | |
38 | # ROOT_CC - C complier used building ROOT | |
39 | # ROOT_CPP - C++ complier used building ROOT | |
40 | # ROOT_VERSION - ROOT version | |
41 | # ROOT_SVN_REVISION - ROOT subversion revision | |
42 | # ROOT_BIN_DIR - ROOT executable directory | |
43 | # ROOT_INCLUDE_DIR - ROOT header directory | |
44 | # ROOT_LIBRARY_DIR - ROOT library directory | |
45 | # ROOT_LIBRARIES - linker flags for ROOT libraries | |
46 | # ROOT_AUX_LIBRARIES - linker flags for auxiliary libraries | |
47 | # ROOTCINT_EXECUTABLE - path to rootcint program | |
48 | # ROOT_MAJOR_VERSION - ROOT major version | |
49 | # ROOT_MINOR_VERSION - ROOT minor version | |
50 | # ROOT_PATCH_VERSION - ROOT patch level | |
51 | # ROOT_LIBS - list of ROOT library files | |
52 | # | |
53 | # Example usage: | |
54 | # find_package(ROOT 5.26 REQUIRED Minuit2) | |
55 | # | |
56 | # | |
57 | # The module also provides a function to generate ROOT dictionaries. | |
58 | # Example usage: | |
59 | # set(ROOTPWA_DICTIONARY ${CMAKE_CURRENT_BINARY_DIR}/someDict.cc) # set dictionary path | |
60 | # root_generate_dictionary( | |
61 | # "${ROOTPWA_DICTIONARY}" # path to dictionary to generate | |
62 | # "${INCLUDE_DIR1};${INCLUDE_DIR2}" # list of includes | |
63 | # "class1.h;class2.h;class3.h" # list of classes to process | |
64 | # "someLinkDef.h" # ROOT linkDef file | |
65 | # ) | |
66 | # set(SOURCES ${SOURCES} ${ROOTPWA_DICTIONARY}) # append dictionary to sources | |
67 | # | |
68 | # | |
69 | ########################################################################### | |
70 | ||
71 | ||
72 | set(ROOT_FOUND FALSE) | |
73 | set(ROOT_ERROR_REASON "") | |
74 | set(ROOT_DEFINITIONS "") | |
75 | set(ROOT_LIBS) | |
76 | ||
77 | ||
78 | find_program(ROOT_CONFIG_EXECUTABLE root-config) | |
79 | if(NOT ROOT_CONFIG_EXECUTABLE) | |
80 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} Cannot find root-config.") | |
81 | else() | |
82 | ||
83 | set(ROOT_FOUND TRUE) | |
84 | ||
85 | execute_process( | |
86 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix | |
87 | OUTPUT_VARIABLE ROOTSYS | |
88 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
89 | ||
90 | execute_process( | |
91 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --arch | |
92 | OUTPUT_VARIABLE ROOT_TARGET | |
93 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
94 | ||
95 | execute_process( | |
96 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --f77 | |
97 | OUTPUT_VARIABLE ROOT_F77 | |
98 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
99 | ||
100 | execute_process( | |
101 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --cc | |
102 | OUTPUT_VARIABLE ROOT_CC | |
103 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
104 | ||
105 | execute_process( | |
106 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --cxx | |
107 | OUTPUT_VARIABLE ROOT_CPP | |
108 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
109 | ||
110 | execute_process( | |
111 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --version | |
112 | OUTPUT_VARIABLE ROOT_VERSION | |
113 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
114 | ||
115 | execute_process( | |
116 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --svn-revision | |
117 | OUTPUT_VARIABLE ROOT_SVN_REVISION | |
118 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
119 | ||
120 | execute_process( | |
121 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --bindir | |
122 | OUTPUT_VARIABLE ROOT_BIN_DIR | |
123 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
124 | if(NOT EXISTS "${ROOT_BIN_DIR}") | |
125 | set(ROOT_FOUND FALSE) | |
126 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} ROOT executable directory ${ROOT_BIN_DIR} does not exist.") | |
127 | endif() | |
128 | ||
129 | execute_process( | |
130 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --incdir | |
131 | OUTPUT_VARIABLE ROOT_INCLUDE_DIR | |
132 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
133 | if(NOT EXISTS "${ROOT_INCLUDE_DIR}") | |
134 | set(ROOT_FOUND FALSE) | |
135 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} ROOT include directory ${ROOT_INCLUDE_DIR} does not exist.") | |
136 | endif() | |
137 | ||
138 | execute_process( | |
139 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --libdir | |
140 | OUTPUT_VARIABLE ROOT_LIBRARY_DIR | |
141 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
142 | if(NOT EXISTS "${ROOT_LIBRARY_DIR}") | |
143 | set(ROOT_FOUND FALSE) | |
144 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} ROOT library directory ${ROOT_LIBRARY_DIR} does not exist.") | |
145 | endif() | |
146 | ||
147 | execute_process( | |
148 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --noauxlibs --glibs | |
149 | OUTPUT_VARIABLE ROOT_LIBRARIES | |
150 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
151 | ||
152 | execute_process( | |
153 | COMMAND ${ROOT_CONFIG_EXECUTABLE} --auxlibs | |
154 | OUTPUT_VARIABLE ROOT_AUX_LIBRARIES | |
155 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
156 | ||
157 | find_program(ROOTCINT_EXECUTABLE rootcint) | |
158 | if(NOT ROOTCINT_EXECUTABLE) | |
159 | set(ROOT_FOUND FALSE) | |
160 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} Cannot find rootcint.") | |
161 | endif() | |
162 | ||
163 | # parse version string | |
164 | string(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+.*" "\\1" | |
165 | ROOT_MAJOR_VERSION "${ROOT_VERSION}") | |
166 | string(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" | |
167 | ROOT_MINOR_VERSION "${ROOT_VERSION}") | |
168 | string(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+).*" "\\1" | |
169 | ROOT_PATCH_VERSION "${ROOT_VERSION}") | |
da32329d AM |
170 | # make sure minor version is specified |
171 | if(ROOT_FIND_VERSION AND NOT ROOT_FIND_VERSION_MINOR) | |
172 | message(FATAL_ERROR "When requesting a specific version of ROOT, you must provide at least the major and minor version numbers, e.g., 5.22") | |
173 | endif() | |
174 | # set patchlevel to 0, if not specified | |
175 | if(NOT ROOT_FIND_VERSION_PATCH) | |
176 | set(ROOT_FIND_VERSION_PATCH 0) | |
177 | endif() | |
178 | # compute an overall version number which can be compared at once | |
179 | math(EXPR _ROOT_FIND_VERSION "${ROOT_FIND_VERSION_MAJOR} * 10000 + ${ROOT_FIND_VERSION_MINOR} * 100 + ${ROOT_FIND_VERSION_PATCH}") | |
180 | math(EXPR _ROOT_VERSION "${ROOT_MAJOR_VERSION} * 10000 + ${ROOT_MINOR_VERSION} * 100 + ${ROOT_PATCH_VERSION}") | |
181 | # compare version | |
182 | if(ROOT_FIND_VERSION_EXACT) | |
183 | if(NOT _ROOT_VERSION EQUAL "${_ROOT_FIND_VERSION}") | |
184 | set(ROOT_FOUND FALSE) | |
185 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} ROOT version ${ROOT_VERSION} does not match requested version ${ROOT_FIND_VERSION_MAJOR}.${ROOT_FIND_VERSION_MINOR}/${ROOT_FIND_VERSION_PATCH}.") | |
186 | endif() | |
187 | else() | |
188 | if(_ROOT_VERSION LESS "${_ROOT_FIND_VERSION}") | |
189 | set(ROOT_FOUND FALSE) | |
190 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} ROOT version ${ROOT_VERSION} is lower than requested version ${ROOT_FIND_VERSION_MAJOR}.${ROOT_FIND_VERSION_MINOR}/${ROOT_FIND_VERSION_PATCH}.") | |
191 | endif() | |
192 | endif() | |
193 | ||
194 | endif() | |
195 | ||
196 | ||
197 | # generate list of ROOT libraries | |
198 | if(ROOT_FOUND) | |
199 | ||
200 | # create list of internal libraries from root-config output | |
201 | set(_LIBRARY_NAMES) | |
202 | set(_EXTERNAL_ZLIB) | |
203 | separate_arguments(ROOT_LIBRARIES) | |
204 | # remove first -L entry | |
205 | list(REMOVE_AT ROOT_LIBRARIES 0) | |
206 | # loop over -l entries | |
207 | foreach(_LIBRARY ${ROOT_LIBRARIES}) | |
208 | # extract library name from compiler flag and append to list | |
209 | string(REGEX REPLACE "^-.(.*)$" "\\1" _LIBNAME "${_LIBRARY}") | |
210 | # workaround for root-config inconsistency: if ROOT is built with --disable-builtin-zlib | |
211 | # root-config returns the flag for the external zlib together with the internal libraries | |
212 | if(_LIBNAME STREQUAL "z") | |
213 | set(_EXTERNAL_ZLIB "-lz") | |
214 | else() | |
215 | list(APPEND _LIBRARY_NAMES ${_LIBNAME}) | |
216 | endif() | |
217 | endforeach() | |
218 | ||
219 | # append components | |
220 | list(REMOVE_DUPLICATES ROOT_FIND_COMPONENTS) | |
221 | if(ROOT_FIND_COMPONENTS) | |
222 | set(_LIBRARY_NAMES "${_LIBRARY_NAMES};${ROOT_FIND_COMPONENTS}") | |
223 | endif() | |
224 | ||
225 | # check whether libraries exist | |
226 | foreach(_LIBNAME ${_LIBRARY_NAMES}) | |
227 | find_library(_ROOT_LIB_${_LIBNAME} | |
228 | NAMES ${_LIBNAME} | |
229 | PATHS ${ROOT_LIBRARY_DIR} | |
230 | NO_DEFAULT_PATH) | |
231 | if(NOT _ROOT_LIB_${_LIBNAME}) | |
232 | set(ROOT_FOUND FALSE) | |
233 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} Cannot find ROOT library ${_LIBNAME} in ${ROOT_LIBRARY_DIR}.") | |
234 | else() | |
235 | list(APPEND ROOT_LIBS ${_ROOT_LIB_${_LIBNAME}}) | |
236 | endif() | |
237 | endforeach() | |
238 | ||
239 | # create list of external libraries from root-config output | |
240 | separate_arguments(ROOT_AUX_LIBRARIES) | |
241 | # append external zlib to auxiliary libraries | |
242 | if(_EXTERNAL_ZLIB) | |
243 | list(APPEND ROOT_AUX_LIBRARIES ${_EXTERNAL_ZLIB}) | |
244 | endif() | |
245 | # loop over -l entries | |
246 | foreach(_LIBRARY ${ROOT_AUX_LIBRARIES}) | |
247 | # extract library name from compiler flag | |
248 | string(REGEX MATCH "^-l(.*)$" _LIBNAME "${_LIBRARY}") | |
249 | if(_LIBNAME) | |
250 | string(REGEX REPLACE "^-.(.*)$" "\\1" _LIBNAME "${_LIBNAME}") | |
251 | # check whether libraries exist | |
252 | find_library(_AUX_LIB_${_LIBNAME} | |
253 | NAMES ${_LIBNAME}) | |
254 | if(NOT _AUX_LIB_${_LIBNAME}) | |
255 | set(ROOT_FOUND FALSE) | |
256 | set(ROOT_ERROR_REASON "${ROOT_ERROR_REASON} Cannot find ROOT library ${_LIBNAME}.") | |
257 | else() | |
258 | list(APPEND ROOT_LIBS ${_AUX_LIB_${_LIBNAME}}) | |
259 | endif() | |
260 | endif() | |
261 | endforeach() | |
262 | ||
263 | endif() | |
264 | ||
265 | ||
266 | # make variables changeable | |
267 | mark_as_advanced( | |
268 | ROOT_INCLUDE_DIR | |
269 | ROOT_LIBRARY_DIR | |
270 | ROOT_LIBRARIES | |
271 | ROOT_LIBS | |
272 | ROOT_DEFINITIONS | |
273 | ) | |
274 | ||
275 | ||
276 | # report result | |
277 | if(ROOT_FOUND) | |
278 | message(STATUS "Found ROOT version ${ROOT_VERSION} r${ROOT_SVN_REVISION} in ${ROOTSYS}") | |
279 | message(STATUS "Using ROOT include dir ${ROOT_INCLUDE_DIR}") | |
280 | message(STATUS "Using ROOT library dir ${ROOT_LIBRARY_DIR}") | |
281 | message(STATUS "Using ROOT libraries: ${ROOT_LIBRARIES}") | |
282 | message(STATUS "Using ROOT additional components: ${ROOT_FIND_COMPONENTS}") | |
283 | else() | |
284 | if(ROOT_FIND_REQUIRED) | |
285 | message(FATAL_ERROR "Unable to find requested ROOT installation:${ROOT_ERROR_REASON}") | |
286 | else() | |
287 | if(NOT ROOT_FIND_QUIETLY) | |
288 | message(STATUS "ROOT was not found.") | |
289 | endif() | |
290 | endif() | |
291 | endif() | |
292 | ||
293 | ||
294 | # macro that generates ROOT dictionary | |
295 | function(root_generate_dictionary DICT_FILE INCLUDE_DIRS HEADER_FILES LINKDEF_FILE) | |
296 | ||
297 | if(NOT ROOT_FOUND) | |
298 | message(FATAL_ERROR "Impossible to generate dictionary ${DICT_FILE}, because no ROOT installation was found.") | |
299 | endif() | |
300 | ||
301 | # prepare command line argument for compiler definitions (put -D in front) | |
302 | set(_DEFINITIONS) | |
303 | get_property(_DEFS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY COMPILE_DEFINITIONS) | |
304 | foreach(_DEF ${_DEFS}) | |
305 | set(_DEFINITIONS "${_DEFINITIONS} -D${_DEF}") | |
306 | endforeach() | |
307 | separate_arguments(_DEFINITIONS) | |
308 | ||
309 | # prepare command line argument for include directories (put -I in front) | |
310 | set(_INCLUDES) | |
311 | foreach(_FILE ${INCLUDE_DIRS}) | |
312 | set(_INCLUDES ${_INCLUDES} -I${_FILE}) | |
313 | endforeach() | |
314 | ||
315 | # strip paths from header file names | |
316 | set(_HEADERS) | |
317 | foreach(_FILE ${HEADER_FILES}) | |
318 | get_filename_component(_NAME ${_FILE} NAME) | |
319 | set(_HEADERS ${_HEADERS} ${_NAME}) | |
320 | endforeach() | |
321 | ||
322 | # add dictionary header file to output files | |
323 | string(REGEX REPLACE "^(.*)\\.(.*)$" "\\1.h" _DICT_HEADER "${DICT_FILE}") | |
324 | set(OUTPUT_FILES ${DICT_FILE} ${_DICT_HEADER}) | |
325 | ||
326 | add_custom_command(OUTPUT ${OUTPUT_FILES} | |
327 | COMMAND ${ROOTCINT_EXECUTABLE} | |
328 | ARGS -f ${DICT_FILE} -c -DHAVE_CONFIG_H ${_DEFINITIONS} ${_INCLUDES} ${_HEADERS} ${LINKDEF_FILE} | |
329 | DEPENDS ${HEADER_FILES} ${LINKDEF_FILE} | |
330 | ) | |
331 | ||
332 | endfunction(root_generate_dictionary) |