summaryrefslogtreecommitdiffstats
path: root/project/cmake/scripts/common/macros.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'project/cmake/scripts/common/macros.cmake')
-rw-r--r--project/cmake/scripts/common/macros.cmake373
1 files changed, 373 insertions, 0 deletions
diff --git a/project/cmake/scripts/common/macros.cmake b/project/cmake/scripts/common/macros.cmake
new file mode 100644
index 0000000..dd2233b
--- /dev/null
+++ b/project/cmake/scripts/common/macros.cmake
@@ -0,0 +1,373 @@
1# This script holds the main functions used to construct the build system
2
3# include system specific macros
4include(${CORE_SOURCE_DIR}/project/cmake/scripts/${CORE_SYSTEM_NAME}/macros.cmake)
5
6# Add a library, optionally as a dependency of the main application
7# Arguments:
8# name name of the library to add
9# Optional Arguments:
10# NO_MAIN_DEPENDS if specified, the library is not added to main depends
11# Implicit arguments:
12# SOURCES the sources of the library
13# HEADERS the headers of the library (only for IDE support)
14# OTHERS other library related files (only for IDE support)
15# On return:
16# Library will be built, optionally added to ${core_DEPENDS}
17function(core_add_library name)
18 cmake_parse_arguments(arg "NO_MAIN_DEPENDS" "" "" ${ARGN})
19 add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
20 set_target_properties(${name} PROPERTIES PREFIX "")
21 if(NOT arg_NO_MAIN_DEPENDS)
22 set(core_DEPENDS ${name} ${core_DEPENDS} CACHE STRING "" FORCE)
23 endif()
24
25 # Add precompiled headers to Kodi main libraries
26 if(WIN32 AND "${CMAKE_CURRENT_LIST_DIR}" MATCHES "^${CORE_SOURCE_DIR}/xbmc")
27 add_precompiled_header(${name} pch.h ${CORE_SOURCE_DIR}/xbmc/win32/pch.cpp
28 PCH_TARGET kodi)
29 endif()
30
31 # IDE support
32 if(CMAKE_GENERATOR MATCHES "Xcode")
33 file(RELATIVE_PATH parentfolder ${CORE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..)
34 set_target_properties(${name} PROPERTIES FOLDER "${parentfolder}")
35 elseif(CMAKE_GENERATOR MATCHES "Visual Studio")
36 file(RELATIVE_PATH foldername ${CORE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
37 set_target_properties(${name} PROPERTIES FOLDER "${foldername}")
38 source_group(" " REGULAR_EXPRESSION ".*")
39 endif()
40endfunction()
41
42# Add a test library, and add sources to list for gtest integration macros
43function(core_add_test_library name)
44 core_add_library(${name} NO_MAIN_DEPENDS)
45 set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL 1)
46 foreach(src ${SOURCES})
47 set(test_sources ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${test_sources} CACHE STRING "" FORCE)
48 endforeach()
49 set(test_archives ${test_archives} ${name} CACHE STRING "" FORCE)
50endfunction()
51
52# Add a data file to installation list with a mirror in build tree
53# Arguments:
54# file full path to file to mirror
55# relative the relative base of file path in the build/install tree
56# give another parameter to exclude from install target
57# Implicit arguments:
58# CORE_SOURCE_DIR - root of source tree
59# On return:
60# file is added to ${install_data} and mirrored in build tree
61function(copy_file_to_buildtree file relative)
62 if(NOT WIN32)
63 string(REPLACE "\(" "\\(" file ${file})
64 string(REPLACE "\)" "\\)" file ${file})
65 endif()
66 string(REPLACE "${relative}/" "" outfile ${file})
67
68 if(NOT TARGET export-files)
69 add_custom_target(export-files ALL COMMENT "Copying files into build tree")
70 endif()
71 if(NOT ${CORE_SOURCE_DIR} MATCHES ${CMAKE_BINARY_DIR})
72 if(VERBOSE)
73 message(STATUS "copy_file_to_buildtree - copying file: ${file} -> ${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
74 endif()
75 add_custom_command(TARGET export-files COMMAND ${CMAKE_COMMAND} -E copy_if_different "${file}" "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
76 endif()
77 if(NOT ARGN)
78 list(APPEND install_data ${outfile})
79 set(install_data ${install_data} PARENT_SCOPE)
80 endif()
81endfunction()
82
83# add data files to installation list with a mirror in build tree.
84# reads list of files to install from a given list of text files.
85# Arguments:
86# pattern globbing pattern for text files to read
87# give another parameter to exclude from installation target
88# Implicit arguments:
89# CORE_SOURCE_DIR - root of source tree
90# On return:
91# files are added to ${install_data} and mirrored in build tree
92function(copy_files_from_filelist_to_buildtree pattern)
93 foreach(arg ${ARGN})
94 list(APPEND pattern ${arg})
95 endforeach()
96 # copies files listed in text files to the buildtree
97 # Input: [glob pattern: filepattern]
98 list(SORT pattern)
99 if(VERBOSE)
100 message(STATUS "copy_files_from_filelist_to_buildtree - got pattern: ${pattern}")
101 endif()
102 foreach(pat ${pattern})
103 file(GLOB filenames ${pat})
104 foreach(filename ${filenames})
105 string(STRIP ${filename} filename)
106 core_file_read_filtered(fstrings ${filename})
107 foreach(dir ${fstrings})
108 file(GLOB_RECURSE files RELATIVE ${CORE_SOURCE_DIR} ${CORE_SOURCE_DIR}/${dir})
109 foreach(file ${files})
110 if(ARGN)
111 copy_file_to_buildtree(${CORE_SOURCE_DIR}/${file} ${CORE_SOURCE_DIR} 1)
112 else()
113 copy_file_to_buildtree(${CORE_SOURCE_DIR}/${file} ${CORE_SOURCE_DIR})
114 endif()
115 endforeach()
116 endforeach()
117 endforeach()
118 endforeach()
119 set(install_data ${install_data} PARENT_SCOPE)
120endfunction()
121
122# helper macro to set modified variables in parent scope
123macro(export_dep)
124 set(SYSTEM_INCLUDES ${SYSTEM_INCLUDES} PARENT_SCOPE)
125 set(DEPLIBS ${DEPLIBS} PARENT_SCOPE)
126 set(DEP_DEFINES ${DEP_DEFINES} PARENT_SCOPE)
127 set(${depup}_FOUND ${${depup}_FOUND} PARENT_SCOPE)
128 mark_as_advanced(${depup}_LIBRARIES)
129endmacro()
130
131# add a required dependency of main application
132# Arguments:
133# dep name of find rule for dependency, used uppercased for variable prefix
134# On return:
135# dependency added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
136function(core_require_dep dep)
137 find_package(${dep} REQUIRED)
138 string(TOUPPER ${dep} depup)
139 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
140 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
141 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
142 export_dep()
143endfunction()
144
145# add a required dyloaded dependency of main application
146# Arguments:
147# dep name of find rule for dependency, used uppercased for variable prefix
148# On return:
149# dependency added to ${SYSTEM_INCLUDES}, ${dep}_SONAME is set up
150function(core_require_dyload_dep dep)
151 find_package(${dep} REQUIRED)
152 string(TOUPPER ${dep} depup)
153 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
154 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
155 find_soname(${depup} REQUIRED)
156 export_dep()
157 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
158endfunction()
159
160# helper macro for optional deps
161macro(setup_enable_switch)
162 string(TOUPPER ${dep} depup)
163 if (ARGV1)
164 set(enable_switch ${ARGV1})
165 else()
166 set(enable_switch ENABLE_${depup})
167 endif()
168endmacro()
169
170# add an optional dependency of main application
171# Arguments:
172# dep name of find rule for dependency, used uppercased for variable prefix
173# On return:
174# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
175function(core_optional_dep dep)
176 setup_enable_switch()
177 if(${enable_switch})
178 find_package(${dep})
179 if(${depup}_FOUND)
180 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
181 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
182 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
183 set(final_message ${final_message} "${depup} enabled: Yes" PARENT_SCOPE)
184 export_dep()
185 else()
186 set(final_message ${final_message} "${depup} enabled: No" PARENT_SCOPE)
187 endif()
188 endif()
189endfunction()
190
191# add an optional dyloaded dependency of main application
192# Arguments:
193# dep name of find rule for dependency, used uppercased for variable prefix
194# On return:
195# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEP_DEFINES}, ${dep}_SONAME is set up
196function(core_optional_dyload_dep dep)
197 setup_enable_switch()
198 if(${enable_switch})
199 find_package(${dep})
200 if(${depup}_FOUND)
201 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
202 find_soname(${depup} REQUIRED)
203 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
204 set(final_message ${final_message} "${depup} enabled: Yes" PARENT_SCOPE)
205 export_dep()
206 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
207 endif()
208 endif()
209endfunction()
210
211function(core_file_read_filtered result filepattern)
212 # Reads STRINGS from text files
213 # with comments filtered out
214 # Result: [list: result]
215 # Input: [glob pattern: filepattern]
216 file(GLOB filenames ${filepattern})
217 list(SORT filenames)
218 foreach(filename ${filenames})
219 if(VERBOSE)
220 message(STATUS "core_file_read_filtered - filename: ${filename}")
221 endif()
222 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
223 foreach(fstring ${fstrings})
224 string(REGEX REPLACE "^(.*)#(.*)" "\\1" fstring ${fstring})
225 string(REGEX REPLACE "//.*" "" fstring ${fstring})
226 string(STRIP ${fstring} fstring)
227 list(APPEND filename_strings ${fstring})
228 endforeach()
229 endforeach()
230 set(${result} ${filename_strings} PARENT_SCOPE)
231endfunction()
232
233function(core_add_subdirs_from_filelist files)
234 # Adds subdirectories from a sorted list of files
235 # Input: [list: filenames] [bool: sort]
236 foreach(arg ${ARGN})
237 list(APPEND files ${arg})
238 endforeach()
239 list(SORT files)
240 if(VERBOSE)
241 message(STATUS "core_add_subdirs_from_filelist - got pattern: ${files}")
242 endif()
243 foreach(filename ${files})
244 string(STRIP ${filename} filename)
245 core_file_read_filtered(fstrings ${filename})
246 foreach(subdir ${fstrings})
247 STRING_SPLIT(subdir " " ${subdir})
248 list(GET subdir 0 subdir_src)
249 list(GET subdir -1 subdir_dest)
250 if(VERBOSE)
251 message(STATUS " core_add_subdirs_from_filelist - adding subdir: ${CORE_SOURCE_DIR}${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
252 endif()
253 add_subdirectory(${CORE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
254 endforeach()
255 endforeach()
256endfunction()
257
258macro(core_add_optional_subdirs_from_filelist pattern)
259 # Adds subdirectories from text files
260 # if the option(s) in the 3rd field are enabled
261 # Input: [glob pattern: filepattern]
262 foreach(arg ${ARGN})
263 list(APPEND pattern ${arg})
264 endforeach()
265 foreach(elem ${pattern})
266 string(STRIP ${elem} elem)
267 list(APPEND filepattern ${elem})
268 endforeach()
269
270 file(GLOB filenames ${filepattern})
271 list(SORT filenames)
272 if(VERBOSE)
273 message(STATUS "core_add_optional_subdirs_from_filelist - got pattern: ${filenames}")
274 endif()
275
276 foreach(filename ${filenames})
277 if(VERBOSE)
278 message(STATUS "core_add_optional_subdirs_from_filelist - reading file: ${filename}")
279 endif()
280 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
281 foreach(line ${fstrings})
282 string(REPLACE " " ";" line "${line}")
283 list(GET line 0 subdir_src)
284 list(GET line 1 subdir_dest)
285 list(GET line 3 opts)
286 foreach(opt ${opts})
287 if(ENABLE_${opt})
288 if(VERBOSE)
289 message(STATUS " core_add_optional_subdirs_from_filelist - adding subdir: ${CORE_SOURCE_DIR}${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
290 endif()
291 add_subdirectory(${CORE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
292 else()
293 if(VERBOSE)
294 message(STATUS " core_add_optional_subdirs_from_filelist: OPTION ${opt} not enabled for ${subdir_src}, skipping subdir")
295 endif()
296 endif()
297 endforeach()
298 endforeach()
299 endforeach()
300endmacro()
301
302macro(today RESULT)
303 if (WIN32)
304 execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT})
305 string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
306 elseif(UNIX)
307 execute_process(COMMAND date -u +%F
308 OUTPUT_VARIABLE ${RESULT})
309 string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
310 else()
311 message(SEND_ERROR "date not implemented")
312 set(${RESULT} 000000)
313 endif()
314 string(REGEX REPLACE "(\r?\n)+$" "" ${RESULT} "${${RESULT}}")
315endmacro()
316
317function(core_find_git_rev)
318 if(EXISTS ${CORE_SOURCE_DIR}/VERSION)
319 file(STRINGS ${CORE_SOURCE_DIR}/VERSION VERSION_FILE)
320 string(SUBSTRING "${VERSION_FILE}" 1 16 GIT_REV)
321 else()
322 find_package(Git)
323 if(GIT_FOUND AND EXISTS ${CORE_SOURCE_DIR}/.git)
324 execute_process(COMMAND ${GIT_EXECUTABLE} diff-files --ignore-submodules --quiet --
325 RESULT_VARIABLE status_code
326 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
327 if (NOT status_code)
328 execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --cached --ignore-submodules --quiet HEAD --
329 RESULT_VARIABLE status_code
330 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
331 endif()
332 today(DATE)
333 execute_process(COMMAND ${GIT_EXECUTABLE} --no-pager log --abbrev=7 -n 1
334 --pretty=format:"%h-dirty" HEAD
335 OUTPUT_VARIABLE LOG_UNFORMATTED
336 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
337 string(SUBSTRING ${LOG_UNFORMATTED} 1 7 HASH)
338 else()
339 execute_process(COMMAND ${GIT_EXECUTABLE} --no-pager log --abbrev=7 -n 1
340 --pretty=format:"%h %cd" HEAD
341 OUTPUT_VARIABLE LOG_UNFORMATTED
342 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
343 string(SUBSTRING ${LOG_UNFORMATTED} 1 7 HASH)
344 string(SUBSTRING ${LOG_UNFORMATTED} 9 10 DATE)
345 string(REPLACE "-" "" DATE ${DATE})
346 endif()
347 set(GIT_REV "${DATE}-${HASH}")
348 endif()
349 if(GIT_REV)
350 set(APP_SCMID ${GIT_REV} PARENT_SCOPE)
351 endif()
352endfunction()
353
354macro(core_find_versions)
355 include(CMakeParseArguments)
356 core_file_read_filtered(version_list ${CORE_SOURCE_DIR}/version.txt)
357 string(REPLACE " " ";" version_list "${version_list}")
358 cmake_parse_arguments(APP "" "VERSION_MAJOR;VERSION_MINOR;VERSION_TAG;VERSION_CODE;ADDON_API;APP_NAME;COMPANY_NAME" "" ${version_list})
359
360 set(APP_NAME ${APP_APP_NAME}) # inconsistency in upstream
361 string(TOLOWER ${APP_APP_NAME} APP_NAME_LC)
362 set(COMPANY_NAME ${APP_COMPANY_NAME})
363 set(APP_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR})
364 if(APP_VERSION_TAG)
365 set(APP_VERSION ${APP_VERSION}-${APP_VERSION_TAG})
366 endif()
367 string(REPLACE "." "," FILE_VERSION ${APP_ADDON_API}.0)
368 string(TOLOWER ${APP_VERSION_TAG} APP_VERSION_TAG_LC)
369 file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h guilib_version REGEX "^.*GUILIB_API_VERSION (.*)$")
370 string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version ${guilib_version})
371 file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h guilib_version_min REGEX "^.*GUILIB_MIN_API_VERSION (.*)$")
372 string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version_min ${guilib_version_min})
373endmacro()