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