summaryrefslogtreecommitdiffstats
path: root/project/cmake/scripts/common
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2016-11-24 21:27:41 +0100
committermanuel <manuel@mausz.at>2016-11-24 21:27:41 +0100
commit8cdf8dec703d882b46ca50a769fabb95ffc48e2c (patch)
treef7fe8233508f79d3dc94f8f445ce6342e7dfbdbb /project/cmake/scripts/common
parent5823b05feb29a59510c32a9c28ca18b50b9b6399 (diff)
downloadkodi-pvr-build-8cdf8dec703d882b46ca50a769fabb95ffc48e2c.tar.gz
kodi-pvr-build-8cdf8dec703d882b46ca50a769fabb95ffc48e2c.tar.bz2
kodi-pvr-build-8cdf8dec703d882b46ca50a769fabb95ffc48e2c.zip
sync with upstream
Diffstat (limited to 'project/cmake/scripts/common')
-rw-r--r--project/cmake/scripts/common/AddOptions.cmake78
-rw-r--r--project/cmake/scripts/common/AddonHelpers.cmake268
-rw-r--r--project/cmake/scripts/common/ArchSetup.cmake (renamed from project/cmake/scripts/common/archsetup.cmake)53
-rw-r--r--project/cmake/scripts/common/CMakeHelpers.cmake54
-rw-r--r--project/cmake/scripts/common/CheckCommits.cmake (renamed from project/cmake/scripts/common/checkcommits.cmake)0
-rw-r--r--project/cmake/scripts/common/CheckTargetPlatform.cmake (renamed from project/cmake/scripts/common/check_target_platform.cmake)32
-rw-r--r--project/cmake/scripts/common/GenerateVersionedFiles.cmake18
-rw-r--r--project/cmake/scripts/common/GeneratorSetup.cmake (renamed from project/cmake/scripts/common/generatorsetup.cmake)25
-rw-r--r--project/cmake/scripts/common/HandleDepends.cmake (renamed from project/cmake/scripts/common/handle-depends.cmake)30
-rw-r--r--project/cmake/scripts/common/Macros.cmake619
-rw-r--r--project/cmake/scripts/common/PrepareEnv.cmake (renamed from project/cmake/scripts/common/prepare-env.cmake)79
-rw-r--r--project/cmake/scripts/common/ProjectMacros.cmake (renamed from project/cmake/scripts/common/projectmacros.cmake)12
-rw-r--r--project/cmake/scripts/common/Uninstall.cmake22
-rw-r--r--project/cmake/scripts/common/addon-helpers.cmake171
-rw-r--r--project/cmake/scripts/common/addoptions.cmake82
-rw-r--r--project/cmake/scripts/common/generateversionedfiles.cmake11
-rw-r--r--project/cmake/scripts/common/macros.cmake383
-rw-r--r--project/cmake/scripts/common/managestring.cmake235
-rw-r--r--project/cmake/scripts/common/pathsetup.cmake3
19 files changed, 1198 insertions, 977 deletions
diff --git a/project/cmake/scripts/common/AddOptions.cmake b/project/cmake/scripts/common/AddOptions.cmake
new file mode 100644
index 0000000..96837c1
--- /dev/null
+++ b/project/cmake/scripts/common/AddOptions.cmake
@@ -0,0 +1,78 @@
1# - Add options without repeating them on the command line
2#
3# Synopsis:
4#
5# add_options (lang build opts)
6#
7# where:
8#
9# lang Name of the language whose compiler should receive the
10# options, e.g. CXX. If a comma-separated list is received
11# then the option is added for all those languages. Use the
12# special value ALL_LANGUAGES for these languages: CXX, C
13# and Fortran
14#
15# build Kind of build to which this options should apply,
16# such as DEBUG and RELEASE. This can also be a comma-
17# separated list. Use the special value ALL_BUILDS to apply
18# to all builds.
19#
20# opts List of options to add. Each should be quoted.
21#
22# Example:
23#
24# add_options (CXX RELEASE "-O3" "-DNDEBUG" "-Wall")
25
26function(add_options langs builds)
27 # special handling of empty language specification
28 if("${langs}" STREQUAL "ALL_LANGUAGES")
29 set(langs CXX C Fortran)
30 endif()
31 foreach(lang IN LISTS langs)
32 # prepend underscore if necessary
33 foreach(build IN LISTS builds)
34 if(NOT ("${build}" STREQUAL "ALL_BUILDS"))
35 set(_bld "_${build}")
36 string(TOUPPER "${_bld}" _bld)
37 else()
38 set(_bld "")
39 endif()
40 foreach(_opt IN LISTS ARGN)
41 set(_var "CMAKE_${lang}_FLAGS${_bld}")
42 #message(STATUS "Adding \"${_opt}\" to \${${_var}}")
43 # remove it first
44 string(REPLACE "${_opt}" "" _without "${${_var}}")
45 string(STRIP "${_without}" _without)
46 # we need to strip this one as well, so they are comparable
47 string(STRIP "${${_var}}" _stripped)
48 # if it wasn't there, then add it at the end
49 if("${_without}" STREQUAL "${_stripped}")
50 # don't add any extra spaces if no options yet are set
51 if(NOT ${_stripped} STREQUAL "")
52 set(${_var} "${_stripped} ${_opt}")
53 else()
54 set(${_var} "${_opt}")
55 endif()
56 set(${_var} "${${_var}}" PARENT_SCOPE)
57 endif()
58 endforeach()
59 endforeach()
60 endforeach()
61endfunction()
62
63# set varname to flag unless user has specified something that matches regex
64function(set_default_option varname flag regex)
65 if(NOT "$ENV{CXXFLAGS}" MATCHES "${regex}"
66 AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}"
67 AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}")
68 set(${varname} ${flag} PARENT_SCOPE)
69 else()
70 set(${varname} PARENT_SCOPE)
71 endif()
72endfunction()
73
74# note: this must be called before project()
75macro(no_default_options)
76 # prevent the platform probe to set options
77 set(CMAKE_NOT_USING_CONFIG_FLAGS TRUE)
78endmacro()
diff --git a/project/cmake/scripts/common/AddonHelpers.cmake b/project/cmake/scripts/common/AddonHelpers.cmake
new file mode 100644
index 0000000..6680ed1
--- /dev/null
+++ b/project/cmake/scripts/common/AddonHelpers.cmake
@@ -0,0 +1,268 @@
1# Workaround for the fact that cpack's filenames are not customizable.
2# Each add-on is added as a separate component to facilitate zip/tgz packaging.
3# The filenames are always of the form basename-component, which is
4# incompatible with the addonid-version scheme we want. This hack renames
5# the files from the file names generated by the 'package' target.
6# Sadly we cannot extend the 'package' target, as it is a builtin target, see
7# http://public.kitware.com/Bug/view.php?id=8438
8# Thus, we have to add an 'addon-package' target.
9add_custom_target(addon-package
10 COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package)
11
12macro(add_cpack_workaround target version ext)
13 if(NOT PACKAGE_DIR)
14 set(PACKAGE_DIR "${CMAKE_INSTALL_PREFIX}/zips")
15 endif()
16
17 add_custom_command(TARGET addon-package PRE_BUILD
18 COMMAND ${CMAKE_COMMAND} -E make_directory ${PACKAGE_DIR}
19 COMMAND ${CMAKE_COMMAND} -E copy ${CPACK_PACKAGE_DIRECTORY}/addon-${target}-${version}.${ext} ${PACKAGE_DIR}/${target}-${version}.${ext})
20endmacro()
21
22# Grab the version from a given add-on's addon.xml
23macro (addon_version dir prefix)
24 if(EXISTS ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in)
25 file(READ ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in ADDONXML)
26 else()
27 file(READ ${dir}/addon.xml ADDONXML)
28 endif()
29
30 string(REGEX MATCH "<addon[^>]*version.?=.?.[0-9\\.]+" VERSION_STRING ${ADDONXML})
31 string(REGEX REPLACE ".*version=.([0-9\\.]+).*" "\\1" ${prefix}_VERSION ${VERSION_STRING})
32 message(STATUS ${prefix}_VERSION=${${prefix}_VERSION})
33endmacro()
34
35# Build, link and optionally package an add-on
36macro (build_addon target prefix libs)
37 addon_version(${target} ${prefix})
38 if(${prefix}_SOURCES)
39 add_library(${target} ${${prefix}_SOURCES})
40 target_link_libraries(${target} ${${libs}})
41 set_target_properties(${target} PROPERTIES VERSION ${${prefix}_VERSION}
42 SOVERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}
43 PREFIX "")
44 if(OS STREQUAL "android")
45 set_target_properties(${target} PROPERTIES PREFIX "lib")
46 endif()
47 elseif(${prefix}_CUSTOM_BINARY)
48 add_custom_target(${target} ALL)
49 endif()
50
51 # get the library's location
52 if(${prefix}_CUSTOM_BINARY)
53 list(GET ${prefix}_CUSTOM_BINARY 0 LIBRARY_LOCATION)
54 list(GET ${prefix}_CUSTOM_BINARY 1 LIBRARY_FILENAME)
55 else()
56 set(LIBRARY_LOCATION $<TARGET_FILE:${target}>)
57 # get the library's filename
58 if("${CORE_SYSTEM_NAME}" STREQUAL "android")
59 # for android we need the filename without any version numbers
60 set(LIBRARY_FILENAME $<TARGET_LINKER_FILE_NAME:${target}>)
61 else()
62 set(LIBRARY_FILENAME $<TARGET_FILE_NAME:${target}>)
63 endif()
64 endif()
65
66 # if there's an addon.xml.in we need to generate the addon.xml
67 if(EXISTS ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in)
68 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in)
69 set(PLATFORM ${CORE_SYSTEM_NAME})
70
71 file(READ ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in addon_file)
72 string(CONFIGURE "${addon_file}" addon_file_conf @ONLY)
73 file(GENERATE OUTPUT ${PROJECT_SOURCE_DIR}/${target}/addon.xml CONTENT "${addon_file_conf}")
74 if(${APP_NAME_UC}_BUILD_DIR)
75 file(GENERATE OUTPUT ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/addon.xml CONTENT "${addon_file_conf}")
76 endif()
77 endif()
78
79 # if there's an settings.xml.in we need to generate the settings.xml
80 if(EXISTS ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in)
81 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in)
82 set(PLATFORM ${CORE_SYSTEM_NAME})
83
84 file(READ ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in settings_file)
85 string(CONFIGURE "${settings_file}" settings_file_conf @ONLY)
86 file(GENERATE OUTPUT ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml CONTENT "${settings_file_conf}")
87 if(${APP_NAME_UC}_BUILD_DIR)
88 file(GENERATE OUTPUT ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/resources/settings.xml CONTENT "${settings_file_conf}")
89 endif()
90 endif()
91
92 # set zip as default if addon-package is called without PACKAGE_XXX
93 set(CPACK_GENERATOR "ZIP")
94 set(ext "zip")
95 if(PACKAGE_ZIP OR PACKAGE_TGZ)
96 if(PACKAGE_TGZ)
97 set(CPACK_GENERATOR "TGZ")
98 set(ext "tar.gz")
99 endif()
100 set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
101 set(CPACK_PACKAGE_FILE_NAME addon)
102 if(CMAKE_BUILD_TYPE STREQUAL "Release")
103 set(CPACK_STRIP_FILES TRUE)
104 endif()
105 set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
106 set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
107 list(APPEND CPACK_COMPONENTS_ALL ${target}-${${prefix}_VERSION})
108 # Pack files together to create an archive
109 install(DIRECTORY ${target} DESTINATION ./ COMPONENT ${target}-${${prefix}_VERSION} PATTERN "xml.in" EXCLUDE)
110 if(WIN32)
111 if(NOT CPACK_PACKAGE_DIRECTORY)
112 # determine the temporary path
113 file(TO_CMAKE_PATH "$ENV{TEMP}" WIN32_TEMP_PATH)
114 string(LENGTH "${WIN32_TEMP_PATH}" WIN32_TEMP_PATH_LENGTH)
115 string(LENGTH "${PROJECT_BINARY_DIR}" PROJECT_BINARY_DIR_LENGTH)
116
117 # check if the temporary path is shorter than the default packaging directory path
118 if(WIN32_TEMP_PATH_LENGTH GREATER 0 AND WIN32_TEMP_PATH_LENGTH LESS PROJECT_BINARY_DIR_LENGTH)
119 # set the directory used by CPack for packaging to the temp directory
120 set(CPACK_PACKAGE_DIRECTORY ${WIN32_TEMP_PATH})
121 endif()
122 endif()
123
124 # in case of a VC++ project the installation location contains a $(Configuration) VS variable
125 # we replace it with ${CMAKE_BUILD_TYPE} (which doesn't cover the case when the build configuration
126 # is changed within Visual Studio)
127 string(REPLACE "$(Configuration)" "${CMAKE_BUILD_TYPE}" LIBRARY_LOCATION "${LIBRARY_LOCATION}")
128
129 if(${prefix}_SOURCES)
130 # install the generated DLL file
131 install(PROGRAMS ${LIBRARY_LOCATION} DESTINATION ${target}
132 COMPONENT ${target}-${${prefix}_VERSION})
133
134 if(CMAKE_BUILD_TYPE MATCHES Debug)
135 # for debug builds also install the PDB file
136 get_filename_component(LIBRARY_DIR ${LIBRARY_LOCATION} DIRECTORY)
137 install(FILES $<TARGET_PDB_FILE:${target}> DESTINATION ${target}
138 COMPONENT ${target}-${${prefix}_VERSION})
139 endif()
140 endif()
141 if (${prefix}_CUSTOM_BINARY)
142 list(GET ${prefix}_CUSTOM_BINARY 0 FROM_BINARY)
143 list(GET ${prefix}_CUSTOM_BINARY 1 TO_BINARY)
144 install(FILES ${FROM_BINARY} DESTINATION ${target} RENAME ${TO_BINARY})
145 endif()
146 if(${prefix}_CUSTOM_DATA)
147 install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${target}/resources)
148 endif()
149 else()
150 if(NOT CPACK_PACKAGE_DIRECTORY)
151 set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR})
152 endif()
153 if(${prefix}_SOURCES)
154 install(TARGETS ${target} DESTINATION ${target}
155 COMPONENT ${target}-${${prefix}_VERSION})
156 endif()
157 if (${prefix}_CUSTOM_BINARY)
158 list(GET ${prefix}_CUSTOM_BINARY 0 FROM_BINARY)
159 list(GET ${prefix}_CUSTOM_BINARY 1 TO_BINARY)
160 if(OS STREQUAL "android")
161 set(TO_BINARY "lib${TO_BINARY}")
162 endif()
163 install(FILES ${FROM_BINARY} DESTINATION ${target} RENAME ${TO_BINARY}
164 COMPONENT ${target}-${${prefix}_VERSION})
165 endif()
166 if(${prefix}_CUSTOM_DATA)
167 install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${target}/resources)
168 endif()
169 endif()
170 add_cpack_workaround(${target} ${${prefix}_VERSION} ${ext})
171 else()
172 if(CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL rbpi OR CORE_SYSTEM_NAME STREQUAL freebsd)
173 if(NOT OVERRIDE_PATHS)
174 if(CMAKE_INSTALL_PREFIX AND NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT CMAKE_INSTALL_PREFIX STREQUAL "${${APP_NAME_UC}_PREFIX}")
175 message(WARNING "CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} differs from ${APP_NAME} prefix, changing to ${${APP_NAME_UC}_PREFIX}. Please pass -DOVERRIDE_PATHS=1 to skip this check")
176 endif()
177 if(CMAKE_INSTALL_LIBDIR AND NOT CMAKE_INSTALL_LIBDIR STREQUAL "${${APP_NAME_UC}_LIB_DIR}")
178 message(WARNING "CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} differs from ${APP_NAME} libdir, changing to ${${APP_NAME_UC}_LIB_DIR}. Please pass -DOVERRIDE_PATHS=1 to skip this check")
179 endif()
180 if(CMAKE_INSTALL_DATADIR AND NOT CMAKE_INSTALL_DATADIR STREQUAL "${${APP_NAME_UC}_DATA_DIR}")
181 message(WARNING "CMAKE_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR} differs from ${APP_NAME} datadir, changing to ${${APP_NAME_UC}_DATA_DIR}. Please pass -DOVERRIDE_PATHS=1 to skip this check")
182 endif()
183 set(CMAKE_INSTALL_PREFIX "${${APP_NAME_UC}_PREFIX}" CACHE PATH "${APP_NAME} install prefix" FORCE)
184 set(CMAKE_INSTALL_LIBDIR "${${APP_NAME_UC}_LIB_DIR}" CACHE PATH "${APP_NAME} install libdir" FORCE)
185 set(CMAKE_INSTALL_DATADIR "${${APP_NAME_UC}_DATA_DIR}" CACHE PATH "${APP_NAME} install datadir" FORCE)
186 else()
187 if(NOT CMAKE_INSTALL_LIBDIR)
188 set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib/${APP_NAME_LC}")
189 endif()
190 if(NOT CMAKE_INSTALL_DATADIR)
191 set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_PREFIX}/share/${APP_NAME_LC}")
192 endif()
193 endif()
194 else()
195 set(CMAKE_INSTALL_LIBDIR "lib/${APP_NAME_LC}")
196 set(CMAKE_INSTALL_DATADIR "share/${APP_NAME_LC}")
197 endif()
198 if(${prefix}_SOURCES)
199 install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
200 endif()
201 if (${prefix}_CUSTOM_BINARY)
202 list(GET ${prefix}_CUSTOM_BINARY 0 FROM_BINARY)
203 list(GET ${prefix}_CUSTOM_BINARY 1 TO_BINARY)
204 if(OS STREQUAL "android")
205 set(TO_BINARY "lib${TO_BINARY}")
206 endif()
207 install(FILES ${FROM_BINARY} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target} RENAME ${TO_BINARY})
208 endif()
209 install(DIRECTORY ${target} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons PATTERN "xml.in" EXCLUDE)
210 if(${prefix}_CUSTOM_DATA)
211 install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons/${target}/resources)
212 endif()
213 endif()
214 if(${APP_NAME_UC}_BUILD_DIR)
215 file(GLOB_RECURSE files ${CMAKE_CURRENT_SOURCE_DIR}/${target}/*)
216 if(${prefix}_CUSTOM_DATA)
217 add_custom_command(TARGET ${target} POST_BUILD
218 COMMAND ${CMAKE_COMMAND} -E copy_directory
219 ${${prefix}_CUSTOM_DATA}
220 ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/resources)
221 endif()
222 foreach(file ${files})
223 string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/${target}/" "" name "${file}")
224 # A good way to deal with () in filenames
225 if(NOT ${file} MATCHES xml.in)
226 configure_file(${file} ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/${name} COPYONLY)
227 endif()
228 endforeach()
229 add_custom_command(TARGET ${target} POST_BUILD
230 COMMAND ${CMAKE_COMMAND} -E copy
231 ${LIBRARY_LOCATION}
232 ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/${LIBRARY_FILENAME})
233 endif()
234endmacro()
235
236# finds a path to a given file (recursive)
237function (kodi_find_path var_name filename search_path strip_file)
238 file(GLOB_RECURSE PATH_TO_FILE ${search_path} ${filename})
239 if(strip_file)
240 string(REPLACE ${filename} "" PATH_TO_FILE ${PATH_TO_FILE})
241 endif()
242 set (${var_name} ${PATH_TO_FILE} PARENT_SCOPE)
243endfunction()
244
245# Cmake build options
246include(AddOptions)
247include(TestCXXAcceptsFlag)
248option(PACKAGE_ZIP "Package Zip file?" OFF)
249option(PACKAGE_TGZ "Package TGZ file?" OFF)
250option(BUILD_SHARED_LIBS "Build shared libs?" ON)
251
252# LTO support?
253CHECK_CXX_ACCEPTS_FLAG("-flto" HAVE_LTO)
254if(HAVE_LTO)
255 option(USE_LTO "use link time optimization" OFF)
256 if(USE_LTO)
257 add_options(ALL_LANGUAGES ALL_BUILDS "-flto")
258 endif()
259endif()
260
261# set this to try linking dependencies as static as possible
262if(ADDONS_PREFER_STATIC_LIBS)
263 set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
264endif()
265
266if(${APP_NAME_UC}_BUILD_DIR)
267 list(APPEND CMAKE_PREFIX_PATH ${${APP_NAME_UC}_BUILD_DIR}/build)
268endif()
diff --git a/project/cmake/scripts/common/archsetup.cmake b/project/cmake/scripts/common/ArchSetup.cmake
index dff5558..438e3bd 100644
--- a/project/cmake/scripts/common/archsetup.cmake
+++ b/project/cmake/scripts/common/ArchSetup.cmake
@@ -71,15 +71,33 @@ if(CMAKE_TOOLCHAIN_FILE)
71 endif() 71 endif()
72endif() 72endif()
73 73
74# While CMAKE_CROSSCOMPILING is set unconditionally if there's a toolchain file,
75# this variable is set if we can execute build artefacts on the host system (for example unit tests).
76if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR AND
77 CMAKE_HOST_SYSTEM_NAME STREQUAL CMAKE_SYSTEM_NAME)
78 set(CORE_HOST_IS_TARGET TRUE)
79else()
80 set(CORE_HOST_IS_TARGET FALSE)
81endif()
82
74# Main cpp 83# Main cpp
75set(CORE_MAIN_SOURCE ${CORE_SOURCE_DIR}/xbmc/platform/posix/main.cpp) 84set(CORE_MAIN_SOURCE ${CORE_SOURCE_DIR}/xbmc/platform/posix/main.cpp)
76 85
77# system specific arch setup 86# system specific arch setup
78include(${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/archsetup.cmake) 87if(NOT EXISTS ${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/ArchSetup.cmake)
88 message(FATAL_ERROR "Couldn't find configuration for '${CORE_SYSTEM_NAME}' "
89 "Either the platform is not (yet) supported "
90 "or a toolchain file has to be specified. "
91 "Consult ${CMAKE_SOURCE_DIR}/README.md for instructions. "
92 "Note: Specifying a toolchain requires a clean build directory!")
93endif()
94include(${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/ArchSetup.cmake)
79 95
80message(STATUS "Core system type: ${CORE_SYSTEM_NAME}") 96message(STATUS "Core system type: ${CORE_SYSTEM_NAME}")
81message(STATUS "Platform: ${PLATFORM}") 97message(STATUS "Platform: ${PLATFORM}")
82message(STATUS "CPU: ${CPU}, ARCH: ${ARCH}") 98message(STATUS "CPU: ${CPU}, ARCH: ${ARCH}")
99message(STATUS "Cross-Compiling: ${CMAKE_CROSSCOMPILING}")
100message(STATUS "Execute build artefacts on host: ${CORE_HOST_IS_TARGET}")
83 101
84check_type(string std::u16string HAVE_STD__U16_STRING) 102check_type(string std::u16string HAVE_STD__U16_STRING)
85check_type(string std::u32string HAVE_STD__U32_STRING) 103check_type(string std::u32string HAVE_STD__U32_STRING)
@@ -87,6 +105,7 @@ check_type(string char16_t HAVE_CHAR16_T)
87check_type(string char32_t HAVE_CHAR32_T) 105check_type(string char32_t HAVE_CHAR32_T)
88check_type(stdint.h uint_least16_t HAVE_STDINT_H) 106check_type(stdint.h uint_least16_t HAVE_STDINT_H)
89check_symbol_exists(posix_fadvise fcntl.h HAVE_POSIX_FADVISE) 107check_symbol_exists(posix_fadvise fcntl.h HAVE_POSIX_FADVISE)
108check_symbol_exists(PRIdMAX inttypes.h HAVE_INTTYPES_H)
90check_builtin("long* temp=0; long ret=__sync_add_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_ADD_AND_FETCH) 109check_builtin("long* temp=0; long ret=__sync_add_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_ADD_AND_FETCH)
91check_builtin("long* temp=0; long ret=__sync_sub_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_SUB_AND_FETCH) 110check_builtin("long* temp=0; long ret=__sync_sub_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_SUB_AND_FETCH)
92check_builtin("long* temp=0; long ret=__sync_val_compare_and_swap(temp, 1, 1)" HAS_BUILTIN_SYNC_VAL_COMPARE_AND_SWAP) 111check_builtin("long* temp=0; long ret=__sync_val_compare_and_swap(temp, 1, 1)" HAS_BUILTIN_SYNC_VAL_COMPARE_AND_SWAP)
@@ -97,3 +116,35 @@ check_function_exists(localtime_r HAVE_LOCALTIME_R)
97if(HAVE_LOCALTIME_R) 116if(HAVE_LOCALTIME_R)
98 list(APPEND SYSTEM_DEFINES -DHAVE_LOCALTIME_R=1) 117 list(APPEND SYSTEM_DEFINES -DHAVE_LOCALTIME_R=1)
99endif() 118endif()
119if(HAVE_INTTYPES_H)
120 list(APPEND SYSTEM_DEFINES -DHAVE_INTTYPES_H=1)
121endif()
122
123find_package(SSE)
124foreach(_sse SSE SSE2 SSE3 SSSE3 SSE4_1 SSE4_2 AVX AVX2)
125 if(${${_sse}_FOUND})
126 # enable SSE versions up to 4.1 by default, if available
127 if(NOT ${_sse} MATCHES "AVX" AND NOT ${_sse} STREQUAL "SSE4_2")
128 option(ENABLE_${_sse} "Enable ${_sse}" ON)
129 else()
130 option(ENABLE_${_sse} "Enable ${_sse}" OFF)
131 endif()
132 endif()
133 if(ENABLE_${_sse})
134 set(HAVE_${_sse} TRUE CACHE STRING "${_sse} enabled")
135 list(APPEND ARCH_DEFINES -DHAVE_${_sse}=1)
136 endif()
137endforeach()
138
139if(NOT DEFINED NEON OR NEON)
140 option(ENABLE_NEON "Enable NEON optimization" ${NEON})
141 if(ENABLE_NEON)
142 message(STATUS "NEON optimization enabled")
143 add_options(CXX ALL_BUILDS "-mfpu=neon -mvectorize-with-neon-quad")
144 endif()
145endif()
146
147if(CMAKE_BUILD_TYPE STREQUAL "Debug")
148 add_options (ALL_LANGUAGES DEBUG "-g" "-D_DEBUG" "-Wall")
149endif()
150
diff --git a/project/cmake/scripts/common/CMakeHelpers.cmake b/project/cmake/scripts/common/CMakeHelpers.cmake
new file mode 100644
index 0000000..995c38a
--- /dev/null
+++ b/project/cmake/scripts/common/CMakeHelpers.cmake
@@ -0,0 +1,54 @@
1# This file contains functions that support the debugging of the CMake files.
2
3# This file shouldn't be included per default in any CMake file. It should be
4# included and used only on demand. All functions are prefixed with "debug_".
5#
6# Usage:
7# include(scripts/common/CMakeHelpers.cmake)
8# debug_print_variables()
9
10# Print all CMake variables.
11macro(debug_print_variables)
12 get_cmake_property(_variableNames VARIABLES)
13 foreach(_variableName ${_variableNames})
14 message(STATUS "${_variableName} = ${${_variableName}}")
15 endforeach()
16endmacro()
17
18# Get all properties that CMake supports and convert them to a list.
19function(debug_get_properties VAR)
20 execute_process(COMMAND cmake --help-property-list
21 OUTPUT_VARIABLE _properties)
22 string(REGEX REPLACE ";" "\\\\;" _properties "${_properties}")
23 string(REGEX REPLACE "\n" ";" _properties "${_properties}")
24 list(REMOVE_DUPLICATES _properties)
25 list(REMOVE_ITEM _properties LOCATION)
26 set(${VAR} ${_properties} PARENT_SCOPE)
27endfunction()
28
29# List all properties.
30function(debug_list_properties)
31 debug_get_properties(_properties)
32 message("CMake properties = ${_properties}")
33endfunction()
34
35# Print all set properties of a specified target.
36function(debug_print_target_properties target)
37 if(NOT TARGET ${target})
38 message(FATAL_ERROR "There is no target named '${target}'")
39 endif()
40
41 debug_get_properties(_properties)
42
43 # Reading LOCATION property is deprecated and triggers a fatal error.
44 string(REGEX REPLACE ";LOCATION;|LOCATION" "" _properties "${_properties}")
45 string(REGEX REPLACE "<CONFIG>" "${CMAKE_BUILD_TYPE}" _properties
46 "${_properties}")
47 foreach(_property ${_properties})
48 get_property(_value TARGET ${target} PROPERTY ${_property} SET)
49 if(_value)
50 get_target_property(_value ${target} ${_property})
51 message("${target} ${_property} = ${_value}")
52 endif()
53 endforeach()
54endfunction()
diff --git a/project/cmake/scripts/common/checkcommits.cmake b/project/cmake/scripts/common/CheckCommits.cmake
index 304e623..304e623 100644
--- a/project/cmake/scripts/common/checkcommits.cmake
+++ b/project/cmake/scripts/common/CheckCommits.cmake
diff --git a/project/cmake/scripts/common/check_target_platform.cmake b/project/cmake/scripts/common/CheckTargetPlatform.cmake
index fc8b403..5b5d9a1 100644
--- a/project/cmake/scripts/common/check_target_platform.cmake
+++ b/project/cmake/scripts/common/CheckTargetPlatform.cmake
@@ -9,7 +9,7 @@ function(check_target_platform dir target_platform build)
9 if(EXISTS ${dir} AND EXISTS ${dir}/platforms.txt) 9 if(EXISTS ${dir} AND EXISTS ${dir}/platforms.txt)
10 # get all the specified platforms 10 # get all the specified platforms
11 file(STRINGS ${dir}/platforms.txt platforms) 11 file(STRINGS ${dir}/platforms.txt platforms)
12 separate_arguments(platforms) 12 string(REPLACE " " ";" platforms ${platforms})
13 13
14 # check if the addon/dependency should be built for the current platform 14 # check if the addon/dependency should be built for the current platform
15 foreach(platform ${platforms}) 15 foreach(platform ${platforms})
@@ -21,11 +21,11 @@ function(check_target_platform dir target_platform build)
21 if(${platform_first} STREQUAL "!") 21 if(${platform_first} STREQUAL "!")
22 # extract the platform 22 # extract the platform
23 string(LENGTH ${platform} platform_length) 23 string(LENGTH ${platform} platform_length)
24 MATH(EXPR platform_length "${platform_length} - 1") 24 math(EXPR platform_length "${platform_length} - 1")
25 string(SUBSTRING ${platform} 1 ${platform_length} platform) 25 string(SUBSTRING ${platform} 1 ${platform_length} platform)
26 26
27 # check if the current platform does not match the extracted platform 27 # check if the current platform does not match the extracted platform
28 if (NOT ${platform} STREQUAL ${target_platform}) 28 if(NOT ${platform} STREQUAL ${target_platform})
29 set(${build} TRUE) 29 set(${build} TRUE)
30 endif() 30 endif()
31 endif() 31 endif()
@@ -43,19 +43,21 @@ function(check_install_permissions install_dir have_perms)
43 # param[in] install_dir directory to check for write permissions 43 # param[in] install_dir directory to check for write permissions
44 # param[out] have_perms wether we have permissions to install to install_dir 44 # param[out] have_perms wether we have permissions to install to install_dir
45 45
46 set(${have_perms} TRUE) 46 set(testfile_lib ${install_dir}/lib/kodi/.cmake-inst-test)
47 execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}/lib/kodi 47 set(testfile_share ${install_dir}/share/kodi/.cmake-inst-test)
48 COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}/share/kodi 48 get_filename_component(testdir_lib ${testfile_lib} DIRECTORY)
49 COMMAND ${CMAKE_COMMAND} -E touch ${install_dir}/lib/kodi/.cmake-inst-test ${install_dir}/share/kodi/.cmake-inst-test 49 get_filename_component(testdir_share ${testfile_share} DIRECTORY)
50 RESULT_VARIABLE permtest)
51 50
52 if(${permtest} GREATER 0) 51 execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${testdir_lib})
53 message(STATUS "check_install_permissions: ${permtest}") 52 execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${testdir_share})
54 set(${have_perms} FALSE) 53 execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${testfile_lib})
55 endif() 54 execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${testfile_share})
56 set(${have_perms} "${${have_perms}}" PARENT_SCOPE)
57 55
58 if(EXISTS ${install_dir}/lib/kodi/.cmake-inst-test OR EXISTS ${install_dir}/share/kodi/.cmake-inst-test) 56 if(EXISTS ${testfile_lib} AND EXISTS ${testfile_share})
59 file(REMOVE ${install_dir}/lib/kodi/.cmake-inst-test ${install_dir}/share/kodi/.cmake-inst-test) 57 set(${have_perms} True PARENT_SCOPE)
58 else()
59 message(STATUS "check_install_permissions ${install_dir}: failed to create files")
60 set(${have_perms} False PARENT_SCOPE)
60 endif() 61 endif()
62 file(REMOVE ${testfile_lib} ${testfile_share})
61endfunction() 63endfunction()
diff --git a/project/cmake/scripts/common/GenerateVersionedFiles.cmake b/project/cmake/scripts/common/GenerateVersionedFiles.cmake
new file mode 100644
index 0000000..e105b27
--- /dev/null
+++ b/project/cmake/scripts/common/GenerateVersionedFiles.cmake
@@ -0,0 +1,18 @@
1include(${CORE_SOURCE_DIR}/project/cmake/scripts/common/Macros.cmake)
2
3core_find_versions()
4file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/xbmc.addon)
5file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/kodi.guilib)
6
7# configure_file without dependency tracking
8# configure_file would register additional file dependencies that interfere
9# with the ones from add_custom_command (and the generation would happen twice)
10function(generate_versioned_file _SRC _DEST)
11 file(READ ${CORE_SOURCE_DIR}/${_SRC} file_content)
12 string(CONFIGURE "${file_content}" file_content @ONLY)
13 file(WRITE ${CMAKE_BINARY_DIR}/${_DEST} "${file_content}")
14endfunction()
15
16generate_versioned_file(addons/xbmc.addon/addon.xml.in addons/xbmc.addon/addon.xml)
17generate_versioned_file(addons/kodi.guilib/addon.xml.in addons/kodi.guilib/addon.xml)
18generate_versioned_file(xbmc/CompileInfo.cpp.in ${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp)
diff --git a/project/cmake/scripts/common/generatorsetup.cmake b/project/cmake/scripts/common/GeneratorSetup.cmake
index 75083ca..304b504 100644
--- a/project/cmake/scripts/common/generatorsetup.cmake
+++ b/project/cmake/scripts/common/GeneratorSetup.cmake
@@ -22,3 +22,28 @@ else()
22 set(CORE_BUILD_CONFIG ${CMAKE_BUILD_TYPE}) 22 set(CORE_BUILD_CONFIG ${CMAKE_BUILD_TYPE})
23 message(STATUS "Generator: Single-configuration: ${CMAKE_BUILD_TYPE} (${CMAKE_GENERATOR})") 23 message(STATUS "Generator: Single-configuration: ${CMAKE_BUILD_TYPE} (${CMAKE_GENERATOR})")
24endif() 24endif()
25
26# Print CMake version
27message(STATUS "CMake Version: ${CMAKE_VERSION}")
28
29# Deal with CMake special cases
30if(CMAKE_VERSION VERSION_EQUAL 3.5.1)
31 message(WARNING "CMake 3.5.1 introduced a crash during configuration. "
32 "Please consider upgrading to 3.5.2 (cmake.org/Bug/view.php?id=16044)")
33endif()
34
35# Darwin needs CMake 3.4
36if(APPLE AND CMAKE_VERSION VERSION_LESS 3.4)
37 message(WARNING "Build on Darwin requires CMake 3.4 or later (tdb library support) "
38 "or the usage of the patched version in depends.")
39endif()
40
41# Windows needs CMake 3.6 (VS_STARTUP_PROJECT)
42if(WIN32 AND CMAKE_VERSION VERSION_LESS 3.6)
43 message(FATAL_ERROR "Build on Windows needs CMake 3.6 or later")
44endif()
45
46# Ninja needs CMake 3.2 due to ExternalProject BUILD_BYPRODUCTS usage
47if(CMAKE_GENERATOR STREQUAL Ninja AND CMAKE_VERSION VERSION_LESS 3.2)
48 message(FATAL_ERROR "Generator: Ninja requires CMake 3.2 or later")
49endif()
diff --git a/project/cmake/scripts/common/handle-depends.cmake b/project/cmake/scripts/common/HandleDepends.cmake
index 4d78928..880ccdf 100644
--- a/project/cmake/scripts/common/handle-depends.cmake
+++ b/project/cmake/scripts/common/HandleDepends.cmake
@@ -1,15 +1,17 @@
1include(${APP_ROOT}/project/cmake/scripts/common/check_target_platform.cmake) 1include(${CORE_SOURCE_DIR}/project/cmake/scripts/common/CheckTargetPlatform.cmake)
2 2
3# handle addon depends 3# handle addon depends
4function(add_addon_depends addon searchpath) 4function(add_addon_depends addon searchpath)
5 # input: string addon string searchpath 5 # input: string addon string searchpath
6 6
7 set(OUTPUT_DIR ${DEPENDS_PATH}) 7 set(OUTPUT_DIR ${ADDON_DEPENDS_PATH})
8 # look for platform-specific dependencies
8 file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt) 9 file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt)
9 file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt) 10 file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt)
10 list(APPEND cmake_input_files ${cmake_input_files2}) 11 list(APPEND cmake_input_files ${cmake_input_files2})
11 12
12 foreach(file ${cmake_input_files}) 13 foreach(file ${cmake_input_files})
14 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${file})
13 if(NOT (file MATCHES CMakeLists.txt OR 15 if(NOT (file MATCHES CMakeLists.txt OR
14 file MATCHES install.txt OR 16 file MATCHES install.txt OR
15 file MATCHES noinstall.txt OR 17 file MATCHES noinstall.txt OR
@@ -18,9 +20,9 @@ function(add_addon_depends addon searchpath)
18 file MATCHES platforms.txt)) 20 file MATCHES platforms.txt))
19 message(STATUS "Processing ${file}") 21 message(STATUS "Processing ${file}")
20 file(STRINGS ${file} def) 22 file(STRINGS ${file} def)
21 separate_arguments(def) 23 string(REPLACE " " ";" def ${def})
22 list(LENGTH def deflength) 24 list(LENGTH def deflength)
23 get_filename_component(dir ${file} PATH) 25 get_filename_component(dir ${file} DIRECTORY)
24 26
25 # get the id of the dependency 27 # get the id of the dependency
26 if(NOT "${def}" STREQUAL "") 28 if(NOT "${def}" STREQUAL "")
@@ -45,8 +47,9 @@ function(add_addon_depends addon searchpath)
45 47
46 # check if there are any library specific flags that need to be passed on 48 # check if there are any library specific flags that need to be passed on
47 if(EXISTS ${dir}/flags.txt) 49 if(EXISTS ${dir}/flags.txt)
50 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags.txt)
48 file(STRINGS ${dir}/flags.txt extraflags) 51 file(STRINGS ${dir}/flags.txt extraflags)
49 separate_arguments(extraflags) 52 string(REPLACE " " ";" extraflags ${extraflags})
50 message(STATUS "${id} extraflags: ${extraflags}") 53 message(STATUS "${id} extraflags: ${extraflags}")
51 endif() 54 endif()
52 55
@@ -70,16 +73,20 @@ function(add_addon_depends addon searchpath)
70 73
71 if(CMAKE_TOOLCHAIN_FILE) 74 if(CMAKE_TOOLCHAIN_FILE)
72 list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) 75 list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
73 MESSAGE("toolchain specified") 76 message("toolchain specified")
74 MESSAGE(${BUILD_ARGS}) 77 message(${BUILD_ARGS})
75 endif() 78 endif()
76 79
77 # if there's a CMakeLists.txt use it to prepare the build 80 # prepare patchfile. ensure we have a clean file after reconfiguring
78 set(PATCH_FILE ${BUILD_DIR}/${id}/tmp/patch.cmake) 81 set(PATCH_FILE ${BUILD_DIR}/${id}/tmp/patch.cmake)
82 file(REMOVE ${PATCH_FILE})
83
84 # if there's a CMakeLists.txt use it to prepare the build
79 if(EXISTS ${dir}/CMakeLists.txt) 85 if(EXISTS ${dir}/CMakeLists.txt)
86 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/CMakeLists.txt)
80 file(APPEND ${PATCH_FILE} 87 file(APPEND ${PATCH_FILE}
81 "file(COPY ${dir}/CMakeLists.txt 88 "file(COPY ${dir}/CMakeLists.txt
82 DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") 89 DESTINATION ${BUILD_DIR}/${id}/src/${id})\n")
83 endif() 90 endif()
84 91
85 # check if we have patches to apply 92 # check if we have patches to apply
@@ -104,6 +111,7 @@ function(add_addon_depends addon searchpath)
104 endif() 111 endif()
105 endif() 112 endif()
106 113
114 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${patch})
107 file(APPEND ${PATCH_FILE} 115 file(APPEND ${PATCH_FILE}
108 "execute_process(COMMAND ${PATCH_PROGRAM} -p1 -i \"${patch}\")\n") 116 "execute_process(COMMAND ${PATCH_PROGRAM} -p1 -i \"${patch}\")\n")
109 endforeach() 117 endforeach()
@@ -125,6 +133,7 @@ function(add_addon_depends addon searchpath)
125 133
126 # check if there's a deps.txt containing dependencies on other libraries 134 # check if there's a deps.txt containing dependencies on other libraries
127 if(EXISTS ${dir}/deps.txt) 135 if(EXISTS ${dir}/deps.txt)
136 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/deps.txt)
128 file(STRINGS ${dir}/deps.txt deps) 137 file(STRINGS ${dir}/deps.txt deps)
129 message(STATUS "${id} depends: ${deps}") 138 message(STATUS "${id} depends: ${deps}")
130 else() 139 else()
@@ -133,6 +142,7 @@ function(add_addon_depends addon searchpath)
133 142
134 if(CROSS_AUTOCONF AND AUTOCONF_FILES) 143 if(CROSS_AUTOCONF AND AUTOCONF_FILES)
135 foreach(afile ${AUTOCONF_FILES}) 144 foreach(afile ${AUTOCONF_FILES})
145 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${afile})
136 file(APPEND ${PATCH_FILE} 146 file(APPEND ${PATCH_FILE}
137 "message(STATUS \"AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}\")\n 147 "message(STATUS \"AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}\")\n
138 file(COPY ${afile} DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") 148 file(COPY ${afile} DESTINATION ${BUILD_DIR}/${id}/src/${id})\n")
@@ -141,7 +151,7 @@ function(add_addon_depends addon searchpath)
141 151
142 # if the patch file exists we need to set the PATCH_COMMAND 152 # if the patch file exists we need to set the PATCH_COMMAND
143 set(PATCH_COMMAND "") 153 set(PATCH_COMMAND "")
144 if (EXISTS ${PATCH_FILE}) 154 if(EXISTS ${PATCH_FILE})
145 set(PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_FILE}) 155 set(PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_FILE})
146 endif() 156 endif()
147 157
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
diff --git a/project/cmake/scripts/common/prepare-env.cmake b/project/cmake/scripts/common/PrepareEnv.cmake
index 8e9bd1c..8e02382 100644
--- a/project/cmake/scripts/common/prepare-env.cmake
+++ b/project/cmake/scripts/common/PrepareEnv.cmake
@@ -1,25 +1,6 @@
1# parse version.txt to get the version info 1# parse version.txt and libKODI_guilib.h to get the version and API info
2if(EXISTS "${APP_ROOT}/version.txt") 2include(${CORE_SOURCE_DIR}/project/cmake/scripts/common/Macros.cmake)
3 file(STRINGS "${APP_ROOT}/version.txt" versions) 3core_find_versions()
4 foreach (version ${versions})
5 if(version MATCHES "^VERSION_.*")
6 string(REGEX MATCH "^[^ ]+" version_name ${version})
7 string(REPLACE "${version_name} " "" version_value ${version})
8 set(APP_${version_name} "${version_value}")
9 else()
10 string(REGEX MATCH "^[^ ]+" name ${version})
11 string(REPLACE "${name} " "" value ${version})
12 set(${name} "${value}")
13 endif()
14 endforeach()
15 string(TOLOWER ${APP_NAME} APP_NAME_LC)
16 string(TOUPPER ${APP_NAME} APP_NAME_UC)
17endif()
18
19# bail if we can't parse versions
20if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR)
21 message(FATAL_ERROR "Could not determine app version! make sure that ${APP_ROOT}/version.txt exists")
22endif()
23 4
24# in case we need to download something, set KODI_MIRROR to the default if not alread set 5# in case we need to download something, set KODI_MIRROR to the default if not alread set
25if(NOT DEFINED KODI_MIRROR) 6if(NOT DEFINED KODI_MIRROR)
@@ -28,24 +9,19 @@ endif()
28 9
29### copy all the addon binding header files to include/kodi 10### copy all the addon binding header files to include/kodi
30# make sure include/kodi exists and is empty 11# make sure include/kodi exists and is empty
31set(APP_LIB_DIR ${DEPENDS_PATH}/lib/${APP_NAME_LC}) 12set(APP_LIB_DIR ${ADDON_DEPENDS_PATH}/lib/${APP_NAME_LC})
32if(NOT EXISTS "${APP_LIB_DIR}/") 13if(NOT EXISTS "${APP_LIB_DIR}/")
33 file(MAKE_DIRECTORY ${APP_LIB_DIR}) 14 file(MAKE_DIRECTORY ${APP_LIB_DIR})
34endif() 15endif()
35 16
36set(APP_INCLUDE_DIR ${DEPENDS_PATH}/include/${APP_NAME_LC}) 17set(APP_DATA_DIR ${ADDON_DEPENDS_PATH}/share/${APP_NAME_LC})
37if(NOT EXISTS "${APP_INCLUDE_DIR}/") 18if(NOT EXISTS "${APP_DATA_DIR}/")
38 file(MAKE_DIRECTORY ${APP_INCLUDE_DIR}) 19 file(MAKE_DIRECTORY ${APP_DATA_DIR})
39endif() 20endif()
40 21
41# we still need XBMC_INCLUDE_DIR and XBMC_LIB_DIR for backwards compatibility to xbmc 22set(APP_INCLUDE_DIR ${ADDON_DEPENDS_PATH}/include/${APP_NAME_LC})
42set(XBMC_LIB_DIR ${DEPENDS_PATH}/lib/xbmc) 23if(NOT EXISTS "${APP_INCLUDE_DIR}/")
43if(NOT EXISTS "${XBMC_LIB_DIR}/") 24 file(MAKE_DIRECTORY ${APP_INCLUDE_DIR})
44 file(MAKE_DIRECTORY ${XBMC_LIB_DIR})
45endif()
46set(XBMC_INCLUDE_DIR ${DEPENDS_PATH}/include/xbmc)
47if(NOT EXISTS "${XBMC_INCLUDE_DIR}/")
48 file(MAKE_DIRECTORY ${XBMC_INCLUDE_DIR})
49endif() 25endif()
50 26
51# make sure C++11 is always set 27# make sure C++11 is always set
@@ -56,42 +32,23 @@ if(NOT WIN32)
56 endif() 32 endif()
57endif() 33endif()
58 34
59# generate the proper kodi-config.cmake file 35# generate the proper KodiConfig.cmake file
60configure_file(${APP_ROOT}/project/cmake/kodi-config.cmake.in ${APP_LIB_DIR}/kodi-config.cmake @ONLY) 36configure_file(${CORE_SOURCE_DIR}/project/cmake/KodiConfig.cmake.in ${APP_LIB_DIR}/KodiConfig.cmake @ONLY)
61 37
62# copy cmake helpers to lib/kodi 38# copy cmake helpers to lib/kodi
63file(COPY ${APP_ROOT}/project/cmake/scripts/common/addon-helpers.cmake 39file(COPY ${CORE_SOURCE_DIR}/project/cmake/scripts/common/AddonHelpers.cmake
64 ${APP_ROOT}/project/cmake/scripts/common/addoptions.cmake 40 ${CORE_SOURCE_DIR}/project/cmake/scripts/common/AddOptions.cmake
65 DESTINATION ${APP_LIB_DIR}) 41 DESTINATION ${APP_LIB_DIR})
66 42
67# generate xbmc-config.cmake for backwards compatibility to xbmc
68configure_file(${APP_ROOT}/project/cmake/xbmc-config.cmake.in ${XBMC_LIB_DIR}/xbmc-config.cmake @ONLY)
69
70### copy all the addon binding header files to include/kodi 43### copy all the addon binding header files to include/kodi
71# parse addon-bindings.mk to get the list of header files to copy 44# parse addon-bindings.mk to get the list of header files to copy
72file(STRINGS ${APP_ROOT}/xbmc/addons/addon-bindings.mk bindings) 45core_file_read_filtered(bindings ${CORE_SOURCE_DIR}/xbmc/addons/addon-bindings.mk)
73string(REPLACE "\n" ";" bindings "${bindings}")
74foreach(binding ${bindings}) 46foreach(binding ${bindings})
75 string(REPLACE " =" ";" binding "${binding}") 47 string(REPLACE " =" ";" binding "${binding}")
76 string(REPLACE "+=" ";" binding "${binding}") 48 string(REPLACE "+=" ";" binding "${binding}")
77 list(GET binding 1 header) 49 list(GET binding 1 header)
78 # copy the header file to include/kodi 50 # copy the header file to include/kodi
79 file(COPY ${APP_ROOT}/${header} DESTINATION ${APP_INCLUDE_DIR}) 51 configure_file(${CORE_SOURCE_DIR}/${header} ${APP_INCLUDE_DIR} COPYONLY)
80
81 # auto-generate header files for backwards compatibility to xbmc with deprecation warning
82 # but only do it if the file doesn't already exist
83 get_filename_component(headerfile ${header} NAME)
84 if (NOT EXISTS "${XBMC_INCLUDE_DIR}/${headerfile}")
85 file(WRITE ${XBMC_INCLUDE_DIR}/${headerfile}
86"#pragma once
87#define DEPRECATION_WARNING \"Including xbmc/${headerfile} has been deprecated, please use kodi/${headerfile}\"
88#ifdef _MSC_VER
89 #pragma message(\"WARNING: \" DEPRECATION_WARNING)
90#else
91 #warning DEPRECATION_WARNING
92#endif
93#include \"kodi/${headerfile}\"")
94 endif()
95endforeach() 52endforeach()
96 53
97### on windows we need a "patch" binary to be able to patch 3rd party sources 54### on windows we need a "patch" binary to be able to patch 3rd party sources
@@ -125,12 +82,12 @@ if(WIN32)
125 endif() 82 endif()
126 83
127 # copy patch.exe into the output directory 84 # copy patch.exe into the output directory
128 file(INSTALL ${PATCH_BINARY_PATH} DESTINATION ${DEPENDS_PATH}/bin) 85 file(INSTALL ${PATCH_BINARY_PATH} DESTINATION ${ADDON_DEPENDS_PATH}/bin)
129 86
130 # make sure that cmake can find the copied patch.exe 87 # make sure that cmake can find the copied patch.exe
131 find_program(PATCH_FOUND NAMES patch patch.exe) 88 find_program(PATCH_FOUND NAMES patch patch.exe)
132 if(NOT PATCH_FOUND) 89 if(NOT PATCH_FOUND)
133 message(FATAL_ERROR "ERROR installing patch utility from ${PATCH_BINARY_PATH} to ${DEPENDS_PATH}/bin") 90 message(FATAL_ERROR "ERROR installing patch utility from ${PATCH_BINARY_PATH} to ${ADDON_DEPENDS_PATH}/bin")
134 endif() 91 endif()
135 endif() 92 endif()
136endif() 93endif()
diff --git a/project/cmake/scripts/common/projectmacros.cmake b/project/cmake/scripts/common/ProjectMacros.cmake
index 7ce4ee9..e73ef90 100644
--- a/project/cmake/scripts/common/projectmacros.cmake
+++ b/project/cmake/scripts/common/ProjectMacros.cmake
@@ -8,7 +8,7 @@
8# xbt is added to ${XBT_FILES} 8# xbt is added to ${XBT_FILES}
9function(pack_xbt input output) 9function(pack_xbt input output)
10 file(GLOB_RECURSE MEDIA_FILES ${input}/*) 10 file(GLOB_RECURSE MEDIA_FILES ${input}/*)
11 get_filename_component(dir ${output} PATH) 11 get_filename_component(dir ${output} DIRECTORY)
12 add_custom_command(OUTPUT ${output} 12 add_custom_command(OUTPUT ${output}
13 COMMAND ${CMAKE_COMMAND} -E make_directory ${dir} 13 COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
14 COMMAND TexturePacker::TexturePacker 14 COMMAND TexturePacker::TexturePacker
@@ -23,18 +23,17 @@ endfunction()
23# Add a skin to installation list, mirroring it in build tree, packing textures 23# Add a skin to installation list, mirroring it in build tree, packing textures
24# Arguments: 24# Arguments:
25# skin skin directory 25# skin skin directory
26# relative relative base path in build tree
27# On return: 26# On return:
28# xbt is added to ${XBT_FILES}, data added to ${install_data}, mirror in build tree 27# xbt is added to ${XBT_FILES}, data added to ${install_data}, mirror in build tree
29function(copy_skin_to_buildtree skin relative) 28function(copy_skin_to_buildtree skin)
30 file(GLOB_RECURSE FILES ${skin}/*) 29 file(GLOB_RECURSE FILES ${skin}/*)
31 file(GLOB_RECURSE MEDIA_FILES ${skin}/media/*) 30 file(GLOB_RECURSE MEDIA_FILES ${skin}/media/*)
32 list(REMOVE_ITEM FILES ${MEDIA_FILES}) 31 list(REMOVE_ITEM FILES ${MEDIA_FILES})
33 foreach(file ${FILES}) 32 foreach(file ${FILES})
34 copy_file_to_buildtree(${file} ${relative}) 33 copy_file_to_buildtree(${file})
35 endforeach() 34 endforeach()
36 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${dest}/media) 35 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${dest}/media)
37 string(REPLACE "${relative}/" "" dest ${skin}) 36 string(REPLACE "${CORE_SOURCE_DIR}/" "" dest ${skin})
38 pack_xbt(${skin}/media ${CMAKE_BINARY_DIR}/${dest}/media/Textures.xbt) 37 pack_xbt(${skin}/media ${CMAKE_BINARY_DIR}/${dest}/media/Textures.xbt)
39 38
40 file(GLOB THEMES RELATIVE ${skin}/themes ${skin}/themes/*) 39 file(GLOB THEMES RELATIVE ${skin}/themes ${skin}/themes/*)
@@ -54,6 +53,9 @@ function(GTEST_ADD_TESTS executable extra_args)
54 message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS") 53 message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
55 endif() 54 endif()
56 foreach(source ${ARGN}) 55 foreach(source ${ARGN})
56 # This assumes that every source file passed in exists. Consider using
57 # SUPPORT_SOURCES for source files which do not contain tests and might
58 # have to be generated.
57 file(READ "${source}" contents) 59 file(READ "${source}" contents)
58 string(REGEX MATCHALL "TEST_?[F]?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents}) 60 string(REGEX MATCHALL "TEST_?[F]?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
59 foreach(hit ${found_tests}) 61 foreach(hit ${found_tests})
diff --git a/project/cmake/scripts/common/Uninstall.cmake b/project/cmake/scripts/common/Uninstall.cmake
new file mode 100644
index 0000000..5660e19
--- /dev/null
+++ b/project/cmake/scripts/common/Uninstall.cmake
@@ -0,0 +1,22 @@
1# Uninstall target
2set(MANIFEST ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt)
3if(EXISTS ${MANIFEST})
4 file(STRINGS ${MANIFEST} files)
5 foreach(file IN LISTS files)
6 if(EXISTS $ENV{DESTDIR}${file})
7 message(STATUS "Uninstalling: ${file}")
8 execute_process(
9 COMMAND ${CMAKE_COMMAND} -E remove $ENV{DESTDIR}${file}
10 OUTPUT_VARIABLE rm_out
11 RESULT_VARIABLE rm_retval
12 )
13 if(NOT "${rm_retval}" STREQUAL 0)
14 message(FATAL_ERROR "Failed to remove file: $ENV{DESTDIR}${file}")
15 endif()
16 else()
17 message(STATUS "File does not exist: $ENV{DESTDIR}${file}")
18 endif()
19 endforeach(file)
20else()
21 message(STATUS "Cannot find install manifest: '${MANIFEST}'")
22endif()
diff --git a/project/cmake/scripts/common/addon-helpers.cmake b/project/cmake/scripts/common/addon-helpers.cmake
deleted file mode 100644
index caef610..0000000
--- a/project/cmake/scripts/common/addon-helpers.cmake
+++ /dev/null
@@ -1,171 +0,0 @@
1# Workaround for the fact that cpack's filenames are not customizable.
2# Each add-on is added as a separate component to facilitate zip/tgz packaging.
3# The filenames are always of the form basename-component, which is
4# incompatible with the addonid-version scheme we want. This hack renames
5# the files from the file names generated by the 'package' target.
6# Sadly we cannot extend the 'package' target, as it is a builtin target, see
7# http://public.kitware.com/Bug/view.php?id=8438
8# Thus, we have to add an 'addon-package' target.
9add_custom_target(addon-package
10 COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package)
11
12macro(add_cpack_workaround target version ext)
13 if(NOT PACKAGE_DIR)
14 set(PACKAGE_DIR "${CMAKE_INSTALL_PREFIX}/zips")
15 endif()
16
17 add_custom_command(TARGET addon-package PRE_BUILD
18 COMMAND ${CMAKE_COMMAND} -E make_directory ${PACKAGE_DIR}
19 COMMAND ${CMAKE_COMMAND} -E copy ${CPACK_PACKAGE_DIRECTORY}/addon-${target}-${version}.${ext} ${PACKAGE_DIR}/${target}-${version}.${ext})
20endmacro()
21
22# Grab the version from a given add-on's addon.xml
23macro (addon_version dir prefix)
24 IF(EXISTS ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in)
25 FILE(READ ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in ADDONXML)
26 ELSE()
27 FILE(READ ${dir}/addon.xml ADDONXML)
28 ENDIF()
29
30 STRING(REGEX MATCH "<addon[^>]*version.?=.?.[0-9\\.]+" VERSION_STRING ${ADDONXML})
31 STRING(REGEX REPLACE ".*version=.([0-9\\.]+).*" "\\1" ${prefix}_VERSION ${VERSION_STRING})
32 message(STATUS ${prefix}_VERSION=${${prefix}_VERSION})
33endmacro()
34
35# Build, link and optionally package an add-on
36macro (build_addon target prefix libs)
37 ADD_LIBRARY(${target} ${${prefix}_SOURCES})
38 TARGET_LINK_LIBRARIES(${target} ${${libs}})
39 addon_version(${target} ${prefix})
40 SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${${prefix}_VERSION}
41 SOVERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}
42 PREFIX "")
43 IF(OS STREQUAL "android")
44 SET_TARGET_PROPERTIES(${target} PROPERTIES PREFIX "lib")
45 ENDIF(OS STREQUAL "android")
46
47 # get the library's location
48 SET(LIBRARY_LOCATION $<TARGET_FILE:${target}>)
49 # get the library's filename
50 if("${CORE_SYSTEM_NAME}" STREQUAL "android")
51 # for android we need the filename without any version numbers
52 set(LIBRARY_FILENAME $<TARGET_LINKER_FILE_NAME:${target}>)
53 else()
54 SET(LIBRARY_FILENAME $<TARGET_FILE_NAME:${target}>)
55 endif()
56
57 # if there's an addon.xml.in we need to generate the addon.xml
58 IF(EXISTS ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in)
59 SET(PLATFORM ${CORE_SYSTEM_NAME})
60
61 FILE(READ ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in addon_file)
62 STRING(CONFIGURE "${addon_file}" addon_file_conf @ONLY)
63 FILE(GENERATE OUTPUT ${PROJECT_SOURCE_DIR}/${target}/addon.xml CONTENT "${addon_file_conf}")
64 ENDIF()
65
66 # set zip as default if addon-package is called without PACKAGE_XXX
67 SET(CPACK_GENERATOR "ZIP")
68 SET(ext "zip")
69 IF(PACKAGE_ZIP OR PACKAGE_TGZ)
70 IF(PACKAGE_TGZ)
71 SET(CPACK_GENERATOR "TGZ")
72 SET(ext "tar.gz")
73 ENDIF(PACKAGE_TGZ)
74 SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
75 set(CPACK_PACKAGE_FILE_NAME addon)
76 IF(CMAKE_BUILD_TYPE STREQUAL "Release")
77 SET(CPACK_STRIP_FILES TRUE)
78 ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release")
79 set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
80 set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
81 list(APPEND CPACK_COMPONENTS_ALL ${target}-${${prefix}_VERSION})
82 # Pack files together to create an archive
83 INSTALL(DIRECTORY ${target} DESTINATION ./ COMPONENT ${target}-${${prefix}_VERSION} PATTERN "addon.xml.in" EXCLUDE)
84 IF(WIN32)
85 if(NOT CPACK_PACKAGE_DIRECTORY)
86 # determine the temporary path
87 file(TO_CMAKE_PATH "$ENV{TEMP}" WIN32_TEMP_PATH)
88 string(LENGTH "${WIN32_TEMP_PATH}" WIN32_TEMP_PATH_LENGTH)
89 string(LENGTH "${PROJECT_BINARY_DIR}" PROJECT_BINARY_DIR_LENGTH)
90
91 # check if the temporary path is shorter than the default packaging directory path
92 if(WIN32_TEMP_PATH_LENGTH GREATER 0 AND WIN32_TEMP_PATH_LENGTH LESS PROJECT_BINARY_DIR_LENGTH)
93 # set the directory used by CPack for packaging to the temp directory
94 set(CPACK_PACKAGE_DIRECTORY ${WIN32_TEMP_PATH})
95 endif()
96 endif()
97
98 # in case of a VC++ project the installation location contains a $(Configuration) VS variable
99 # we replace it with ${CMAKE_BUILD_TYPE} (which doesn't cover the case when the build configuration
100 # is changed within Visual Studio)
101 string(REPLACE "$(Configuration)" "${CMAKE_BUILD_TYPE}" LIBRARY_LOCATION "${LIBRARY_LOCATION}")
102
103 # install the generated DLL file
104 INSTALL(PROGRAMS ${LIBRARY_LOCATION} DESTINATION ${target}
105 COMPONENT ${target}-${${prefix}_VERSION})
106
107 IF(CMAKE_BUILD_TYPE MATCHES Debug)
108 # for debug builds also install the PDB file
109 get_filename_component(LIBRARY_DIR ${LIBRARY_LOCATION} DIRECTORY)
110 INSTALL(FILES $<TARGET_PDB_FILE:${target}> DESTINATION ${target}
111 COMPONENT ${target}-${${prefix}_VERSION})
112 ENDIF()
113 ELSE(WIN32)
114 if(NOT CPACK_PACKAGE_DIRECTORY)
115 set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR})
116 endif()
117 INSTALL(TARGETS ${target} DESTINATION ${target}
118 COMPONENT ${target}-${${prefix}_VERSION})
119 ENDIF(WIN32)
120 add_cpack_workaround(${target} ${${prefix}_VERSION} ${ext})
121 ELSE(PACKAGE_ZIP OR PACKAGE_TGZ)
122 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
123 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX)
124 message(STATUS "setting install paths to match ${APP_NAME}: CMAKE_INSTALL_PREFIX: ${${APP_NAME_UC}_PREFIX}")
125 set(CMAKE_INSTALL_PREFIX "${${APP_NAME_UC}_PREFIX}" CACHE PATH "${APP_NAME} install prefix" FORCE)
126 set(CMAKE_INSTALL_LIBDIR "${${APP_NAME_UC}_LIB_DIR}" CACHE PATH "${APP_NAME} install libdir" FORCE)
127 elseif(NOT CMAKE_INSTALL_PREFIX STREQUAL "${${APP_NAME_UC}_PREFIX}" AND NOT OVERRIDE_PATHS)
128 message(FATAL_ERROR "CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} differs from ${APP_NAME} prefix ${${APP_NAME_UC}_PREFIX}. Please pass -DOVERRIDE_PATHS=1 to skip this check")
129 else()
130 if(NOT CMAKE_INSTALL_LIBDIR)
131 set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib/${APP_NAME_LC}")
132 endif()
133 endif()
134 else()
135 set(CMAKE_INSTALL_LIBDIR "lib/${APP_NAME_LC}")
136 endif()
137 INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
138 INSTALL(DIRECTORY ${target} DESTINATION share/${APP_NAME_LC}/addons PATTERN "addon.xml.in" EXCLUDE)
139 ENDIF(PACKAGE_ZIP OR PACKAGE_TGZ)
140endmacro()
141
142# finds a path to a given file (recursive)
143function (kodi_find_path var_name filename search_path strip_file)
144 file(GLOB_RECURSE PATH_TO_FILE ${search_path} ${filename})
145 if(strip_file)
146 string(REPLACE ${filename} "" PATH_TO_FILE ${PATH_TO_FILE})
147 endif(strip_file)
148 set (${var_name} ${PATH_TO_FILE} PARENT_SCOPE)
149endfunction()
150
151# Cmake build options
152include(addoptions)
153include(TestCXXAcceptsFlag)
154OPTION(PACKAGE_ZIP "Package Zip file?" OFF)
155OPTION(PACKAGE_TGZ "Package TGZ file?" OFF)
156OPTION(BUILD_SHARED_LIBS "Build shared libs?" ON)
157
158# LTO support?
159CHECK_CXX_ACCEPTS_FLAG("-flto" HAVE_LTO)
160IF(HAVE_LTO)
161 OPTION(USE_LTO "use link time optimization" OFF)
162 IF(USE_LTO)
163 add_options(ALL_LANGUAGES ALL_BUILDS "-flto")
164 ENDIF(USE_LTO)
165ENDIF(HAVE_LTO)
166
167# set this to try linking dependencies as static as possible
168IF(ADDONS_PREFER_STATIC_LIBS)
169 SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
170ENDIF(ADDONS_PREFER_STATIC_LIBS)
171
diff --git a/project/cmake/scripts/common/addoptions.cmake b/project/cmake/scripts/common/addoptions.cmake
deleted file mode 100644
index 0ebb823..0000000
--- a/project/cmake/scripts/common/addoptions.cmake
+++ /dev/null
@@ -1,82 +0,0 @@
1# - Add options without repeating them on the command line
2#
3# Synopsis:
4#
5# add_options (lang build opts)
6#
7# where:
8#
9# lang Name of the language whose compiler should receive the
10# options, e.g. CXX. If a comma-separated list is received
11# then the option is added for all those languages. Use the
12# special value ALL_LANGUAGES for these languages: CXX, C
13# and Fortran
14#
15# build Kind of build to which this options should apply,
16# such as DEBUG and RELEASE. This can also be a comma-
17# separated list. Use the special value ALL_BUILDS to apply
18# to all builds.
19#
20# opts List of options to add. Each should be quoted.
21#
22# Example:
23#
24# add_options (CXX RELEASE "-O3" "-DNDEBUG" "-Wall")
25
26function (add_options langs builds)
27 # special handling of empty language specification
28 if ("${langs}" STREQUAL "ALL_LANGUAGES")
29 set (langs CXX C Fortran)
30 endif ("${langs}" STREQUAL "ALL_LANGUAGES")
31 foreach (lang IN LISTS langs)
32 # prepend underscore if necessary
33 foreach (build IN LISTS builds)
34 if (NOT ("${build}" STREQUAL "ALL_BUILDS"))
35 set (_bld "_${build}")
36 string (TOUPPER "${_bld}" _bld)
37 else (NOT ("${build}" STREQUAL "ALL_BUILDS"))
38 set (_bld "")
39 endif (NOT ("${build}" STREQUAL "ALL_BUILDS"))
40 foreach (_opt IN LISTS ARGN)
41 set (_var "CMAKE_${lang}_FLAGS${_bld}")
42 #message (STATUS "Adding \"${_opt}\" to \${${_var}}")
43 # remove it first
44 string (REPLACE "${_opt}" "" _without "${${_var}}")
45 string (STRIP "${_without}" _without)
46 # we need to strip this one as well, so they are comparable
47 string (STRIP "${${_var}}" _stripped)
48 # if it wasn't there, then add it at the end
49 if ("${_without}" STREQUAL "${_stripped}")
50 # don't add any extra spaces if no options yet are set
51 if (NOT ${_stripped} STREQUAL "")
52 set (${_var} "${_stripped} ${_opt}")
53 else (NOT ${_stripped} STREQUAL "")
54 set (${_var} "${_opt}")
55 endif (NOT ${_stripped} STREQUAL "")
56 set (${_var} "${${_var}}" PARENT_SCOPE)
57 endif ("${_without}" STREQUAL "${_stripped}")
58 endforeach (_opt)
59 endforeach (build)
60 endforeach (lang)
61endfunction (add_options lang build)
62
63# set varname to flag unless user has specified something that matches regex
64function (set_default_option varname flag regex)
65 if (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}"
66 AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}"
67 AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}")
68 set (${varname} ${flag} PARENT_SCOPE)
69 else (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}"
70 AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}"
71 AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}")
72 set (${varname} PARENT_SCOPE)
73 endif (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}"
74 AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}"
75 AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}")
76endfunction (set_default_option)
77
78# note: this must be called before project()
79macro (no_default_options)
80 # prevent the platform probe to set options
81 set (CMAKE_NOT_USING_CONFIG_FLAGS TRUE)
82endmacro (no_default_options)
diff --git a/project/cmake/scripts/common/generateversionedfiles.cmake b/project/cmake/scripts/common/generateversionedfiles.cmake
deleted file mode 100644
index ea1fad5..0000000
--- a/project/cmake/scripts/common/generateversionedfiles.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
1include(${CORE_SOURCE_DIR}/project/cmake/scripts/common/macros.cmake)
2
3core_find_versions()
4file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/xbmc.addon)
5file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/addons/kodi.guilib)
6configure_file(${CORE_SOURCE_DIR}/addons/xbmc.addon/addon.xml.in
7 ${CMAKE_BINARY_DIR}/addons/xbmc.addon/addon.xml @ONLY)
8configure_file(${CORE_SOURCE_DIR}/addons/kodi.guilib/addon.xml.in
9 ${CMAKE_BINARY_DIR}/addons/kodi.guilib/addon.xml @ONLY)
10configure_file(${CORE_SOURCE_DIR}/xbmc/CompileInfo.cpp.in
11 ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp @ONLY)
diff --git a/project/cmake/scripts/common/macros.cmake b/project/cmake/scripts/common/macros.cmake
deleted file mode 100644
index 0900740..0000000
--- a/project/cmake/scripts/common/macros.cmake
+++ /dev/null
@@ -1,383 +0,0 @@
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
20 if(NOT SOURCES)
21 message(STATUS "No sources added to ${name} skipping")
22 return()
23 endif()
24
25 add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
26 set_target_properties(${name} PROPERTIES PREFIX "")
27 if(NOT arg_NO_MAIN_DEPENDS)
28 set(core_DEPENDS ${name} ${core_DEPENDS} CACHE STRING "" FORCE)
29 endif()
30
31 # Add precompiled headers to Kodi main libraries
32 if(WIN32 AND "${CMAKE_CURRENT_LIST_DIR}" MATCHES "^${CORE_SOURCE_DIR}/xbmc")
33 add_precompiled_header(${name} pch.h ${CORE_SOURCE_DIR}/xbmc/win32/pch.cpp
34 PCH_TARGET kodi)
35 endif()
36
37 # IDE support
38 if(CMAKE_GENERATOR MATCHES "Xcode")
39 file(RELATIVE_PATH parentfolder ${CORE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..)
40 set_target_properties(${name} PROPERTIES FOLDER "${parentfolder}")
41 elseif(CMAKE_GENERATOR MATCHES "Visual Studio")
42 file(RELATIVE_PATH foldername ${CORE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
43 set_target_properties(${name} PROPERTIES FOLDER "${foldername}")
44 source_group(" " REGULAR_EXPRESSION ".*")
45 endif()
46endfunction()
47
48# Add a test library, and add sources to list for gtest integration macros
49function(core_add_test_library name)
50 core_add_library(${name} NO_MAIN_DEPENDS)
51 set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL 1)
52 foreach(src ${SOURCES})
53 set(test_sources ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${test_sources} CACHE STRING "" FORCE)
54 endforeach()
55 set(test_archives ${test_archives} ${name} CACHE STRING "" FORCE)
56endfunction()
57
58# Add a data file to installation list with a mirror in build tree
59# Arguments:
60# file full path to file to mirror
61# relative the relative base of file path in the build/install tree
62# Optional Arguments:
63# NO_INSTALL: exclude file from installation target
64# Implicit arguments:
65# CORE_SOURCE_DIR - root of source tree
66# On return:
67# Files is mirrored to the build tree and added to ${install_data}
68# (if NO_INSTALL is not given).
69function(copy_file_to_buildtree file relative)
70 cmake_parse_arguments(arg "NO_INSTALL" "" "" ${ARGN})
71 string(REPLACE "${relative}/" "" outfile ${file})
72 get_filename_component(outdir ${outfile} DIRECTORY)
73
74 if(NOT TARGET export-files)
75 file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
76 add_custom_target(export-files ALL COMMENT "Copying files into build tree"
77 COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
78 endif()
79 if(NOT ${CORE_SOURCE_DIR} MATCHES ${CMAKE_BINARY_DIR})
80 if(VERBOSE)
81 message(STATUS "copy_file_to_buildtree - copying file: ${file} -> ${CMAKE_BINARY_DIR}/${outfile}")
82 endif()
83 file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake
84 "file(COPY \"${file}\" DESTINATION \"${CMAKE_BINARY_DIR}/${outdir}\")\n")
85 endif()
86 if(NOT arg_NO_INSTALL)
87 list(APPEND install_data ${outfile})
88 set(install_data ${install_data} PARENT_SCOPE)
89 endif()
90endfunction()
91
92# Add data files to installation list with a mirror in build tree.
93# reads list of files to install from a given list of text files.
94# Arguments:
95# pattern globbing pattern for text files to read
96# Optional Arguments:
97# NO_INSTALL: exclude files from installation target
98# Implicit arguments:
99# CORE_SOURCE_DIR - root of source tree
100# On return:
101# Files are mirrored to the build tree and added to ${install_data}
102# (if NO_INSTALL is not given).
103function(copy_files_from_filelist_to_buildtree pattern)
104 # copies files listed in text files to the buildtree
105 # Input: [glob pattern: filepattern]
106 cmake_parse_arguments(arg "NO_INSTALL" "" "" ${ARGN})
107 list(APPEND pattern ${ARGN})
108 list(SORT pattern)
109 if(VERBOSE)
110 message(STATUS "copy_files_from_filelist_to_buildtree - got pattern: ${pattern}")
111 endif()
112 foreach(pat ${pattern})
113 file(GLOB filenames ${pat})
114 foreach(filename ${filenames})
115 string(STRIP ${filename} filename)
116 core_file_read_filtered(fstrings ${filename})
117 foreach(dir ${fstrings})
118 file(GLOB_RECURSE files RELATIVE ${CORE_SOURCE_DIR} ${CORE_SOURCE_DIR}/${dir})
119 foreach(file ${files})
120 if(arg_NO_INSTALL)
121 copy_file_to_buildtree(${CORE_SOURCE_DIR}/${file} ${CORE_SOURCE_DIR} NO_INSTALL)
122 else()
123 copy_file_to_buildtree(${CORE_SOURCE_DIR}/${file} ${CORE_SOURCE_DIR})
124 endif()
125 endforeach()
126 endforeach()
127 endforeach()
128 endforeach()
129 set(install_data ${install_data} PARENT_SCOPE)
130endfunction()
131
132# helper macro to set modified variables in parent scope
133macro(export_dep)
134 set(SYSTEM_INCLUDES ${SYSTEM_INCLUDES} PARENT_SCOPE)
135 set(DEPLIBS ${DEPLIBS} PARENT_SCOPE)
136 set(DEP_DEFINES ${DEP_DEFINES} PARENT_SCOPE)
137 set(${depup}_FOUND ${${depup}_FOUND} PARENT_SCOPE)
138 mark_as_advanced(${depup}_LIBRARIES)
139endmacro()
140
141# add a required dependency of main application
142# Arguments:
143# dep name of find rule for dependency, used uppercased for variable prefix
144# On return:
145# dependency added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
146function(core_require_dep dep)
147 find_package(${dep} REQUIRED)
148 string(TOUPPER ${dep} depup)
149 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
150 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
151 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
152 export_dep()
153endfunction()
154
155# add a required dyloaded dependency of main application
156# Arguments:
157# dep name of find rule for dependency, used uppercased for variable prefix
158# On return:
159# dependency added to ${SYSTEM_INCLUDES}, ${dep}_SONAME is set up
160function(core_require_dyload_dep dep)
161 find_package(${dep} REQUIRED)
162 string(TOUPPER ${dep} depup)
163 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
164 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
165 find_soname(${depup} REQUIRED)
166 export_dep()
167 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
168endfunction()
169
170# helper macro for optional deps
171macro(setup_enable_switch)
172 string(TOUPPER ${dep} depup)
173 if (ARGV1)
174 set(enable_switch ${ARGV1})
175 else()
176 set(enable_switch ENABLE_${depup})
177 endif()
178endmacro()
179
180# add an optional dependency of main application
181# Arguments:
182# dep name of find rule for dependency, used uppercased for variable prefix
183# On return:
184# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
185function(core_optional_dep dep)
186 setup_enable_switch()
187 if(${enable_switch})
188 find_package(${dep})
189 if(${depup}_FOUND)
190 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
191 list(APPEND DEPLIBS ${${depup}_LIBRARIES})
192 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
193 set(final_message ${final_message} "${depup} enabled: Yes" PARENT_SCOPE)
194 export_dep()
195 else()
196 set(final_message ${final_message} "${depup} enabled: No" PARENT_SCOPE)
197 endif()
198 endif()
199endfunction()
200
201# add an optional dyloaded dependency of main application
202# Arguments:
203# dep name of find rule for dependency, used uppercased for variable prefix
204# On return:
205# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEP_DEFINES}, ${dep}_SONAME is set up
206function(core_optional_dyload_dep dep)
207 setup_enable_switch()
208 if(${enable_switch})
209 find_package(${dep})
210 if(${depup}_FOUND)
211 list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
212 find_soname(${depup} REQUIRED)
213 list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
214 set(final_message ${final_message} "${depup} enabled: Yes" PARENT_SCOPE)
215 export_dep()
216 set(${depup}_SONAME ${${depup}_SONAME} PARENT_SCOPE)
217 endif()
218 endif()
219endfunction()
220
221function(core_file_read_filtered result filepattern)
222 # Reads STRINGS from text files
223 # with comments filtered out
224 # Result: [list: result]
225 # Input: [glob pattern: filepattern]
226 file(GLOB filenames ${filepattern})
227 list(SORT filenames)
228 foreach(filename ${filenames})
229 if(VERBOSE)
230 message(STATUS "core_file_read_filtered - filename: ${filename}")
231 endif()
232 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
233 foreach(fstring ${fstrings})
234 string(REGEX REPLACE "^(.*)#(.*)" "\\1" fstring ${fstring})
235 string(REGEX REPLACE "//.*" "" fstring ${fstring})
236 string(STRIP ${fstring} fstring)
237 list(APPEND filename_strings ${fstring})
238 endforeach()
239 endforeach()
240 set(${result} ${filename_strings} PARENT_SCOPE)
241endfunction()
242
243function(core_add_subdirs_from_filelist files)
244 # Adds subdirectories from a sorted list of files
245 # Input: [list: filenames] [bool: sort]
246 foreach(arg ${ARGN})
247 list(APPEND files ${arg})
248 endforeach()
249 list(SORT files)
250 if(VERBOSE)
251 message(STATUS "core_add_subdirs_from_filelist - got pattern: ${files}")
252 endif()
253 foreach(filename ${files})
254 string(STRIP ${filename} filename)
255 core_file_read_filtered(fstrings ${filename})
256 foreach(subdir ${fstrings})
257 STRING_SPLIT(subdir " " ${subdir})
258 list(GET subdir 0 subdir_src)
259 list(GET subdir -1 subdir_dest)
260 if(VERBOSE)
261 message(STATUS " core_add_subdirs_from_filelist - adding subdir: ${CORE_SOURCE_DIR}${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
262 endif()
263 add_subdirectory(${CORE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
264 endforeach()
265 endforeach()
266endfunction()
267
268macro(core_add_optional_subdirs_from_filelist pattern)
269 # Adds subdirectories from text files
270 # if the option(s) in the 3rd field are enabled
271 # Input: [glob pattern: filepattern]
272 foreach(arg ${ARGN})
273 list(APPEND pattern ${arg})
274 endforeach()
275 foreach(elem ${pattern})
276 string(STRIP ${elem} elem)
277 list(APPEND filepattern ${elem})
278 endforeach()
279
280 file(GLOB filenames ${filepattern})
281 list(SORT filenames)
282 if(VERBOSE)
283 message(STATUS "core_add_optional_subdirs_from_filelist - got pattern: ${filenames}")
284 endif()
285
286 foreach(filename ${filenames})
287 if(VERBOSE)
288 message(STATUS "core_add_optional_subdirs_from_filelist - reading file: ${filename}")
289 endif()
290 file(STRINGS ${filename} fstrings REGEX "^[^#//]")
291 foreach(line ${fstrings})
292 string(REPLACE " " ";" line "${line}")
293 list(GET line 0 subdir_src)
294 list(GET line 1 subdir_dest)
295 list(GET line 3 opts)
296 foreach(opt ${opts})
297 if(ENABLE_${opt})
298 if(VERBOSE)
299 message(STATUS " core_add_optional_subdirs_from_filelist - adding subdir: ${CORE_SOURCE_DIR}${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
300 endif()
301 add_subdirectory(${CORE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
302 else()
303 if(VERBOSE)
304 message(STATUS " core_add_optional_subdirs_from_filelist: OPTION ${opt} not enabled for ${subdir_src}, skipping subdir")
305 endif()
306 endif()
307 endforeach()
308 endforeach()
309 endforeach()
310endmacro()
311
312macro(today RESULT)
313 if (WIN32)
314 execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT})
315 string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
316 elseif(UNIX)
317 execute_process(COMMAND date -u +%F
318 OUTPUT_VARIABLE ${RESULT})
319 string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
320 else()
321 message(SEND_ERROR "date not implemented")
322 set(${RESULT} 000000)
323 endif()
324 string(REGEX REPLACE "(\r?\n)+$" "" ${RESULT} "${${RESULT}}")
325endmacro()
326
327function(core_find_git_rev)
328 find_package(Git)
329 if(GIT_FOUND AND EXISTS ${CORE_SOURCE_DIR}/.git)
330 execute_process(COMMAND ${GIT_EXECUTABLE} diff-files --ignore-submodules --quiet --
331 RESULT_VARIABLE status_code
332 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
333 if (NOT status_code)
334 execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --ignore-submodules --quiet HEAD --
335 RESULT_VARIABLE status_code
336 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
337 endif()
338 if (status_code)
339 execute_process(COMMAND ${GIT_EXECUTABLE} log -n 1 --pretty=format:"%h-dirty" HEAD
340 OUTPUT_VARIABLE HASH
341 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
342 string(SUBSTRING ${HASH} 1 13 HASH)
343 else()
344 execute_process(COMMAND ${GIT_EXECUTABLE} log -n 1 --pretty=format:"%h" HEAD
345 OUTPUT_VARIABLE HASH
346 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
347 string(SUBSTRING ${HASH} 1 7 HASH)
348 endif()
349 execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%cd" --date=short HEAD
350 OUTPUT_VARIABLE DATE
351 WORKING_DIRECTORY ${CORE_SOURCE_DIR})
352 string(SUBSTRING ${DATE} 1 10 DATE)
353 else()
354 today(DATE)
355 set(HASH "nogitfound")
356 endif()
357 string(REPLACE "-" "" DATE ${DATE})
358 set(GIT_REV "${DATE}-${HASH}")
359 if(GIT_REV)
360 set(APP_SCMID ${GIT_REV} PARENT_SCOPE)
361 endif()
362endfunction()
363
364macro(core_find_versions)
365 include(CMakeParseArguments)
366 core_file_read_filtered(version_list ${CORE_SOURCE_DIR}/version.txt)
367 string(REPLACE " " ";" version_list "${version_list}")
368 cmake_parse_arguments(APP "" "VERSION_MAJOR;VERSION_MINOR;VERSION_TAG;VERSION_CODE;ADDON_API;APP_NAME;COMPANY_NAME" "" ${version_list})
369
370 set(APP_NAME ${APP_APP_NAME}) # inconsistency in upstream
371 string(TOLOWER ${APP_APP_NAME} APP_NAME_LC)
372 set(COMPANY_NAME ${APP_COMPANY_NAME})
373 set(APP_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR})
374 if(APP_VERSION_TAG)
375 set(APP_VERSION ${APP_VERSION}-${APP_VERSION_TAG})
376 endif()
377 string(REPLACE "." "," FILE_VERSION ${APP_ADDON_API}.0)
378 string(TOLOWER ${APP_VERSION_TAG} APP_VERSION_TAG_LC)
379 file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h guilib_version REGEX "^.*GUILIB_API_VERSION (.*)$")
380 string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version ${guilib_version})
381 file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h guilib_version_min REGEX "^.*GUILIB_MIN_API_VERSION (.*)$")
382 string(REGEX REPLACE ".*\"(.*)\"" "\\1" guilib_version_min ${guilib_version_min})
383endmacro()
diff --git a/project/cmake/scripts/common/managestring.cmake b/project/cmake/scripts/common/managestring.cmake
deleted file mode 100644
index 7321f4c..0000000
--- a/project/cmake/scripts/common/managestring.cmake
+++ /dev/null
@@ -1,235 +0,0 @@
1# - Collection of String utility macros.
2# Defines the following macros:
3# STRING_TRIM(var str [NOUNQUOTE])
4# - Trim a string by removing the leading and trailing spaces,
5# just like STRING(STRIP ...) in CMake 2.6 and later.
6# This macro is needed as CMake 2.4 does not support STRING(STRIP ..)
7# This macro also remove quote and double quote marks around the string,
8# unless NOUNQUOTE is defined.
9# * Parameters:
10# + var: A variable that stores the result.
11# + str: A string.
12# + NOUNQUOTE: (Optional) do not remove the double quote mark around the string.
13#
14# STRING_UNQUOTE(var str)
15# - Remove double quote marks and quote marks around a string.
16# If the string is not quoted, then it returns an empty string.
17# * Parameters:
18# + var: A variable that stores the result.
19# + str: A string.
20#
21# STRING_JOIN(var delimiter str_list [str...])
22# - Concatenate strings, with delimiter inserted between strings.
23# * Parameters:
24# + var: A variable that stores the result.
25# + str_list: A list of string.
26# + str: (Optional) more string to be join.
27#
28# STRING_SPLIT(var delimiter str [NOESCAPE_SEMICOLON])
29# - Split a string into a list using a delimiter, which can be in 1 or more
30# characters long.
31# * Parameters:
32# + var: A variable that stores the result.
33# + delimiter: To separate a string.
34# + str: A string.
35# + NOESCAPE_SEMICOLON: (Optional) Do not escape semicolons.
36#
37
38IF(NOT DEFINED _MANAGE_STRING_CMAKE_)
39 SET(_MANAGE_STRING_CMAKE_ "DEFINED")
40
41 MACRO(STRING_TRIM var str)
42 SET(${var} "")
43 IF (NOT "${ARGN}" STREQUAL "NOUNQUOTE")
44 # Need not trim a quoted string.
45 STRING_UNQUOTE(_var "${str}")
46 IF(NOT _var STREQUAL "")
47 # String is quoted
48 SET(${var} "${_var}")
49 ENDIF(NOT _var STREQUAL "")
50 ENDIF(NOT "${ARGN}" STREQUAL "NOUNQUOTE")
51
52 IF(${var} STREQUAL "")
53 SET(_var_1 "${str}")
54 STRING(REGEX REPLACE "^[ \t\r\n]+" "" _var_2 "${str}" )
55 STRING(REGEX REPLACE "[ \t\r\n]+$" "" _var_3 "${_var_2}" )
56 SET(${var} "${_var_3}")
57 ENDIF(${var} STREQUAL "")
58 ENDMACRO(STRING_TRIM var str)
59
60 # Internal macro
61 # Variable cannot be escaped here, as variable is already substituted
62 # at the time it passes to this macro.
63 MACRO(STRING_ESCAPE var str)
64 # ';' and '\' are tricky, need to be encoded.
65 # '#' => '#H'
66 # '\' => '#B'
67 # ';' => '#S'
68 SET(_NOESCAPE_SEMICOLON "")
69 SET(_NOESCAPE_HASH "")
70
71 FOREACH(_arg ${ARGN})
72 IF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
73 SET(_NOESCAPE_SEMICOLON "NOESCAPE_SEMICOLON")
74 ELSEIF(${_arg} STREQUAL "NOESCAPE_HASH")
75 SET(_NOESCAPE_HASH "NOESCAPE_HASH")
76 ENDIF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
77 ENDFOREACH(_arg)
78
79 IF(_NOESCAPE_HASH STREQUAL "")
80 STRING(REGEX REPLACE "#" "#H" _ret "${str}")
81 ELSE(_NOESCAPE_HASH STREQUAL "")
82 SET(_ret "${str}")
83 ENDIF(_NOESCAPE_HASH STREQUAL "")
84
85 STRING(REGEX REPLACE "\\\\" "#B" _ret "${_ret}")
86 IF(_NOESCAPE_SEMICOLON STREQUAL "")
87 STRING(REGEX REPLACE ";" "#S" _ret "${_ret}")
88 ENDIF(_NOESCAPE_SEMICOLON STREQUAL "")
89 SET(${var} "${_ret}")
90 ENDMACRO(STRING_ESCAPE var str)
91
92 MACRO(STRING_UNESCAPE var str)
93 # '#B' => '\'
94 # '#H' => '#'
95 # '#D' => '$'
96 # '#S' => ';'
97 SET(_ESCAPE_VARIABLE "")
98 SET(_NOESCAPE_SEMICOLON "")
99 SET(_ret "${str}")
100 FOREACH(_arg ${ARGN})
101 IF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
102 SET(_NOESCAPE_SEMICOLON "NOESCAPE_SEMICOLON")
103 ELSEIF(${_arg} STREQUAL "ESCAPE_VARIABLE")
104 SET(_ESCAPE_VARIABLE "ESCAPE_VARIABLE")
105 STRING(REGEX REPLACE "#D" "$" _ret "${_ret}")
106 ENDIF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
107 ENDFOREACH(_arg)
108
109 STRING(REGEX REPLACE "#B" "\\\\" _ret "${_ret}")
110 IF(_NOESCAPE_SEMICOLON STREQUAL "")
111 # ';' => '#S'
112 STRING(REGEX REPLACE "#S" "\\\\;" _ret "${_ret}")
113 ELSE(_NOESCAPE_SEMICOLON STREQUAL "")
114 STRING(REGEX REPLACE "#S" ";" _ret "${_ret}")
115 ENDIF(_NOESCAPE_SEMICOLON STREQUAL "")
116
117 IF(NOT _ESCAPE_VARIABLE STREQUAL "")
118 # '#D' => '$'
119 STRING(REGEX REPLACE "#D" "$" _ret "${_ret}")
120 ENDIF(NOT _ESCAPE_VARIABLE STREQUAL "")
121 STRING(REGEX REPLACE "#H" "#" _ret "${_ret}")
122 SET(${var} "${_ret}")
123 ENDMACRO(STRING_UNESCAPE var str)
124
125
126 MACRO(STRING_UNQUOTE var str)
127 STRING_ESCAPE(_ret "${str}" ${ARGN})
128 IF(_ret MATCHES "^[ \t\r\n]+")
129 STRING(REGEX REPLACE "^[ \t\r\n]+" "" _ret "${_ret}")
130 ENDIF(_ret MATCHES "^[ \t\r\n]+")
131 IF(_ret MATCHES "^\"")
132 # Double quote
133 STRING(REGEX REPLACE "\"\(.*\)\"[ \t\r\n]*$" "\\1" _ret "${_ret}")
134 ELSEIF(_ret MATCHES "^'")
135 # Single quote
136 STRING(REGEX REPLACE "'\(.*\)'[ \t\r\n]*$" "\\1" _ret "${_ret}")
137 ELSE(_ret MATCHES "^\"")
138 SET(_ret "")
139 ENDIF(_ret MATCHES "^\"")
140
141 # Unencoding
142 STRING_UNESCAPE(${var} "${_ret}" ${ARGN})
143 ENDMACRO(STRING_UNQUOTE var str)
144
145 MACRO(STRING_JOIN var delimiter str_list)
146 SET(_ret "")
147 FOREACH(_str ${str_list})
148 IF(_ret STREQUAL "")
149 SET(_ret "${_str}")
150 ELSE(_ret STREQUAL "")
151 SET(_ret "${_ret}${delimiter}${_str}")
152 ENDIF(_ret STREQUAL "")
153 ENDFOREACH(_str ${str_list})
154
155 FOREACH(_str ${ARGN})
156 IF(_ret STREQUAL "")
157 SET(_ret "${_str}")
158 ELSE(_ret STREQUAL "")
159 SET(_ret "${_ret}${delimiter}${_str}")
160 ENDIF(_ret STREQUAL "")
161 ENDFOREACH(_str ${str_list})
162 SET(${var} "${_ret}")
163 ENDMACRO(STRING_JOIN var delimiter str_list)
164
165 MACRO(STRING_SPLIT var delimiter str)
166 SET(_max_tokens "")
167 SET(_NOESCAPE_SEMICOLON "")
168 SET(_ESCAPE_VARIABLE "")
169 FOREACH(_arg ${ARGN})
170 IF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
171 SET(_NOESCAPE_SEMICOLON "NOESCAPE_SEMICOLON")
172 ELSEIF(${_arg} STREQUAL "ESCAPE_VARIABLE")
173 SET(_ESCAPE_VARIABLE "ESCAPE_VARIABLE")
174 ELSE(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
175 SET(_max_tokens ${_arg})
176 ENDIF(${_arg} STREQUAL "NOESCAPE_SEMICOLON")
177 ENDFOREACH(_arg)
178
179 IF(NOT _max_tokens)
180 SET(_max_tokens -1)
181 ENDIF(NOT _max_tokens)
182
183 STRING_ESCAPE(_str "${str}" ${_NOESCAPE_SEMICOLON} ${_ESCAPE_VARIABLE})
184 STRING_ESCAPE(_delimiter "${delimiter}" ${_NOESCAPE_SEMICOLON} ${_ESCAPE_VARIABLE})
185
186 SET(_str_list "")
187 SET(_token_count 0)
188 STRING(LENGTH "${_delimiter}" _de_len)
189
190 WHILE(NOT _token_count EQUAL _max_tokens)
191 MATH(EXPR _token_count ${_token_count}+1)
192 IF(_token_count EQUAL _max_tokens)
193 # Last token, no need splitting
194 SET(_str_list ${_str_list} "${_str}")
195 ELSE(_token_count EQUAL _max_tokens)
196 # in case encoded characters are delimiters
197 STRING(LENGTH "${_str}" _str_len)
198 SET(_index 0)
199 SET(_token "")
200 SET(_str_remain "")
201 MATH(EXPR _str_end ${_str_len}-${_de_len}+1)
202 SET(_bound "k")
203 WHILE(_index LESS _str_end)
204 STRING(SUBSTRING "${_str}" ${_index} ${_de_len} _str_cursor)
205 IF(_str_cursor STREQUAL _delimiter)
206 # Get the token
207 STRING(SUBSTRING "${_str}" 0 ${_index} _token)
208 # Get the rest
209 MATH(EXPR _rest_index ${_index}+${_de_len})
210 MATH(EXPR _rest_len ${_str_len}-${_index}-${_de_len})
211 STRING(SUBSTRING "${_str}" ${_rest_index} ${_rest_len} _str_remain)
212 SET(_index ${_str_end})
213 ELSE(_str_cursor STREQUAL _delimiter)
214 MATH(EXPR _index ${_index}+1)
215 ENDIF(_str_cursor STREQUAL _delimiter)
216 ENDWHILE(_index LESS _str_end)
217
218 IF(_str_remain STREQUAL "")
219 # Meaning: end of string
220 LIST(APPEND _str_list "${_str}")
221 SET(_max_tokens ${_token_count})
222 ELSE(_str_remain STREQUAL "")
223 LIST(APPEND _str_list "${_token}")
224 SET(_str "${_str_remain}")
225 ENDIF(_str_remain STREQUAL "")
226 ENDIF(_token_count EQUAL _max_tokens)
227 ENDWHILE(NOT _token_count EQUAL _max_tokens)
228
229
230 # Unencoding
231 STRING_UNESCAPE(${var} "${_str_list}" ${_NOESCAPE_SEMICOLON} ${_ESCAPE_VARIABLE})
232 ENDMACRO(STRING_SPLIT var delimiter str)
233
234ENDIF(NOT DEFINED _MANAGE_STRING_CMAKE_)
235
diff --git a/project/cmake/scripts/common/pathsetup.cmake b/project/cmake/scripts/common/pathsetup.cmake
deleted file mode 100644
index 54b352d..0000000
--- a/project/cmake/scripts/common/pathsetup.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
1# This script configures installation paths
2
3include(${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/pathsetup.cmake)