1 ################################################################################################
2 # Command alias for debugging messages
6 message(STATUS ${ARGN})
9 ################################################################################################
10 # Removes duplicates from list(s)
12 # caffe_list_unique(<list_variable> [<list_variable>] [...])
13 macro(caffe_list_unique)
14 foreach(__lst ${ARGN})
16 list(REMOVE_DUPLICATES ${__lst})
21 ################################################################################################
22 # Clears variables from list
24 # caffe_clear_vars(<variables_list>)
25 macro(caffe_clear_vars)
31 ################################################################################################
32 # Removes duplicates from string
34 # caffe_string_unique(<string_variable>)
35 function(caffe_string_unique __string)
37 set(__list ${${__string}})
38 separate_arguments(__list)
39 list(REMOVE_DUPLICATES __list)
40 foreach(__e ${__list})
41 set(__str "${__str} ${__e}")
43 set(${__string} ${__str} PARENT_SCOPE)
47 ################################################################################################
48 # Prints list element per line
50 # caffe_print_list(<list>)
51 function(caffe_print_list)
57 ################################################################################################
58 # Function merging lists of compiler flags to single string.
60 # caffe_merge_flag_lists(out_variable <list1> [<list2>] [<list3>] ...)
61 function(caffe_merge_flag_lists out_var)
63 foreach(__list ${ARGN})
64 foreach(__flag ${${__list}})
65 string(STRIP ${__flag} __flag)
66 set(__result "${__result} ${__flag}")
69 string(STRIP ${__result} __result)
70 set(${out_var} ${__result} PARENT_SCOPE)
73 ################################################################################################
74 # Converts all paths in list to absolute
76 # caffe_convert_absolute_paths(<list_variable>)
77 function(caffe_convert_absolute_paths variable)
79 foreach(__s ${${variable}})
80 get_filename_component(__abspath ${__s} ABSOLUTE)
81 list(APPEND __list ${__abspath})
83 set(${variable} ${__list} PARENT_SCOPE)
86 ################################################################################################
87 # Reads set of version defines from the header file
89 # caffe_parse_header(<file> <define1> <define2> <define3> ..)
90 macro(caffe_parse_header FILENAME FILE_VAR)
92 set(__parnet_scope OFF)
95 if("${name}" STREQUAL "PARENT_SCOPE")
96 set(__parnet_scope ON)
97 elseif("${name}" STREQUAL "CACHE")
100 set(vars_regex "${vars_regex}|${name}")
102 set(vars_regex "${name}")
105 if(EXISTS "${FILENAME}")
106 file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
110 foreach(name ${ARGN})
111 if(NOT "${name}" STREQUAL "PARENT_SCOPE" AND NOT "${name}" STREQUAL "CACHE")
113 if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
114 string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
119 set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
120 elseif(__parnet_scope)
121 set(${name} "${${name}}" PARENT_SCOPE)
130 ################################################################################################
131 # Reads single version define from the header file and parses it
133 # caffe_parse_header_single_define(<library_name> <file> <define_name>)
134 function(caffe_parse_header_single_define LIBNAME HDR_PATH VARNAME)
136 if(EXISTS "${HDR_PATH}")
137 file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
141 string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
142 string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR "${${LIBNAME}_H}")
143 string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
144 set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN} PARENT_SCOPE)
145 set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN} PARENT_SCOPE)
146 set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN} PARENT_SCOPE)
147 set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}" PARENT_SCOPE)
149 # append a TWEAK version if it exists:
150 set(${LIBNAME}_VERSION_TWEAK "")
151 if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
152 set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN} PARENT_SCOPE)
154 if(${LIBNAME}_VERSION_TWEAK)
155 set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN} PARENT_SCOPE)
157 set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN} PARENT_SCOPE)
162 ########################################################################################################
163 # An option that the user can select. Can accept condition to control when option is available for user.
165 # caffe_option(<option_variable> "doc string" <initial value or boolean expression> [IF <condition>])
166 function(caffe_option variable description value)
167 set(__value ${value})
169 set(__varname "__value")
171 if(arg STREQUAL "IF" OR arg STREQUAL "if")
172 set(__varname "__condition")
174 list(APPEND ${__varname} ${arg})
178 if("${__condition}" STREQUAL "")
179 set(__condition 2 GREATER 1)
183 if("${__value}" MATCHES ";")
185 option(${variable} "${description}" ON)
187 option(${variable} "${description}" OFF)
189 elseif(DEFINED ${__value})
191 option(${variable} "${description}" ON)
193 option(${variable} "${description}" OFF)
196 option(${variable} "${description}" ${__value})
199 unset(${variable} CACHE)
203 ################################################################################################
204 # Utility macro for comparing two lists. Used for CMake debugging purposes
206 # caffe_compare_lists(<list_variable> <list2_variable> [description])
207 function(caffe_compare_lists list1 list2 desc)
208 set(__list1 ${${list1}})
209 set(__list2 ${${list2}})
212 list(LENGTH __list1 __len1)
213 list(LENGTH __list2 __len2)
215 if(NOT ${__len1} EQUAL ${__len2})
216 message(FATAL_ERROR "Lists are not equal. ${__len1} != ${__len2}. ${desc}")
219 foreach(__i RANGE 1 ${__len1})
220 math(EXPR __index "${__i}- 1")
221 list(GET __list1 ${__index} __item1)
222 list(GET __list2 ${__index} __item2)
223 if(NOT ${__item1} STREQUAL ${__item2})
224 message(FATAL_ERROR "Lists are not equal. Differ at element ${__index}. ${desc}")
229 ################################################################################################
230 # Command for disabling warnings for different platforms (see below for gcc and VisualStudio)
232 # caffe_warnings_disable(<CMAKE_[C|CXX]_FLAGS[_CONFIGURATION]> -Wshadow /wd4996 ..,)
233 macro(caffe_warnings_disable)
235 set(_msvc_warnings "")
236 set(_gxx_warnings "")
239 if(arg MATCHES "^CMAKE_")
240 list(APPEND _flag_vars ${arg})
241 elseif(arg MATCHES "^/wd")
242 list(APPEND _msvc_warnings ${arg})
243 elseif(arg MATCHES "^-W")
244 list(APPEND _gxx_warnings ${arg})
249 set(_flag_vars CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
252 if(MSVC AND _msvc_warnings)
253 foreach(var ${_flag_vars})
254 foreach(warning ${_msvc_warnings})
255 set(${var} "${${var}} ${warning}")
258 elseif((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) AND _gxx_warnings)
259 foreach(var ${_flag_vars})
260 foreach(warning ${_gxx_warnings})
261 if(NOT warning MATCHES "^-Wno-")
262 string(REPLACE "${warning}" "" ${var} "${${var}}")
263 string(REPLACE "-W" "-Wno-" warning "${warning}")
265 set(${var} "${${var}} ${warning}")
269 caffe_clear_vars(_flag_vars _msvc_warnings _gxx_warnings)
272 ################################################################################################
273 # Helper function get current definitions
275 # caffe_get_current_definitions(<definitions_variable>)
276 function(caffe_get_current_definitions definitions_var)
277 get_property(current_definitions DIRECTORY PROPERTY COMPILE_DEFINITIONS)
280 foreach(d ${current_definitions})
281 list(APPEND result -D${d})
284 caffe_list_unique(result)
285 set(${definitions_var} ${result} PARENT_SCOPE)
288 ################################################################################################
289 # Helper function get current includes/definitions
291 # caffe_get_current_cflags(<cflagslist_variable>)
292 function(caffe_get_current_cflags cflags_var)
293 get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
294 caffe_convert_absolute_paths(current_includes)
295 caffe_get_current_definitions(cflags)
297 foreach(i ${current_includes})
298 list(APPEND cflags "-I${i}")
301 caffe_list_unique(cflags)
302 set(${cflags_var} ${cflags} PARENT_SCOPE)
305 ################################################################################################
306 # Helper function to parse current linker libs into link directories, libflags and osx frameworks
308 # caffe_parse_linker_libs(<Caffe_LINKER_LIBS_var> <directories_var> <libflags_var> <frameworks_var>)
309 function(caffe_parse_linker_libs Caffe_LINKER_LIBS_variable folders_var flags_var frameworks_var)
315 set(__varname "__unspec")
317 # split libs into debug, optimized, unspecified and frameworks
318 foreach(list_elem ${${Caffe_LINKER_LIBS_variable}})
319 if(list_elem STREQUAL "debug")
320 set(__varname "__debug")
321 elseif(list_elem STREQUAL "optimized")
322 set(__varname "__optimized")
323 elseif(list_elem MATCHES "^-framework[ \t]+([^ \t].*)")
324 list(APPEND __framework -framework ${CMAKE_MATCH_1})
326 list(APPEND ${__varname} ${list_elem})
327 set(__varname "__unspec")
331 # attach debug or optimized libs to unspecified according to current configuration
332 if(CMAKE_BUILD_TYPE MATCHES "Debug")
333 set(__libs ${__unspec} ${__debug})
335 set(__libs ${__unspec} ${__optimized})
341 # convert linker libraries list to link flags
342 foreach(lib ${__libs})
344 list(APPEND folders $<TARGET_LINKER_FILE_DIR:${lib}>)
345 list(APPEND libflags -l${lib})
346 elseif(lib MATCHES "^-l.*")
347 list(APPEND libflags ${lib})
348 elseif(IS_ABSOLUTE ${lib})
349 get_filename_component(folder ${lib} PATH)
350 get_filename_component(filename ${lib} NAME)
351 string(REGEX REPLACE "\\.[^.]*$" "" filename_without_shortest_ext ${filename})
353 string(REGEX MATCH "^lib(.*)" __match ${filename_without_shortest_ext})
354 list(APPEND libflags -l${CMAKE_MATCH_1})
355 list(APPEND folders ${folder})
357 message(FATAL_ERROR "Logic error. Need to update cmake script")
361 caffe_list_unique(libflags folders)
363 set(${folders_var} ${folders} PARENT_SCOPE)
364 set(${flags_var} ${libflags} PARENT_SCOPE)
365 set(${frameworks_var} ${__framework} PARENT_SCOPE)
368 ################################################################################################
369 # Helper function to detect Darwin version, i.e. 10.8, 10.9, 10.10, ....
371 # caffe_detect_darwin_version(<version_variable>)
372 function(caffe_detect_darwin_version output_var)
374 execute_process(COMMAND /usr/bin/sw_vers -productVersion
375 RESULT_VARIABLE __sw_vers OUTPUT_VARIABLE __sw_vers_out
376 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
378 set(${output_var} ${__sw_vers_out} PARENT_SCOPE)
380 set(${output_var} "" PARENT_SCOPE)