summaryrefslogtreecommitdiffstats
path: root/cmake/scripts/common/Macros.cmake
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2017-06-04 16:57:49 +0200
committermanuel <manuel@mausz.at>2017-06-04 16:57:49 +0200
commitf44ecaa4f27e7538ddcad66d40e543bffa2d2d86 (patch)
treed8de60fc7e17edeb6f0921726c038ee54b281445 /cmake/scripts/common/Macros.cmake
parentae08c8b7221bc965ac40d70e53fc8fcddb050c46 (diff)
downloadkodi-pvr-build-f44ecaa4f27e7538ddcad66d40e543bffa2d2d86.tar.gz
kodi-pvr-build-f44ecaa4f27e7538ddcad66d40e543bffa2d2d86.tar.bz2
kodi-pvr-build-f44ecaa4f27e7538ddcad66d40e543bffa2d2d86.zip
sync with upstream
Diffstat (limited to 'cmake/scripts/common/Macros.cmake')
-rw-r--r--cmake/scripts/common/Macros.cmake722
1 files changed, 722 insertions, 0 deletions
diff --git a/cmake/scripts/common/Macros.cmake b/cmake/scripts/common/Macros.cmake
new file mode 100644
index 0000000..4b6f890
--- /dev/null
+++ b/cmake/scripts/common/Macros.cmake
@@ -0,0 +1,722 @@
1# This script holds the main functions used to construct the build system
2
3# Include system specific macros but only if this file is included from
4# kodi main project. It's not needed for kodi-addons project
5# If CORE_SOURCE_DIR is set, it was called from kodi-addons project
6# TODO: drop check if we ever integrate kodi-addons into kodi project
7if(NOT CORE_SOURCE_DIR)
8 include(${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/Macros.cmake)
9endif()
10
11# IDEs: Group source files in target in folders (file system hierarchy)
12# Source: http://blog.audio-tk.com/2015/09/01/sorting-source-files-and-projects-in-folders-with-cmake-and-visual-studioxcode/
13# Arguments:
14# target The target that shall be grouped by folders.
15# Optional Arguments:
16# RELATIVE allows to specify a different reference folder.
17function(source_group_by_folder target)
18 if(NOT TARGET ${target})
19 message(FATAL_ERROR "There is no target named '${target}'")
20 endif()
21
22 set(SOURCE_GROUP_DELIMITER "/")
23
24 cmake_parse_arguments(arg "" "RELATIVE" "" ${ARGN})
25 if(arg_RELATIVE)
26 set(relative_dir ${arg_RELATIVE})
27 else()
28 set(relative_dir ${CMAKE_CURRENT_SOURCE_DIR})
29 endif()
30
31 get_property(files TARGET ${target} PROPERTY SOURCES)
32 if(files)
33 list(SORT files)
34
35 if(CMAKE_GENERATOR STREQUAL Xcode)
36 set_target_properties(${target} PROPERTIES SOURCES "${files}")
37 endif()
38 endif()
39 foreach(file ${files})
40 if(NOT IS_ABSOLUTE ${file})
41 set(file ${CMAKE_CURRENT_SOURCE_DIR}/${file})
42 endif()
43 file(RELATIVE_PATH relative_file ${relative_dir} ${file})
44 get_filename_component(dir "${relative_file}" DIRECTORY)
45 if(NOT dir STREQUAL "${last_dir}")
46 if(files)
47 source_group("${last_dir}" FILES ${files})
48 endif()
49 set(files "")
50 endif()
51 set(files ${files} ${file})
52 set(last_dir "${dir}")
53 endforeach(file)
54 if(files)
55 source_group("${last_dir}" FILES ${files})
56 endif()
57endfunction()
58
59# Add sources to main application
60# Arguments:
61# name name of the library to add
62# Implicit arguments:
63# ENABLE_STATIC_LIBS Build static libraries per directory
64# SOURCES the sources of the library
65# HEADERS the headers of the library (only for IDE support)
66# OTHERS other library related files (only for IDE support)
67# On return:
68# Library will be built, optionally added to ${core_DEPENDS}
69# Sets CORE_LIBRARY for calls for setting target specific options
70function(core_add_library name)
71 if(ENABLE_STATIC_LIBS)
72 add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
73 set_target_properties(${name} PROPERTIES PREFIX "")
74 set(core_DEPENDS ${name} ${core_DEPENDS} CACHE STRING "" FORCE)
75 add_dependencies(${name} libcpluff ffmpeg dvdnav crossguid)
76 set(CORE_LIBRARY ${name} PARENT_SCOPE)
77
78 # Add precompiled headers to Kodi main libraries
79 if(CORE_SYSTEM_NAME STREQUAL windows)
80 add_precompiled_header(${name} pch.h ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/pch.cpp PCH_TARGET kodi)
81 set_language_cxx(${name})
82 target_link_libraries(${name} PUBLIC effects11)
83 endif()
84 else()
85 foreach(src IN LISTS SOURCES HEADERS OTHERS)
86 get_filename_component(src_path "${src}" ABSOLUTE)
87 list(APPEND FILES ${src_path})
88 endforeach()
89 target_sources(lib${APP_NAME_LC} PRIVATE ${FILES})
90 set(CORE_LIBRARY lib${APP_NAME_LC} PARENT_SCOPE)
91 endif()
92endfunction()
93
94# Add a test library, and add sources to list for gtest integration macros
95function(core_add_test_library name)
96 if(ENABLE_STATIC_LIBS)
97 add_library(${name} STATIC ${SOURCES} ${SUPPORTED_SOURCES} ${HEADERS} ${OTHERS})
98 set_target_properties(${name} PROPERTIES PREFIX ""
99 EXCLUDE_FROM_ALL 1
100 FOLDER "Build Utilities/tests")
101 add_dependencies(${name} libcpluff ffmpeg dvdnav crossguid)
102 set(test_archives ${test_archives} ${name} CACHE STRING "" FORCE)
103 endif()
104 foreach(src IN LISTS SOURCES SUPPORTED_SOURCES HEADERS OTHERS)
105 get_filename_component(src_path "${src}" ABSOLUTE)
106 set(test_sources "${src_path}" ${test_sources} CACHE STRING "" FORCE)
107 endforeach()
108endfunction()
109
110# Add an addon callback library
111# Arguments:
112# name name of the library to add
113# Implicit arguments:
114# SOURCES the sources of the library
115# HEADERS the headers of the library (only for IDE support)
116# OTHERS other library related files (only for IDE support)
117# On return:
118# Library target is defined and added to LIBRARY_FILES
119function(core_add_addon_library name)
120 get_filename_component(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} NAME)
121 list(APPEND SOURCES lib${name}.cpp)
122 core_add_shared_library(${name} OUTPUT_DIRECTORY addons/${DIRECTORY})
123 set_target_properties(${name} PROPERTIES FOLDER addons)
124 target_include_directories(${name} PRIVATE
125 ${CMAKE_CURRENT_SOURCE_DIR}
126 ${CMAKE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi
127 ${CMAKE_SOURCE_DIR}/xbmc)
128endfunction()
129
130# Add an dl-loaded shared library
131# Arguments:
132# name name of the library to add
133# Optional arguments:
134# WRAPPED wrap this library on POSIX platforms to add VFS support for
135# libraries that would otherwise not support it.
136# OUTPUT_DIRECTORY where to create the library in the build dir
137# (default: system)
138# Implicit arguments:
139# SOURCES the sources of the library
140# HEADERS the headers of the library (only for IDE support)
141# OTHERS other library related files (only for IDE support)
142# On return:
143# Library target is defined and added to LIBRARY_FILES
144function(core_add_shared_library name)
145 cmake_parse_arguments(arg "WRAPPED" "OUTPUT_DIRECTORY" "" ${ARGN})
146 if(arg_OUTPUT_DIRECTORY)
147 set(OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY})
148 else()
149 if(NOT CORE_SYSTEM_NAME STREQUAL windows)
150 set(OUTPUT_DIRECTORY system)
151 endif()
152 endif()
153 if(CORE_SYSTEM_NAME STREQUAL windows)
154 set(OUTPUT_NAME lib${name})
155 else()
156 set(OUTPUT_NAME lib${name}-${ARCH})
157 endif()
158
159 if(NOT arg_WRAPPED OR CORE_SYSTEM_NAME STREQUAL windows)
160 add_library(${name} SHARED ${SOURCES} ${HEADERS} ${OTHERS})
161 set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
162 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
163 OUTPUT_NAME ${OUTPUT_NAME} PREFIX "")
164 foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
165 string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
166 set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
167 RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY})
168 endforeach()
169
170 set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}/${OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX} CACHE STRING "" FORCE)
171 add_dependencies(${APP_NAME_LC}-libraries ${name})
172 else()
173 add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
174 set_target_properties(${name} PROPERTIES POSITION_INDEPENDENT_CODE 1)
175 core_link_library(${name} ${OUTPUT_DIRECTORY}/lib${name})
176 endif()
177endfunction()
178
179# Sets the compile language for all C source files in a target to CXX.
180# Needs to be called from the CMakeLists.txt that defines the target.
181# Arguments:
182# target target
183function(set_language_cxx target)
184 get_property(sources TARGET ${target} PROPERTY SOURCES)
185 foreach(file IN LISTS sources)
186 if(file MATCHES "\.c$")
187 set_source_files_properties(${file} PROPERTIES LANGUAGE CXX)
188 endif()
189 endforeach()
190endfunction()
191
192# Add a data file to installation list with a mirror in build tree
193# Mirroring files in the buildtree allows to execute the app from there.
194# Arguments:
195# file full path to file to mirror
196# Optional Arguments:
197# NO_INSTALL: exclude file from installation target (only mirror)
198# DIRECTORY: directory where the file should be mirrored to
199# (default: preserve tree structure relative to CMAKE_SOURCE_DIR)
200# KEEP_DIR_STRUCTURE: preserve tree structure even when DIRECTORY is set
201# On return:
202# Files is mirrored to the build tree and added to ${install_data}
203# (if NO_INSTALL is not given).
204function(copy_file_to_buildtree file)
205 cmake_parse_arguments(arg "NO_INSTALL" "DIRECTORY;KEEP_DIR_STRUCTURE" "" ${ARGN})
206 if(arg_DIRECTORY)
207 set(outdir ${arg_DIRECTORY})
208 if(arg_KEEP_DIR_STRUCTURE)
209 get_filename_component(srcdir ${arg_KEEP_DIR_STRUCTURE} DIRECTORY)
210 string(REPLACE "${CMAKE_SOURCE_DIR}/${srcdir}/" "" outfile ${file})
211 if(NOT IS_DIRECTORY ${file})
212 set(outdir ${outdir}/${outfile})
213 endif()
214 else()
215 get_filename_component(outfile ${file} NAME)
216 set(outfile ${outdir}/${outfile})
217 endif()
218 else()
219 string(REPLACE "${CMAKE_SOURCE_DIR}/" "" outfile ${file})
220 get_filename_component(outdir ${outfile} DIRECTORY)
221 endif()
222
223 if(NOT TARGET export-files)
224 file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
225 add_custom_target(export-files ALL COMMENT "Copying files into build tree"
226 COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
227 set_target_properties(export-files PROPERTIES FOLDER "Build Utilities")
228 file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake "# Export files to build tree\n")
229 endif()
230
231 # Exclude autotools build artefacts and other blacklisted files in source tree.
232 if(file MATCHES "(Makefile|\.in|\.xbt|\.so|\.dylib|\.gitignore)$")
233 if(VERBOSE)
234 message(STATUS "copy_file_to_buildtree - ignoring file: ${file}")
235 endif()
236 return()
237 endif()
238
239 if(NOT file STREQUAL ${CMAKE_BINARY_DIR}/${outfile})
240 if(VERBOSE)
241 message(STATUS "copy_file_to_buildtree - copying file: ${file} -> ${CMAKE_BINARY_DIR}/${outfile}")
242 endif()
243 file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake
244 "file(COPY \"${file}\" DESTINATION \"${CMAKE_BINARY_DIR}/${outdir}\")\n")
245 endif()
246
247 if(NOT arg_NO_INSTALL)
248 list(APPEND install_data ${outfile})
249 set(install_data ${install_data} PARENT_SCOPE)
250 endif()
251endfunction()
252
253# Add data files to installation list with a mirror in build tree.
254# reads list of files to install from a given list of text files.
255# Arguments:
256# pattern globbing pattern for text files to read
257# Optional Arguments:
258# NO_INSTALL: exclude files from installation target
259# Implicit arguments:
260# CMAKE_SOURCE_DIR - root of source tree
261# On return:
262# Files are mirrored to the build tree and added to ${install_data}
263# (if NO_INSTALL is not given).
264function(copy_files_from_filelist_to_buildtree pattern)
265 # copies files listed in text files to the buildtree
266 # Input: [glob pattern: filepattern]
267 cmake_parse_arguments(arg "NO_INSTALL" "" "" ${ARGN})
268 list(APPEND pattern ${ARGN})
269 list(SORT pattern)
270 if(VERBOSE)
271 message(STATUS "copy_files_from_filelist_to_buildtree - got pattern: ${pattern}")
272 endif()
273 foreach(pat ${pattern})
274 file(GLOB filenames ${pat})
275 foreach(filename ${filenames})
276 string(STRIP ${filename} filename)
277 core_file_read_filtered(fstrings ${filename})
278 foreach(dir ${fstrings})
279 string(CONFIGURE ${dir} dir)
280 string(REPLACE " " ";" dir ${dir})
281 list(GET dir 0 src)
282 list(LENGTH dir len)
283 if(len EQUAL 1)
284 set(dest)
285 elseif(len EQUAL 3)
286 list(GET dir 1 opt)
287 if(opt STREQUAL "KEEP_DIR_STRUCTURE")
288 set(DIR_OPTION ${opt} ${src})
289 if(VERBOSE)
290 message(STATUS "copy_files_from_filelist_to_buildtree - DIR_OPTION: ${DIR_OPTION}")
291 endif()
292 endif()
293 list(GET dir -1 dest)
294 else()
295 list(GET dir -1 dest)
296 endif()
297
298 # If the full path to an existing file is specified then add that single file.
299 # Don't recursively add all files with the given name.
300 if(EXISTS ${CMAKE_SOURCE_DIR}/${src} AND (NOT IS_DIRECTORY ${CMAKE_SOURCE_DIR}/${src} OR DIR_OPTION))
301 set(files ${src})
302 else()
303 file(GLOB_RECURSE files RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/${src})
304 endif()
305
306 foreach(file ${files})
307 if(arg_NO_INSTALL)
308 copy_file_to_buildtree(${CMAKE_SOURCE_DIR}/${file} DIRECTORY ${dest} NO_INSTALL ${DIR_OPTION})
309 else()
310 copy_file_to_buildtree(${CMAKE_SOURCE_DIR}/${file} DIRECTORY ${dest} ${DIR_OPTION})
311 endif()
312 endforeach()
313 endforeach()
314 endforeach()
315 endforeach()
316 set(install_data ${install_data} PARENT_SCOPE)
317endfunction()
318
319# helper macro to set modified variables in parent scope
320macro(export_dep)
321 set(SYSTEM_INCLUDES ${SYSTEM_INCLUDES} PARENT_SCOPE)
322 set(DEPLIBS ${DEPLIBS} PARENT_SCOPE)
323 set(DEP_DEFINES ${DEP_DEFINES} PARENT_SCOPE)
324 set(${depup}_FOUND ${${depup}_FOUND} PARENT_SCOPE)
325 mark_as_advanced(${depup}_LIBRARIES)
326endmacro()
327
328# add a required dependency of main application
329# Arguments:
330# dep_list name of find rule for dependency, used uppercased for variable prefix
331# also accepts a list of multiple dependencies
332# On return:
333# dependency added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
334function(core_require_dep)
335 foreach(dep ${ARGN})
336 find_package(${dep} REQUIRED)
337 string(TOUPPER ${dep} depup)
338 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
339 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
340 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
341 export_dep()
342 endforeach()
343endfunction()
344
345# add a required dyloaded dependency of main application
346# Arguments:
347# dep_list name of find rule for dependency, used uppercased for variable prefix
348# also accepts a list of multiple dependencies
349# On return:
350# dependency added to ${SYSTEM_INCLUDES}, ${dep}_SONAME is set up
351function(core_require_dyload_dep)
352 foreach(dep ${ARGN})
353 find_package(${dep} REQUIRED)
354 string(TOUPPER ${dep} depup)
355 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
356 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
357 find_soname(${depup} REQUIRED)
358 export_dep()
359 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
360 endforeach()
361endfunction()
362
363# helper macro for optional deps
364macro(setup_enable_switch)
365 string(TOUPPER ${dep} depup)
366 if(${ARGV1})
367 set(enable_switch ${ARGV1})
368 else()
369 set(enable_switch ENABLE_${depup})
370 endif()
371 # normal options are boolean, so we override set our ENABLE_FOO var to allow "auto" handling
372 set(${enable_switch} "AUTO" CACHE STRING "Enable ${depup} support?")
373endmacro()
374
375# add an optional dependency of main application
376# Arguments:
377# dep_list name of find rule for dependency, used uppercased for variable prefix
378# also accepts a list of multiple dependencies
379# On return:
380# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
381function(core_optional_dep)
382 foreach(dep ${ARGN})
383 set(_required False)
384 setup_enable_switch()
385 if(${enable_switch} STREQUAL AUTO)
386 find_package(${dep})
387 elseif(${${enable_switch}})
388 find_package(${dep} REQUIRED)
389 set(_required True)
390 endif()
391
392 if(${depup}_FOUND)
393 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
394 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
395 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
396 set(final_message ${final_message} "${depup} enabled: Yes")
397 export_dep()
398 elseif(_required)
399 message(FATAL_ERROR "${depup} enabled but not found")
400 else()
401 set(final_message ${final_message} "${depup} enabled: No")
402 endif()
403 endforeach()
404 set(final_message ${final_message} PARENT_SCOPE)
405endfunction()
406
407# add an optional dyloaded dependency of main application
408# Arguments:
409# dep_list name of find rule for dependency, used uppercased for variable prefix
410# also accepts a list of multiple dependencies
411# On return:
412# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEP_DEFINES}, ${dep}_SONAME is set up
413function(core_optional_dyload_dep)
414 foreach(dep ${ARGN})
415 set(_required False)
416 setup_enable_switch()
417 if(${enable_switch} STREQUAL AUTO)
418 find_package(${dep})
419 elseif(${${enable_switch}})
420 find_package(${dep} REQUIRED)
421 set(_required True)
422 endif()
423
424 if(${depup}_FOUND)
425 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
426 find_soname(${depup} REQUIRED)
427 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
428 set(final_message ${final_message} "${depup} enabled: Yes" PARENT_SCOPE)
429 export_dep()
430 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
431 elseif(_required)
432 message(FATAL_ERROR "${depup} enabled but not found")
433 else()
434 set(final_message ${final_message} "${depup} enabled: No" PARENT_SCOPE)
435 endif()
436 endforeach()
437endfunction()
438
439function(core_file_read_filtered result filepattern)
440 # Reads STRINGS from text files
441 # with comments filtered out
442 # Result: [list: result]
443 # Input: [glob pattern: filepattern]
444 file(GLOB filenames ${filepattern})
445 list(SORT filenames)
446 foreach(filename ${filenames})
447 if(VERBOSE)
448 message(STATUS "core_file_read_filtered - filename: ${filename}")
449 endif()
450 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename})
451 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
452 foreach(fstring ${fstrings})
453 string(REGEX REPLACE "^(.*)#(.*)" "\\1" fstring ${fstring})
454 string(REGEX REPLACE "[ \n\r\t]//.*" "" fstring ${fstring})
455 string(STRIP ${fstring} fstring)
456 list(APPEND filename_strings ${fstring})
457 endforeach()
458 endforeach()
459 set(${result} ${filename_strings} PARENT_SCOPE)
460endfunction()
461
462function(core_add_subdirs_from_filelist files)
463 # Adds subdirectories from a sorted list of files
464 # Input: [list: filenames] [bool: sort]
465 foreach(arg ${ARGN})
466 list(APPEND files ${arg})
467 endforeach()
468 list(SORT files)
469 if(VERBOSE)
470 message(STATUS "core_add_subdirs_from_filelist - got pattern: ${files}")
471 endif()
472 foreach(filename ${files})
473 string(STRIP ${filename} filename)
474 core_file_read_filtered(fstrings ${filename})
475 foreach(subdir ${fstrings})
476 string(REPLACE " " ";" subdir ${subdir})
477 list(GET subdir 0 subdir_src)
478 list(GET subdir -1 subdir_dest)
479 if(VERBOSE)
480 message(STATUS " core_add_subdirs_from_filelist - adding subdir: ${CMAKE_SOURCE_DIR}/${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
481 endif()
482 add_subdirectory(${CMAKE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
483 endforeach()
484 endforeach()
485endfunction()
486
487macro(core_add_optional_subdirs_from_filelist pattern)
488 # Adds subdirectories from text files
489 # if the option(s) in the 3rd field are enabled
490 # Input: [glob pattern: filepattern]
491 foreach(arg ${ARGN})
492 list(APPEND pattern ${arg})
493 endforeach()
494 foreach(elem ${pattern})
495 string(STRIP ${elem} elem)
496 list(APPEND filepattern ${elem})
497 endforeach()
498
499 file(GLOB filenames ${filepattern})
500 list(SORT filenames)
501 if(VERBOSE)
502 message(STATUS "core_add_optional_subdirs_from_filelist - got pattern: ${filenames}")
503 endif()
504
505 foreach(filename ${filenames})
506 if(VERBOSE)
507 message(STATUS "core_add_optional_subdirs_from_filelist - reading file: ${filename}")
508 endif()
509 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename})
510 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
511 foreach(line ${fstrings})
512 string(REPLACE " " ";" line "${line}")
513 list(GET line 0 subdir_src)
514 list(GET line 1 subdir_dest)
515 list(GET line 3 opts)
516 foreach(opt ${opts})
517 if(ENABLE_${opt})
518 if(VERBOSE)
519 message(STATUS " core_add_optional_subdirs_from_filelist - adding subdir: ${CMAKE_SOURCE_DIR}/${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
520 endif()
521 add_subdirectory(${CMAKE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
522 else()
523 if(VERBOSE)
524 message(STATUS " core_add_optional_subdirs_from_filelist: OPTION ${opt} not enabled for ${subdir_src}, skipping subdir")
525 endif()
526 endif()
527 endforeach()
528 endforeach()
529 endforeach()
530endmacro()
531
532# Generates an RFC2822 timestamp
533#
534# The following variable is set:
535# RFC2822_TIMESTAMP
536function(rfc2822stamp)
537 execute_process(COMMAND date -R
538 OUTPUT_VARIABLE RESULT)
539 set(RFC2822_TIMESTAMP ${RESULT} PARENT_SCOPE)
540endfunction()
541
542# Generates an user stamp from git config info
543#
544# The following variable is set:
545# PACKAGE_MAINTAINER - user stamp in the form of "username <username@example.com>"
546# if no git tree is found, value is set to "nobody <nobody@example.com>"
547function(userstamp)
548 find_package(Git)
549 if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
550 execute_process(COMMAND ${GIT_EXECUTABLE} config user.name
551 OUTPUT_VARIABLE username
552 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
553 OUTPUT_STRIP_TRAILING_WHITESPACE)
554 execute_process(COMMAND ${GIT_EXECUTABLE} config user.email
555 OUTPUT_VARIABLE useremail
556 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
557 OUTPUT_STRIP_TRAILING_WHITESPACE)
558 set(PACKAGE_MAINTAINER "${username} <${useremail}>" PARENT_SCOPE)
559 else()
560 set(PACKAGE_MAINTAINER "nobody <nobody@example.com>" PARENT_SCOPE)
561 endif()
562endfunction()
563
564# Parses git info and sets variables used to identify the build
565# Arguments:
566# stamp variable name to return
567# Optional Arguments:
568# FULL: generate git HEAD commit in the form of 'YYYYMMDD-hash'
569# if git tree is dirty, value is set in the form of 'YYYYMMDD-hash-dirty'
570# if no git tree is found, value is set in the form of 'YYYYMMDD-nogitfound'
571# if FULL is not given, stamp is generated following the same process as above
572# but without 'YYYYMMDD'
573# On return:
574# Variable is set with generated stamp to PARENT_SCOPE
575function(core_find_git_rev stamp)
576 # allow manual setting GIT_VERSION
577 if(GIT_VERSION)
578 set(${stamp} ${GIT_VERSION} PARENT_SCOPE)
579 else()
580 find_package(Git)
581 if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
582 execute_process(COMMAND ${GIT_EXECUTABLE} update-index --ignore-submodules --refresh -q)
583 execute_process(COMMAND ${GIT_EXECUTABLE} diff-files --ignore-submodules --quiet --
584 RESULT_VARIABLE status_code
585 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
586 if(NOT status_code)
587 execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --ignore-submodules --quiet HEAD --
588 RESULT_VARIABLE status_code
589 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
590 endif()
591 if(status_code)
592 execute_process(COMMAND ${GIT_EXECUTABLE} log -n 1 --pretty=format:"%h-dirty" HEAD
593 OUTPUT_VARIABLE HASH
594 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
595 string(SUBSTRING ${HASH} 1 13 HASH)
596 else()
597 execute_process(COMMAND ${GIT_EXECUTABLE} log -n 1 --pretty=format:"%h" HEAD
598 OUTPUT_VARIABLE HASH
599 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
600 string(SUBSTRING ${HASH} 1 7 HASH)
601 endif()
602 execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%cd" --date=short HEAD
603 OUTPUT_VARIABLE DATE
604 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
605 string(SUBSTRING ${DATE} 1 10 DATE)
606 string(REPLACE "-" "" DATE ${DATE})
607 else()
608 string(TIMESTAMP DATE "%Y%m%d" UTC)
609 set(HASH "nogitfound")
610 endif()
611 cmake_parse_arguments(arg "FULL" "" "" ${ARGN})
612 if(arg_FULL)
613 set(${stamp} ${DATE}-${HASH} PARENT_SCOPE)
614 else()
615 set(${stamp} ${HASH} PARENT_SCOPE)
616 endif()
617 endif()
618endfunction()
619
620# Parses version.txt and versions.h and sets variables
621# used to construct dirs structure, file naming, API version, etc.
622#
623# The following variables are set from version.txt:
624# APP_NAME - app name
625# APP_NAME_LC - lowercased app name
626# APP_NAME_UC - uppercased app name
627# APP_PACKAGE - Android full package name
628# COMPANY_NAME - company name
629# APP_VERSION_MAJOR - the app version major
630# APP_VERSION_MINOR - the app version minor
631# APP_VERSION_TAG - the app version tag
632# APP_VERSION_TAG_LC - lowercased app version tag
633# APP_VERSION - the app version (${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}-${APP_VERSION_TAG})
634# APP_ADDON_API - the addon API version in the form of 16.9.702
635# FILE_VERSION - file version in the form of 16,9,702,0 - Windows only
636#
637# Set various variables defined in "versions.h"
638macro(core_find_versions)
639 # kodi-addons project also calls this macro and uses CORE_SOURCE_DIR
640 # to point to core base dir
641 # Set CORE_SOURCE_DIR here, otherwise kodi main project fails
642 # TODO: drop this code block and refactor the rest to use CMAKE_SOURCE_DIR
643 # if we ever integrate kodi-addons into kodi project
644 if(NOT CORE_SOURCE_DIR)
645 set(CORE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
646 endif()
647
648 include(CMakeParseArguments)
649 core_file_read_filtered(version_list ${CORE_SOURCE_DIR}/version.txt)
650 string(REPLACE " " ";" version_list "${version_list}")
651 cmake_parse_arguments(APP "" "APP_NAME;COMPANY_NAME;WEBSITE;VERSION_MAJOR;VERSION_MINOR;VERSION_TAG;VERSION_CODE;ADDON_API;APP_PACKAGE" "" ${version_list})
652
653 set(APP_NAME ${APP_APP_NAME}) # inconsistency but APP_APP_NAME looks weird
654 string(TOLOWER ${APP_APP_NAME} APP_NAME_LC)
655 string(TOUPPER ${APP_APP_NAME} APP_NAME_UC)
656 set(COMPANY_NAME ${APP_COMPANY_NAME})
657 set(APP_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR})
658 set(APP_PACKAGE ${APP_APP_PACKAGE})
659 if(APP_VERSION_TAG)
660 set(APP_VERSION ${APP_VERSION}-${APP_VERSION_TAG})
661 string(TOLOWER ${APP_VERSION_TAG} APP_VERSION_TAG_LC)
662 endif()
663 string(REPLACE "." "," FILE_VERSION ${APP_ADDON_API}.0)
664
665 # Set defines used in addon.xml.in and read from versions.h to set add-on
666 # version parts automatically
667 # This part is nearly identical to "AddonHelpers.cmake", except location of versions.h
668 file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h BIN_ADDON_PARTS)
669 foreach(loop_var ${BIN_ADDON_PARTS})
670 string(FIND "${loop_var}" "#define ADDON_" matchres)
671 if("${matchres}" EQUAL 0)
672 string(REGEX MATCHALL "[A-Z0-9._]+|[A-Z0-9._]+$" loop_var "${loop_var}")
673 list(GET loop_var 0 include_name)
674 list(GET loop_var 1 include_version)
675 string(REGEX REPLACE ".*\"(.*)\"" "\\1" ${include_name} ${include_version})
676 endif()
677 endforeach(loop_var)
678
679 # unset variables not used anywhere else
680 unset(version_list)
681 unset(APP_APP_NAME)
682 unset(BIN_ADDON_PARTS)
683
684 # bail if we can't parse version.txt
685 if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR)
686 message(FATAL_ERROR "Could not determine app version! Make sure that ${CORE_SOURCE_DIR}/version.txt exists")
687 endif()
688endmacro()
689
690# add-on xml's
691# find all folders containing addon.xml.in and used to define
692# ADDON_XML_OUTPUTS, ADDON_XML_DEPENDS and ADDON_INSTALL_DATA
693macro(find_addon_xml_in_files)
694 file(GLOB ADDON_XML_IN_FILE ${CMAKE_SOURCE_DIR}/addons/*/addon.xml.in)
695 foreach(loop_var ${ADDON_XML_IN_FILE})
696 list(GET loop_var 0 xml_name)
697
698 string(REPLACE "/addon.xml.in" "" xml_name ${xml_name})
699 string(REPLACE "${CORE_SOURCE_DIR}/" "" xml_name ${xml_name})
700
701 list(APPEND ADDON_XML_DEPENDS "${CORE_SOURCE_DIR}/${xml_name}/addon.xml.in")
702 list(APPEND ADDON_XML_OUTPUTS "${CMAKE_BINARY_DIR}/${xml_name}/addon.xml")
703
704 # Read content of add-on folder to have on install
705 file(GLOB ADDON_FILES "${CORE_SOURCE_DIR}/${xml_name}/*")
706 foreach(loop_var ${ADDON_FILES})
707 if(loop_var MATCHES "addon.xml.in")
708 string(REPLACE "addon.xml.in" "addon.xml" loop_var ${loop_var})
709 endif()
710
711 list(GET loop_var 0 file_name)
712 string(REPLACE "${CORE_SOURCE_DIR}/" "" file_name ${file_name})
713 list(APPEND ADDON_INSTALL_DATA "${file_name}")
714
715 unset(file_name)
716 endforeach()
717 unset(xml_name)
718 endforeach()
719
720 # Append also versions.h to depends
721 list(APPEND ADDON_XML_DEPENDS "${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h")
722endmacro()