summaryrefslogtreecommitdiffstats
path: root/cmake/scripts
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /cmake/scripts
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--cmake/scripts/android/ArchSetup.cmake45
-rw-r--r--cmake/scripts/android/Install.cmake174
l---------cmake/scripts/android/Macros.cmake1
-rw-r--r--cmake/scripts/android/PathSetup.cmake33
-rw-r--r--cmake/scripts/common/AddOptions.cmake78
-rw-r--r--cmake/scripts/common/AddonHelpers.cmake437
-rw-r--r--cmake/scripts/common/AddonHelpers.dox59
-rw-r--r--cmake/scripts/common/ArchSetup.cmake201
-rw-r--r--cmake/scripts/common/CMakeHelpers.cmake54
-rw-r--r--cmake/scripts/common/CheckCommits.cmake75
-rw-r--r--cmake/scripts/common/CheckTargetPlatform.cmake70
-rw-r--r--cmake/scripts/common/CompilerSettings.cmake5
-rw-r--r--cmake/scripts/common/DependencyOptions.cmake23
-rw-r--r--cmake/scripts/common/GenerateVersionedFiles.cmake35
-rw-r--r--cmake/scripts/common/GeneratorSetup.cmake49
-rw-r--r--cmake/scripts/common/HandleDepends.cmake301
-rw-r--r--cmake/scripts/common/Macros.cmake789
-rw-r--r--cmake/scripts/common/ModuleHelpers.cmake424
-rw-r--r--cmake/scripts/common/PathSetup.cmake13
-rw-r--r--cmake/scripts/common/Platform.cmake57
-rw-r--r--cmake/scripts/common/PrepareEnv.cmake107
-rw-r--r--cmake/scripts/common/ProjectMacros.cmake89
-rw-r--r--cmake/scripts/common/StaticAnalysis.cmake39
-rw-r--r--cmake/scripts/common/Uninstall.cmake58
-rw-r--r--cmake/scripts/darwin/Macros.cmake8
-rw-r--r--cmake/scripts/darwin_embedded/ArchSetup.cmake68
-rw-r--r--cmake/scripts/darwin_embedded/ExtraTargets.cmake32
-rw-r--r--cmake/scripts/darwin_embedded/Install.cmake130
-rw-r--r--cmake/scripts/darwin_embedded/Macros.cmake119
-rw-r--r--cmake/scripts/darwin_embedded/PathSetup.cmake7
-rw-r--r--cmake/scripts/freebsd/ArchSetup.cmake46
-rw-r--r--cmake/scripts/freebsd/ExtraTargets.cmake1
l---------cmake/scripts/freebsd/Install.cmake1
-rw-r--r--cmake/scripts/freebsd/Macros.cmake95
l---------cmake/scripts/freebsd/PathSetup.cmake1
-rw-r--r--cmake/scripts/linux/ArchSetup.cmake207
-rw-r--r--cmake/scripts/linux/CodeCoverage.cmake97
-rw-r--r--cmake/scripts/linux/ExtraTargets.cmake32
-rw-r--r--cmake/scripts/linux/Install.cmake329
-rw-r--r--cmake/scripts/linux/Linkers.txt4
-rw-r--r--cmake/scripts/linux/Macros.cmake95
-rw-r--r--cmake/scripts/linux/PathSetup.cmake40
-rw-r--r--cmake/scripts/osx/ArchSetup.cmake56
-rw-r--r--cmake/scripts/osx/ExtraTargets.cmake3
-rw-r--r--cmake/scripts/osx/Install.cmake73
-rw-r--r--cmake/scripts/osx/Macros.cmake119
-rw-r--r--cmake/scripts/osx/PathSetup.cmake32
-rw-r--r--cmake/scripts/windows/ArchSetup.cmake128
-rw-r--r--cmake/scripts/windows/CFlagOverrides.cmake10
-rw-r--r--cmake/scripts/windows/CXXFlagOverrides.cmake10
-rw-r--r--cmake/scripts/windows/Install.cmake0
-rw-r--r--cmake/scripts/windows/Macros.cmake66
-rw-r--r--cmake/scripts/windows/PathSetup.cmake34
-rw-r--r--cmake/scripts/windows/tools/patch.cmake50
-rw-r--r--cmake/scripts/windowsstore/ArchSetup.cmake127
-rw-r--r--cmake/scripts/windowsstore/CFlagOverrides.cmake17
-rw-r--r--cmake/scripts/windowsstore/CXXFlagOverrides.cmake17
-rw-r--r--cmake/scripts/windowsstore/Install.cmake10
-rw-r--r--cmake/scripts/windowsstore/Macros.cmake182
-rw-r--r--cmake/scripts/windowsstore/PathSetup.cmake34
-rw-r--r--cmake/scripts/windowsstore/tools/patch.cmake50
61 files changed, 5546 insertions, 0 deletions
diff --git a/cmake/scripts/android/ArchSetup.cmake b/cmake/scripts/android/ArchSetup.cmake
new file mode 100644
index 0000000..2fe85fe
--- /dev/null
+++ b/cmake/scripts/android/ArchSetup.cmake
@@ -0,0 +1,45 @@
+if(NOT CMAKE_TOOLCHAIN_FILE)
+ message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE required for android. See ${CMAKE_SOURCE_DIR}/cmake/README.md")
+endif()
+
+set(ARCH_DEFINES -DTARGET_POSIX -DTARGET_LINUX -DTARGET_ANDROID)
+set(SYSTEM_DEFINES -D__STDC_CONSTANT_MACROS -D_LARGEFILE64_SOURCE
+ -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64=1)
+
+# Main cpp
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/android/activity/XBMCApp.cpp)
+
+set(PLATFORM_DIR platform/linux)
+set(PLATFORMDEFS_DIR platform/posix)
+if(WITH_ARCH)
+ set(ARCH ${WITH_ARCH})
+else()
+ if(CPU STREQUAL armeabi-v7a)
+ set(ARCH arm)
+ set(NEON True)
+ set(NEON_FLAGS "-mfpu=neon")
+ if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
+ set(NEON_FLAGS "${NEON_FLAGS} -mvectorize-with-neon-quad")
+ endif()
+ elseif(CPU STREQUAL arm64-v8a)
+ set(ARCH aarch64)
+ set(NEON True)
+ elseif(CPU STREQUAL i686)
+ set(ARCH i486-linux)
+ set(NEON False)
+ elseif(CPU STREQUAL x86_64)
+ set(ARCH x86_64)
+ set(NEON False)
+ else()
+ message(SEND_ERROR "Unknown CPU: ${CPU}")
+ endif()
+endif()
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_ZEROCONF)
+
+set(ENABLE_X11 OFF CACHE BOOL "" FORCE)
+set(ENABLE_OPTICAL OFF CACHE BOOL "" FORCE)
+set(ENABLE_MDNS OFF CACHE BOOL "" FORCE)
+
+list(APPEND DEPLIBS android log jnigraphics mediandk)
diff --git a/cmake/scripts/android/Install.cmake b/cmake/scripts/android/Install.cmake
new file mode 100644
index 0000000..f39b858
--- /dev/null
+++ b/cmake/scripts/android/Install.cmake
@@ -0,0 +1,174 @@
+# Android packaging
+
+if(CMAKE_BUILD_TYPE STREQUAL Debug)
+ set(ANDROID_DEBUGGABLE true)
+else()
+ set(ANDROID_DEBUGGABLE false)
+endif()
+
+# Configure files into packaging environment.
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/Makefile.in
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/Makefile @ONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/gradle.properties
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/gradle.properties COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/build.gradle
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/build.gradle COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/gradlew
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/gradlew COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/settings.gradle
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/settings.gradle COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/gradle/wrapper/gradle-wrapper.jar
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/gradle/wrapper/gradle-wrapper.jar COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/gradle/wrapper/gradle-wrapper.properties
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/gradle/wrapper/gradle-wrapper.properties COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/xbmc/jni/Android.mk
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/xbmc/jni/Android.mk COPYONLY)
+file(WRITE ${CMAKE_BINARY_DIR}/tools/depends/Makefile.include
+ "$(PREFIX)/lib/${APP_NAME_LC}/lib${APP_NAME_LC}.so: ;\n")
+
+string(REPLACE "." ";" APP_VERSION_CODE_LIST ${APP_VERSION_CODE})
+list(GET APP_VERSION_CODE_LIST 0 major)
+list(GET APP_VERSION_CODE_LIST 1 minor)
+list(GET APP_VERSION_CODE_LIST 2 patch)
+unset(APP_VERSION_CODE_LIST)
+math(EXPR APP_VERSION_CODE_ANDROID "(${major} * 100 + ${minor}) * 1000 + ${patch}")
+unset(major)
+unset(minor)
+if(ARCH STREQUAL aarch64 AND patch LESS 999)
+ math(EXPR APP_VERSION_CODE_ANDROID "${APP_VERSION_CODE_ANDROID} + 1")
+endif()
+unset(patch)
+
+set(package_files strings.xml
+ colors.xml
+ searchable.xml
+ AndroidManifest.xml
+ build.gradle
+ src/Splash.java
+ src/Main.java
+ src/XBMCBroadcastReceiver.java
+ src/XBMCInputDeviceListener.java
+ src/XBMCJsonRPC.java
+ src/XBMCMainView.java
+ src/XBMCMediaSession.java
+ src/XBMCRecommendationBuilder.java
+ src/XBMCSearchableActivity.java
+ src/XBMCSettingsContentObserver.java
+ src/XBMCProperties.java
+ src/XBMCVideoView.java
+ src/XBMCFile.java
+ src/XBMCURIUtils.java
+ src/channels/SyncChannelJobService.java
+ src/channels/SyncProgramsJobService.java
+ src/channels/model/XBMCDatabase.java
+ src/channels/model/Subscription.java
+ src/channels/util/SharedPreferencesHelper.java
+ src/channels/util/TvUtil.java
+ src/interfaces/XBMCAudioManagerOnAudioFocusChangeListener.java
+ src/interfaces/XBMCSurfaceTextureOnFrameAvailableListener.java
+ src/interfaces/XBMCNsdManagerResolveListener.java
+ src/interfaces/XBMCNsdManagerRegistrationListener.java
+ src/interfaces/XBMCNsdManagerDiscoveryListener.java
+ src/interfaces/XBMCMediaDrmOnEventListener.java
+ src/interfaces/XBMCDisplayManagerDisplayListener.java
+ src/interfaces/XBMCSpeechRecognitionListener.java
+ src/model/TVEpisode.java
+ src/model/Movie.java
+ src/model/TVShow.java
+ src/model/File.java
+ src/model/Album.java
+ src/model/Song.java
+ src/model/MusicVideo.java
+ src/model/Media.java
+ src/content/XBMCFileContentProvider.java
+ src/content/XBMCMediaContentProvider.java
+ src/content/XBMCContentProvider.java
+ src/content/XBMCYTDLContentProvider.java
+ )
+foreach(file IN LISTS package_files)
+ configure_file(${CMAKE_SOURCE_DIR}/tools/android/packaging/xbmc/${file}.in
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/xbmc/${file} @ONLY)
+endforeach()
+
+# Copy files to the location expected by the Android packaging scripts.
+add_custom_target(bundle
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/tools/android/packaging/media
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/media
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/tools/android/packaging/xbmc/res
+ ${CMAKE_BINARY_DIR}/tools/android/packaging/xbmc/res
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/lib/python${PYTHON_VERSION} ${libdir}/python${PYTHON_VERSION}
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/share/${APP_NAME_LC} ${datadir}/${APP_NAME_LC}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${APP_NAME_LC}>
+ ${libdir}/${APP_NAME_LC}/$<TARGET_FILE_NAME:${APP_NAME_LC}>)
+add_dependencies(bundle ${APP_NAME_LC})
+
+# This function is used to prepare a prefix expected by the Android packaging
+# scripts. It creates a bundle_files command that is added to the bundle target.
+function(add_bundle_file file destination relative)
+ if(NOT TARGET bundle_files)
+ file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/BundleFiles.cmake)
+ add_custom_target(bundle_files COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/BundleFiles.cmake)
+ add_dependencies(bundle bundle_files)
+ add_dependencies(bundle_files ${APP_NAME_LC})
+ endif()
+
+ string(REPLACE "${relative}/" "" outfile ${file})
+ get_filename_component(file ${file} REALPATH)
+ get_filename_component(outdir ${outfile} DIRECTORY)
+ file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/BundleFiles.cmake
+ "file(COPY \"${file}\" DESTINATION \"${destination}/${outdir}\")\n")
+ if(file MATCHES "\\.so\\..+$")
+ get_filename_component(srcfile "${file}" NAME)
+ string(REGEX REPLACE "\\.so\\..+$" "\.so" destfile ${srcfile})
+ file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/BundleFiles.cmake
+ "file(RENAME \"${destination}/${outdir}/${srcfile}\" \"${destination}/${outdir}/${destfile}\")\n")
+ endif()
+endfunction()
+
+# Copy files into prefix
+foreach(file IN LISTS XBT_FILES install_data)
+ string(REPLACE "${CMAKE_BINARY_DIR}/" "" file ${file})
+ add_bundle_file(${CMAKE_BINARY_DIR}/${file} ${datarootdir}/${APP_NAME_LC} ${CMAKE_BINARY_DIR})
+endforeach()
+
+foreach(library IN LISTS LIBRARY_FILES)
+ add_bundle_file(${library} ${libdir}/${APP_NAME_LC} ${CMAKE_BINARY_DIR})
+endforeach()
+
+foreach(lib IN LISTS required_dyload dyload_optional ITEMS Shairplay)
+ string(TOUPPER ${lib} lib_up)
+ set(lib_so ${${lib_up}_SONAME})
+ if(lib_so AND EXISTS ${DEPENDS_PATH}/lib/${lib_so})
+ add_bundle_file(${DEPENDS_PATH}/lib/${lib_so} ${libdir} "")
+ endif()
+endforeach()
+add_bundle_file(${ASS_LIBRARY} ${libdir} "")
+add_bundle_file(${SHAIRPLAY_LIBRARY} ${libdir} "")
+add_bundle_file(${SMBCLIENT_LIBRARY} ${libdir} "")
+
+# Main targets from Makefile.in
+if(CPU MATCHES i686)
+ set(CPU x86)
+endif()
+foreach(target apk apk-clean)
+ add_custom_target(${target}
+ COMMAND env PATH=${NATIVEPREFIX}/bin:$ENV{PATH} ${CMAKE_MAKE_PROGRAM} -j1
+ -C ${CMAKE_BINARY_DIR}/tools/android/packaging
+ CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
+ CC=${CMAKE_C_COMPILER}
+ CPU=${CPU}
+ HOST=${HOST}
+ TOOLCHAIN=${TOOLCHAIN}
+ PREFIX=${prefix}
+ DEPENDS_PATH=${DEPENDS_PATH}
+ NDKROOT=${NDKROOT}
+ SDKROOT=${SDKROOT}
+ STRIP=${CMAKE_STRIP}
+ ${target}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tools/android/packaging
+ VERBATIM
+ )
+ if(NOT target STREQUAL apk-clean)
+ add_dependencies(${target} bundle)
+ endif()
+endforeach()
diff --git a/cmake/scripts/android/Macros.cmake b/cmake/scripts/android/Macros.cmake
new file mode 120000
index 0000000..2fdbb25
--- /dev/null
+++ b/cmake/scripts/android/Macros.cmake
@@ -0,0 +1 @@
+../linux/Macros.cmake \ No newline at end of file
diff --git a/cmake/scripts/android/PathSetup.cmake b/cmake/scripts/android/PathSetup.cmake
new file mode 100644
index 0000000..6115781
--- /dev/null
+++ b/cmake/scripts/android/PathSetup.cmake
@@ -0,0 +1,33 @@
+if(NOT prefix)
+ set(prefix ${DEPENDS_PATH})
+endif()
+set(CMAKE_INSTALL_PREFIX ${prefix})
+if(NOT exec_prefix)
+ set(exec_prefix ${prefix})
+endif()
+if(NOT libdir)
+ set(libdir ${prefix}/lib)
+endif()
+if(NOT bindir)
+ set(bindir ${prefix}/bin)
+endif()
+if(NOT includedir)
+ set(includedir ${prefix}/include)
+endif()
+if(NOT datarootdir)
+ set(datarootdir ${prefix}/share)
+endif()
+if(NOT datadir)
+ set(datadir ${datarootdir})
+endif()
+
+list(APPEND final_message "-- PATH config --")
+list(APPEND final_message "Prefix: ${prefix}")
+list(APPEND final_message "Libdir: ${libdir}")
+list(APPEND final_message "Bindir: ${bindir}")
+list(APPEND final_message "Includedir: ${includedir}")
+list(APPEND final_message "Datarootdir: ${datarootdir}")
+list(APPEND final_message "Datadir: ${datadir}")
+
+set(PATH_DEFINES -DBIN_INSTALL_PATH=\"${libdir}/${APP_NAME_LC}\"
+ -DINSTALL_PATH=\"${datarootdir}/${APP_NAME_LC}\")
diff --git a/cmake/scripts/common/AddOptions.cmake b/cmake/scripts/common/AddOptions.cmake
new file mode 100644
index 0000000..96837c1
--- /dev/null
+++ b/cmake/scripts/common/AddOptions.cmake
@@ -0,0 +1,78 @@
+# - Add options without repeating them on the command line
+#
+# Synopsis:
+#
+# add_options (lang build opts)
+#
+# where:
+#
+# lang Name of the language whose compiler should receive the
+# options, e.g. CXX. If a comma-separated list is received
+# then the option is added for all those languages. Use the
+# special value ALL_LANGUAGES for these languages: CXX, C
+# and Fortran
+#
+# build Kind of build to which this options should apply,
+# such as DEBUG and RELEASE. This can also be a comma-
+# separated list. Use the special value ALL_BUILDS to apply
+# to all builds.
+#
+# opts List of options to add. Each should be quoted.
+#
+# Example:
+#
+# add_options (CXX RELEASE "-O3" "-DNDEBUG" "-Wall")
+
+function(add_options langs builds)
+ # special handling of empty language specification
+ if("${langs}" STREQUAL "ALL_LANGUAGES")
+ set(langs CXX C Fortran)
+ endif()
+ foreach(lang IN LISTS langs)
+ # prepend underscore if necessary
+ foreach(build IN LISTS builds)
+ if(NOT ("${build}" STREQUAL "ALL_BUILDS"))
+ set(_bld "_${build}")
+ string(TOUPPER "${_bld}" _bld)
+ else()
+ set(_bld "")
+ endif()
+ foreach(_opt IN LISTS ARGN)
+ set(_var "CMAKE_${lang}_FLAGS${_bld}")
+ #message(STATUS "Adding \"${_opt}\" to \${${_var}}")
+ # remove it first
+ string(REPLACE "${_opt}" "" _without "${${_var}}")
+ string(STRIP "${_without}" _without)
+ # we need to strip this one as well, so they are comparable
+ string(STRIP "${${_var}}" _stripped)
+ # if it wasn't there, then add it at the end
+ if("${_without}" STREQUAL "${_stripped}")
+ # don't add any extra spaces if no options yet are set
+ if(NOT ${_stripped} STREQUAL "")
+ set(${_var} "${_stripped} ${_opt}")
+ else()
+ set(${_var} "${_opt}")
+ endif()
+ set(${_var} "${${_var}}" PARENT_SCOPE)
+ endif()
+ endforeach()
+ endforeach()
+ endforeach()
+endfunction()
+
+# set varname to flag unless user has specified something that matches regex
+function(set_default_option varname flag regex)
+ if(NOT "$ENV{CXXFLAGS}" MATCHES "${regex}"
+ AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}"
+ AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}")
+ set(${varname} ${flag} PARENT_SCOPE)
+ else()
+ set(${varname} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# note: this must be called before project()
+macro(no_default_options)
+ # prevent the platform probe to set options
+ set(CMAKE_NOT_USING_CONFIG_FLAGS TRUE)
+endmacro()
diff --git a/cmake/scripts/common/AddonHelpers.cmake b/cmake/scripts/common/AddonHelpers.cmake
new file mode 100644
index 0000000..c541ad7
--- /dev/null
+++ b/cmake/scripts/common/AddonHelpers.cmake
@@ -0,0 +1,437 @@
+# Workaround for the fact that cpack's filenames are not customizable.
+# Each add-on is added as a separate component to facilitate zip/tgz packaging.
+# The filenames are always of the form basename-component, which is
+# incompatible with the addonid-version scheme we want. This hack renames
+# the files from the file names generated by the 'package' target.
+# Sadly we cannot extend the 'package' target, as it is a builtin target, see
+# http://public.kitware.com/Bug/view.php?id=8438
+# Thus, we have to add an 'addon-package' target.
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ add_custom_target(addon-package DEPENDS PACKAGE)
+else()
+ add_custom_target(addon-package
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package)
+endif()
+
+macro(add_cpack_workaround target version ext)
+ if(NOT PACKAGE_DIR)
+ set(PACKAGE_DIR "${CMAKE_INSTALL_PREFIX}/zips")
+ endif()
+
+ add_custom_command(TARGET addon-package POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${PACKAGE_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CPACK_PACKAGE_DIRECTORY}/addon-${target}-${version}-${PLATFORM_TAG}.${ext} ${PACKAGE_DIR}/${target}+${PLATFORM_TAG}/${target}-${version}.${ext})
+endmacro()
+
+# Grab the version from a given add-on's addon.xml
+macro (addon_version dir prefix)
+ if(EXISTS ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in)
+ file(READ ${PROJECT_SOURCE_DIR}/${dir}/addon.xml.in ADDONXML)
+ else()
+ file(READ ${dir}/addon.xml ADDONXML)
+ endif()
+
+ string(REGEX MATCH "<addon[^>]*version.?=.?.[0-9\\.]+" VERSION_STRING ${ADDONXML})
+ string(REGEX REPLACE ".*version=.([0-9\\.]+).*" "\\1" ${prefix}_VERSION ${VERSION_STRING})
+ message(STATUS ${prefix}_VERSION=${${prefix}_VERSION})
+endmacro()
+
+# Build, link and optionally package an add-on
+macro (build_addon target prefix libs)
+ addon_version(${target} ${prefix})
+
+ # Below comes the generation of a list with used sources where the includes to
+ # kodi's headers becomes checked.
+ # This goes the following steps to identify them:
+ # 1. Check headers are at own depended on addon
+ # - If so, it is checked whether the whole folder is already inserted, if
+ # not, it is added.
+ # 2. If headers are not defined independently and there is more as one source
+ # file.
+ # - If yes, it is checked whether the headers with the sources together
+ # - In case no headers are inserted and more than one source file exists,
+ # the whole addon folder is searched for headers.
+ # 3. As a last step, the actual source files are checked.
+ if(${prefix}_SOURCES)
+ # Read used headers from addon, needed to identitfy used kodi addon interface headers
+ if(${prefix}_HEADERS)
+ # Add the used header files defined with CMakeLists.txt from addon itself
+ string(FIND "${${prefix}_HEADERS}" "${PROJECT_SOURCE_DIR}" position)
+ if(position GREATER -1)
+ # include path name already complete
+ list(APPEND USED_SOURCES ${${prefix}_HEADERS})
+ else()
+ # add the complete include path to begin
+ foreach(hdr_file ${${prefix}_HEADERS})
+ list(APPEND USED_SOURCES ${PROJECT_SOURCE_DIR}/${hdr_file})
+ endforeach()
+ endif()
+ else()
+ list(LENGTH ${prefix}_SOURCES _length)
+ if(${_length} GREATER 1)
+ string(REGEX MATCHALL "[.](h)" _length ${${prefix}_SOURCES}})
+ if(NOT _length)
+ file(GLOB_RECURSE USED_SOURCES ${PROJECT_SOURCE_DIR}/*.h*)
+ if(USED_SOURCES)
+ message(AUTHOR_WARNING "Header files not defined in your CMakeLists.txt. Please consider defining ${prefix}_HEADERS as list of all headers used by this addon. Falling back to recursive scan for *.h.")
+ endif()
+ endif()
+ endif()
+ endif()
+
+ # Add the used source files defined with CMakeLists.txt from addon itself
+ string(FIND "${${prefix}_SOURCES}" "${PROJECT_SOURCE_DIR}" position)
+ if(position GREATER -1)
+ # include path name already complete
+ list(APPEND USED_SOURCES ${${prefix}_SOURCES})
+ else()
+ # add the complete include path to begin
+ foreach(src_file ${${prefix}_SOURCES})
+ list(APPEND USED_SOURCES ${PROJECT_SOURCE_DIR}/${src_file})
+ endforeach()
+ endif()
+
+ message(STATUS "Addon dependency check ...")
+ # Set defines used in addon.xml.in and read from versions.h to set add-on
+ # version parts automatically
+ file(STRINGS ${KODI_INCLUDE_DIR}/versions.h BIN_ADDON_PARTS)
+ foreach(loop_var ${BIN_ADDON_PARTS})
+ # Only pass strings with "#define ADDON_" from versions.h
+ if(loop_var MATCHES "#define ADDON_")
+ string(REGEX REPLACE "\\\n" " " loop_var ${loop_var}) # remove header line breaks
+ string(REGEX REPLACE "#define " "" loop_var ${loop_var}) # remove the #define name from string
+ string(REGEX MATCHALL "[//a-zA-Z0-9._-]+" loop_var "${loop_var}") # separate the define values to a list
+
+ # Get the definition name
+ list(GET loop_var 0 include_name)
+ # Check definition are depends who is a bigger list
+ if("${include_name}" MATCHES "_DEPENDS")
+ # Use start definition name as base for other value type
+ list(GET loop_var 0 list_name)
+ string(REPLACE "_DEPENDS" "_MIN" depends_minver ${list_name})
+ string(REPLACE "_DEPENDS" "" depends_ver ${list_name})
+ string(REPLACE "_DEPENDS" "_XML_ID" xml_entry_name ${list_name})
+ string(REPLACE "_DEPENDS" "_USED" used_type_name ${list_name})
+
+ # remove the first value, not needed and wrong on "for" loop
+ list(REMOVE_AT loop_var 0)
+
+ foreach(depend_header ${loop_var})
+ string(STRIP ${depend_header} depend_header)
+ foreach(src_file ${USED_SOURCES})
+ file(STRINGS ${src_file} BIN_ADDON_SRC_PARTS)
+ foreach(loop_var ${BIN_ADDON_SRC_PARTS})
+ string(REGEX MATCH "^[ \t]*#[ \t]*(include|import)[ \t]*[<\"](kodi\/)?(.+)[\">]" include_name "${loop_var}")
+ if(include_name AND CMAKE_MATCH_3 MATCHES ^${depend_header})
+ get_directory_property(CURRENT_DEFS COMPILE_DEFINITIONS)
+ if(NOT used_type_name IN_LIST CURRENT_DEFS)
+ set(ADDON_DEPENDS "${ADDON_DEPENDS}\n<import addon=\"${${xml_entry_name}}\" minversion=\"${${depends_minver}}\" version=\"${${depends_ver}}\"/>")
+ # Inform with them the addon header about used type, if not present before
+ add_definitions(-D${used_type_name})
+ message(STATUS " - Added API usage definition: ${used_type_name} (Version: \"${${depends_ver}}\", Min. Version: \"${${depends_minver}}\")")
+ set(FOUND_HEADER_USAGE 1)
+ endif()
+ endif()
+ endforeach()
+ if(FOUND_HEADER_USAGE EQUAL 1) # break this loop if found but not unset, needed in parts where includes muddled up on addon
+ break()
+ endif()
+ endforeach()
+ # type is found and round becomes broken for next round with other type
+ if(FOUND_HEADER_USAGE EQUAL 1)
+ unset(FOUND_HEADER_USAGE)
+ break()
+ endif()
+ endforeach()
+ else()
+ # read the definition values and make it by the on version.h defined names public
+ list(GET loop_var 1 include_variable)
+ string(REGEX REPLACE ".*\"(.*)\"" "\\1" ${include_name} ${include_variable})
+ set(${include_name} ${${include_name}})
+ endif()
+ endif()
+ endforeach()
+
+ add_library(${target} ${${prefix}_SOURCES} ${${prefix}_HEADERS})
+ target_link_libraries(${target} ${${libs}})
+ set_target_properties(${target} PROPERTIES VERSION ${${prefix}_VERSION}
+ SOVERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}
+ PREFIX ""
+ POSITION_INDEPENDENT_CODE 1)
+ if(OS STREQUAL "android")
+ set_target_properties(${target} PROPERTIES PREFIX "lib")
+ endif()
+ elseif(${prefix}_CUSTOM_BINARY)
+ add_custom_target(${target} ALL)
+ endif()
+
+ # get the library's location
+ if(${prefix}_CUSTOM_BINARY)
+ list(GET ${prefix}_CUSTOM_BINARY 0 LIBRARY_LOCATION)
+ list(GET ${prefix}_CUSTOM_BINARY 1 LIBRARY_FILENAME)
+ if(CORE_SYSTEM_NAME STREQUAL android)
+ set(LIBRARY_FILENAME "lib${LIBRARY_FILENAME}")
+ endif()
+ else()
+ set(LIBRARY_LOCATION $<TARGET_FILE:${target}>)
+ # get the library's filename
+ if(CORE_SYSTEM_NAME STREQUAL android)
+ # for android we need the filename without any version numbers
+ set(LIBRARY_FILENAME $<TARGET_LINKER_FILE_NAME:${target}>)
+ else()
+ set(LIBRARY_FILENAME $<TARGET_FILE_NAME:${target}>)
+ endif()
+ endif()
+
+ # if there's an addon.xml.in we need to generate the addon.xml
+ if(EXISTS ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in)
+
+ file(READ ${PROJECT_SOURCE_DIR}/${target}/addon.xml.in addon_file)
+
+ # If sources are present must be the depends set
+ if(${prefix}_SOURCES)
+ string(FIND "${addon_file}" "\@ADDON_DEPENDS\@" matchres)
+ if("${matchres}" EQUAL -1)
+ message(FATAL_ERROR "\"\@ADDON_DEPENDS\@\" not found in addon.xml.in.")
+ endif()
+ endif()
+
+ # TODO: remove this hack after v18
+ string(REPLACE "<platform>\@PLATFORM\@</platform>" "<platform>\@PLATFORM_TAG\@</platform>" addon_file "${addon_file}")
+
+ string(CONFIGURE "${addon_file}" addon_file_conf @ONLY)
+ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}/addon.xml CONTENT "${addon_file_conf}")
+ if(${APP_NAME_UC}_BUILD_DIR)
+ file(GENERATE OUTPUT ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/addon.xml CONTENT "${addon_file_conf}")
+ endif()
+ endif()
+
+ # if there's an settings.xml.in we need to generate the settings.xml
+ if(EXISTS ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in)
+
+ file(READ ${PROJECT_SOURCE_DIR}/${target}/resources/settings.xml.in settings_file)
+ string(CONFIGURE "${settings_file}" settings_file_conf @ONLY)
+ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}/resources/settings.xml CONTENT "${settings_file_conf}")
+ if(${APP_NAME_UC}_BUILD_DIR)
+ file(GENERATE OUTPUT ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/resources/settings.xml CONTENT "${settings_file_conf}")
+ endif()
+ endif()
+
+ # set zip as default if addon-package is called without PACKAGE_XXX
+ set(CPACK_GENERATOR "ZIP")
+ set(ext "zip")
+ if(PACKAGE_ZIP OR PACKAGE_TGZ)
+ if(PACKAGE_TGZ)
+ set(CPACK_GENERATOR "TGZ")
+ set(ext "tar.gz")
+ endif()
+ set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
+ set(CPACK_PACKAGE_FILE_NAME addon)
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ set(CPACK_STRIP_FILES TRUE)
+ endif()
+ set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
+ set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+ list(APPEND CPACK_COMPONENTS_ALL ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ # Pack files together to create an archive
+ install(DIRECTORY ${target} ${CMAKE_CURRENT_BINARY_DIR}/${target} DESTINATION ./
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG}
+ REGEX ".+\\.xml\\.in(clude)?$" EXCLUDE)
+ if(WIN32)
+ if(NOT CPACK_PACKAGE_DIRECTORY)
+ # determine the temporary path
+ file(TO_CMAKE_PATH "$ENV{TEMP}" WIN32_TEMP_PATH)
+ string(LENGTH "${WIN32_TEMP_PATH}" WIN32_TEMP_PATH_LENGTH)
+ string(LENGTH "${PROJECT_BINARY_DIR}" PROJECT_BINARY_DIR_LENGTH)
+
+ # check if the temporary path is shorter than the default packaging directory path
+ if(WIN32_TEMP_PATH_LENGTH GREATER 0 AND WIN32_TEMP_PATH_LENGTH LESS PROJECT_BINARY_DIR_LENGTH)
+ # set the directory used by CPack for packaging to the temp directory
+ set(CPACK_PACKAGE_DIRECTORY ${WIN32_TEMP_PATH})
+ endif()
+ endif()
+
+ if(${prefix}_SOURCES)
+ # install the generated DLL file
+ install(PROGRAMS ${LIBRARY_LOCATION} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+
+ # for debug builds also install the PDB file
+ install(FILES $<TARGET_PDB_FILE:${target}> DESTINATION ${target}
+ CONFIGURATIONS Debug RelWithDebInfo
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_CUSTOM_BINARY)
+ install(FILES ${LIBRARY_LOCATION} DESTINATION ${target} RENAME ${LIBRARY_FILENAME}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_CUSTOM_DATA)
+ install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${target}/resources
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_EXE)
+ install(PROGRAMS ${${prefix}_ADDITIONAL_BINARY_EXE} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_PARTS)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY_PARTS} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_DIRS)
+ install(DIRECTORY ${${prefix}_ADDITIONAL_BINARY_DIRS} DESTINATION ${target} USE_SOURCE_PERMISSIONS
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ else() # NOT WIN32
+ if(NOT CPACK_PACKAGE_DIRECTORY)
+ set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR})
+ endif()
+ if(${prefix}_SOURCES)
+ install(TARGETS ${target} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_CUSTOM_BINARY)
+ install(FILES ${LIBRARY_LOCATION} DESTINATION ${target} RENAME ${LIBRARY_FILENAME}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_CUSTOM_DATA)
+ install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${target}/resources
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_EXE)
+ install(PROGRAMS ${${prefix}_ADDITIONAL_BINARY_EXE} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_PARTS)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY_PARTS} DESTINATION ${target}
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_DIRS)
+ install(DIRECTORY ${${prefix}_ADDITIONAL_BINARY_DIRS} DESTINATION ${target} USE_SOURCE_PERMISSIONS
+ COMPONENT ${target}-${${prefix}_VERSION}-${PLATFORM_TAG})
+ endif()
+ endif()
+ add_cpack_workaround(${target} ${${prefix}_VERSION} ${ext})
+ else()
+ if(CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd)
+ if(NOT OVERRIDE_PATHS)
+ if(CMAKE_INSTALL_PREFIX AND NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT CMAKE_INSTALL_PREFIX STREQUAL "${${APP_NAME_UC}_PREFIX}")
+ 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")
+ endif()
+ if(CMAKE_INSTALL_LIBDIR AND NOT CMAKE_INSTALL_LIBDIR STREQUAL "${${APP_NAME_UC}_LIB_DIR}")
+ 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")
+ endif()
+ if(CMAKE_INSTALL_DATADIR AND NOT CMAKE_INSTALL_DATADIR STREQUAL "${${APP_NAME_UC}_DATA_DIR}")
+ 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")
+ endif()
+ set(CMAKE_INSTALL_PREFIX "${${APP_NAME_UC}_PREFIX}" CACHE PATH "${APP_NAME} install prefix" FORCE)
+ set(CMAKE_INSTALL_LIBDIR "${${APP_NAME_UC}_LIB_DIR}" CACHE PATH "${APP_NAME} install libdir" FORCE)
+ set(CMAKE_INSTALL_DATADIR "${${APP_NAME_UC}_DATA_DIR}" CACHE PATH "${APP_NAME} install datadir" FORCE)
+ else()
+ if(NOT CMAKE_INSTALL_LIBDIR)
+ set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib/${APP_NAME_LC}")
+ endif()
+ if(NOT CMAKE_INSTALL_DATADIR)
+ set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_PREFIX}/share/${APP_NAME_LC}")
+ endif()
+ endif()
+ else()
+ set(CMAKE_INSTALL_LIBDIR "lib/${APP_NAME_LC}")
+ set(CMAKE_INSTALL_DATADIR "share/${APP_NAME_LC}")
+ endif()
+ if(${prefix}_SOURCES)
+ install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
+ endif()
+ if (${prefix}_CUSTOM_BINARY)
+ install(FILES ${LIBRARY_LOCATION} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target} RENAME ${LIBRARY_FILENAME})
+ endif()
+ install(DIRECTORY ${target} ${CMAKE_CURRENT_BINARY_DIR}/${target} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons
+ REGEX ".+\\.xml\\.in(clude)?$" EXCLUDE)
+ if(${prefix}_CUSTOM_DATA)
+ install(DIRECTORY ${${prefix}_CUSTOM_DATA} DESTINATION ${CMAKE_INSTALL_DATADIR}/addons/${target}/resources)
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_EXE)
+ install(PROGRAMS ${${prefix}_ADDITIONAL_BINARY_EXE} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_PARTS)
+ install(FILES ${${prefix}_ADDITIONAL_BINARY_PARTS} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target})
+ endif()
+ if(${prefix}_ADDITIONAL_BINARY_DIRS)
+ install(DIRECTORY ${${prefix}_ADDITIONAL_BINARY_DIRS} DESTINATION ${CMAKE_INSTALL_LIBDIR}/addons/${target} USE_SOURCE_PERMISSIONS)
+ endif()
+ endif()
+ if(${APP_NAME_UC}_BUILD_DIR)
+ file(GLOB_RECURSE files ${CMAKE_CURRENT_SOURCE_DIR}/${target}/*)
+ if(${prefix}_CUSTOM_DATA)
+ get_filename_component(dname ${${prefix}_CUSTOM_DATA} NAME)
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${${prefix}_CUSTOM_DATA}
+ ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/resources/${dname})
+ endif()
+ foreach(file ${files})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/${target}/" "" name "${file}")
+ # A good way to deal with () in filenames
+ if(NOT ${file} MATCHES xml.in)
+ configure_file(${file} ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/${name} COPYONLY)
+ endif()
+ endforeach()
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${LIBRARY_LOCATION}
+ ${${APP_NAME_UC}_BUILD_DIR}/addons/${target}/${LIBRARY_FILENAME})
+ if(${prefix}_ADDITIONAL_BINARY)
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${${prefix}_ADDITIONAL_BINARY}
+ ${${APP_NAME_UC}_BUILD_DIR}/addons/${target})
+ endif()
+ endif()
+endmacro()
+
+# finds a path to a given file (recursive)
+function (kodi_find_path var_name filename search_path strip_file)
+ file(GLOB_RECURSE PATH_TO_FILE ${search_path} ${filename})
+ if(strip_file)
+ string(REPLACE ${filename} "" PATH_TO_FILE ${PATH_TO_FILE})
+ endif()
+ set (${var_name} ${PATH_TO_FILE} PARENT_SCOPE)
+endfunction()
+
+# Cmake build options
+include(AddOptions)
+include(TestCXXAcceptsFlag)
+option(PACKAGE_ZIP "Package Zip file?" OFF)
+option(PACKAGE_TGZ "Package TGZ file?" OFF)
+option(BUILD_SHARED_LIBS "Build shared libs?" ON)
+
+# LTO support?
+CHECK_CXX_ACCEPTS_FLAG("-flto" HAVE_LTO)
+if(HAVE_LTO)
+ option(USE_LTO "use link time optimization" OFF)
+ if(USE_LTO)
+ add_options(ALL_LANGUAGES ALL_BUILDS "-flto")
+ endif()
+endif()
+
+# set this to try linking dependencies as static as possible
+if(ADDONS_PREFER_STATIC_LIBS)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
+
+if(${APP_NAME_UC}_BUILD_DIR)
+ list(APPEND CMAKE_PREFIX_PATH ${${APP_NAME_UC}_BUILD_DIR}/build)
+endif()
diff --git a/cmake/scripts/common/AddonHelpers.dox b/cmake/scripts/common/AddonHelpers.dox
new file mode 100644
index 0000000..522e0e7
--- /dev/null
+++ b/cmake/scripts/common/AddonHelpers.dox
@@ -0,0 +1,59 @@
+/*!
+\addtogroup cpp_cmake
+
+Kodi which uses it as a library for its binary addons has a special build
+system for this.
+
+To implement this, a CMake macro brought by Kodi is used, this is
+"build_addon (...)". This processes various definitions passed by the addon to
+process the construction.
+
+
+--------------------------------------------------------------------------------
+
+<b>Here's a minimal example of the addon used for CMakeLists.txt:</b>
+
+~~~~~~~~~~~~~{.cmake}
+cmake_minimum_required(VERSION 3.5)
+project(example.addon)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
+
+find_package(Kodi REQUIRED)
+
+include_directories(${KODI_INCLUDE_DIR}
+
+set(DEPLIBS ) # Here empty
+set(EXAMPLE_SOURCES src/main.cpp)
+set(EXAMPLE_HEADERS src/main.h)
+
+build_addon((example.addon EXAMPLE DEPLIBS)
+
+include(CPack)
+~~~~~~~~~~~~~
+
+
+--------------------------------------------------------------------------------
+
+This is a list of special variables that can be passed to the macro.
+The parts defined with "*" must be given the second name given to the macro.
+
+Here to define the necessary creation and installation files on addon CMakeLists.txt:
+| Name | Description
+|-----------------------------|-------------------------------------------------
+| *_SOURCES | List of source code files to be complicated.
+| *_HEADERS | List of used source code header files.
+| *_CUSTOM_BINARY | For special cases where an already created library from an external source is inserted, the <b>"* _SOURCES"</b> and <b>"* _HEADERS"</b> are unused in this case.<br>This is currently used primarily on game addons.
+| *_CUSTOM_DATA | To add additional required data from a folder, which are stored in the shared folder of the addon.<br>With a "/" at the end of the content given to the folder is used, without the folder itself.
+| *_ADDITIONAL_BINARY | In case the additional library has to be installed for the addon, the path or CMake name can be given here.
+| *_ADDITIONAL_BINARY_EXE | In case you need to addon an additional application you can give the path or CMake name, it will be in the same folder as the addon library.<br>The mode bits are set there as EXE.
+| *_ADDITIONAL_BINARY_DIRS | To add complete folders additionally to folders containing the addon library.<br>With a "/" at the end of the content given to the folder is used, without the folder itself.
+
+External creation Options, given by `-D...`:
+| Name | Description
+|-----------------------------|-------------------------------------------------
+| PACKAGE_ZIP | To create a package as a ZIP file. This is also used to install locally addon together.<br>Default is OFF.
+| PACKAGE_TGZ | To create a package as a TGZ file.<br>Default is OFF.
+| BUILD_SHARED_LIBS | To define if addon library is shared or static.<br>Default is ON to have shared.
+| USE_LTO | Use link time optimization.<br>Default is OFF.
+*/
diff --git a/cmake/scripts/common/ArchSetup.cmake b/cmake/scripts/common/ArchSetup.cmake
new file mode 100644
index 0000000..a59fcb5
--- /dev/null
+++ b/cmake/scripts/common/ArchSetup.cmake
@@ -0,0 +1,201 @@
+# This script configures the build for a given architecture.
+# Flags and stringified arch is set up.
+# General compiler tests belongs here.
+#
+# On return, the following variables are set:
+# CMAKE_SYSTEM_NAME - a lowercased system name
+# CPU - the CPU on the target
+# ARCH - the system architecture
+# ARCH_DEFINES - list of compiler definitions for this architecture
+# SYSTEM_DEFINES - list of compiler definitions for this system
+# DEP_DEFINES - compiler definitions for system dependencies (e.g. LIRC)
+# + the results of compiler tests etc.
+
+# workaround a bug in older cmake, where binutils wouldn't be set after deleting CMakeCache.txt
+include(CMakeFindBinUtils)
+
+include(CheckCXXSourceCompiles)
+include(CheckSymbolExists)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckTypeSize)
+
+# Macro to check if a given builtin function exists
+# Arguments:
+# func the function to check
+# var the compiler definition to set if type exists
+# On return:
+# If type was found, the definition is added to SYSTEM_DEFINES
+macro(check_builtin func var)
+ check_cxx_source_compiles("
+ int main()
+ {
+ ${func};
+ }" ${var})
+ if(${var})
+ list(APPEND SYSTEM_DEFINES -D${var}=1)
+ endif()
+endmacro()
+
+
+# -------- Main script ---------
+message(STATUS "System type: ${CMAKE_SYSTEM_NAME}")
+
+if(WITH_CPU)
+ set(CPU ${WITH_CPU})
+elseif(NOT KODI_DEPENDSBUILD)
+ set(CPU ${CMAKE_SYSTEM_PROCESSOR})
+endif()
+
+if(CMAKE_TOOLCHAIN_FILE)
+ if(NOT EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+ message(FATAL_ERROR "Toolchain file ${CMAKE_TOOLCHAIN_FILE} does not exist.")
+ elseif(KODI_DEPENDSBUILD AND (NOT DEPENDS_PATH OR NOT NATIVEPREFIX))
+ message(FATAL_ERROR "Toolchain did not define DEPENDS_PATH or NATIVEPREFIX. Possibly outdated depends.")
+ endif()
+endif()
+
+# While CMAKE_CROSSCOMPILING is set unconditionally if there's a toolchain file,
+# this variable is set if we can execute build artefacts on the host system (for example unit tests).
+if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR AND
+ CMAKE_HOST_SYSTEM_NAME STREQUAL CMAKE_SYSTEM_NAME)
+ if(NOT DEFINED HOST_CAN_EXECUTE_TARGET)
+ set(HOST_CAN_EXECUTE_TARGET TRUE)
+ endif()
+else()
+ if(NOT HOST_CAN_EXECUTE_TARGET)
+ set(HOST_CAN_EXECUTE_TARGET FALSE)
+ endif()
+endif()
+
+# system specific arch setup
+if(NOT EXISTS ${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/ArchSetup.cmake)
+ message(FATAL_ERROR "Couldn't find configuration for '${CORE_SYSTEM_NAME}' "
+ "Either the platform is not (yet) supported "
+ "or a toolchain file has to be specified. "
+ "Consult ${CMAKE_SOURCE_DIR}/cmake/README.md for instructions. "
+ "Note: Specifying a toolchain requires a clean build directory!")
+endif()
+include(${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/ArchSetup.cmake)
+
+# No TARBALL_DIR given, or no arch specific default set
+if(NOT TARBALL_DIR)
+ set(TARBALL_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/download)
+endif()
+
+message(STATUS "Core system type: ${CORE_SYSTEM_NAME}")
+message(STATUS "Platform: ${CORE_PLATFORM_NAME}")
+message(STATUS "CPU: ${CPU}, ARCH: ${ARCH}")
+message(STATUS "Cross-Compiling: ${CMAKE_CROSSCOMPILING}")
+message(STATUS "Execute build artefacts on host: ${CORE_HOST_IS_TARGET}")
+message(STATUS "Depends based build: ${KODI_DEPENDSBUILD}")
+
+check_symbol_exists(posix_fadvise fcntl.h HAVE_POSIX_FADVISE)
+check_symbol_exists(PRIdMAX inttypes.h HAVE_INTTYPES_H)
+check_builtin("long* temp=0; long ret=__sync_add_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_ADD_AND_FETCH)
+check_builtin("long* temp=0; long ret=__sync_sub_and_fetch(temp, 1)" HAS_BUILTIN_SYNC_SUB_AND_FETCH)
+check_builtin("long* temp=0; long ret=__sync_val_compare_and_swap(temp, 1, 1)" HAS_BUILTIN_SYNC_VAL_COMPARE_AND_SWAP)
+check_include_file(sys/inotify.h HAVE_INOTIFY)
+if(HAVE_INOTIFY)
+ list(APPEND SYSTEM_DEFINES -DHAVE_INOTIFY=1)
+endif()
+if(HAVE_POSIX_FADVISE)
+ list(APPEND SYSTEM_DEFINES -DHAVE_POSIX_FADVISE=1)
+endif()
+check_function_exists(localtime_r HAVE_LOCALTIME_R)
+if(HAVE_LOCALTIME_R)
+ list(APPEND SYSTEM_DEFINES -DHAVE_LOCALTIME_R=1)
+endif()
+check_function_exists(gmtime_r HAVE_GMTIME_R)
+if(HAVE_GMTIME_R)
+list(APPEND SYSTEM_DEFINES -DHAVE_GMTIME_R=1)
+endif()
+if(HAVE_INTTYPES_H)
+ list(APPEND SYSTEM_DEFINES -DHAVE_INTTYPES_H=1)
+endif()
+
+set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
+check_symbol_exists("STATX_BTIME" "linux/stat.h" HAVE_STATX)
+if(HAVE_STATX)
+ check_function_exists("statx" FOUND_STATX_FUNCTION)
+ if(FOUND_STATX_FUNCTION)
+ message(STATUS "statx is available")
+ list(APPEND ARCH_DEFINES "-DHAVE_STATX=1")
+ else()
+ message(STATUS "statx flags found but no linkable function : C library too old ?")
+ endif()
+else()
+ message(STATUS "statx() not found")
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS "")
+
+find_package(SSE)
+foreach(_sse SSE SSE2 SSE3 SSSE3 SSE4_1 SSE4_2 AVX AVX2)
+ if(${${_sse}_FOUND})
+ # enable SSE versions up to 4.1 by default, if available
+ if(NOT ${_sse} MATCHES "AVX" AND NOT ${_sse} STREQUAL "SSE4_2")
+ option(ENABLE_${_sse} "Enable ${_sse}" ON)
+ else()
+ option(ENABLE_${_sse} "Enable ${_sse}" OFF)
+ endif()
+ endif()
+ if(ENABLE_${_sse})
+ set(HAVE_${_sse} TRUE CACHE STRING "${_sse} enabled")
+ list(APPEND ARCH_DEFINES -DHAVE_${_sse}=1)
+ endif()
+endforeach()
+
+if(NOT DEFINED NEON OR NEON)
+ option(ENABLE_NEON "Enable NEON optimization" ${NEON})
+ if(ENABLE_NEON)
+ message(STATUS "NEON optimization enabled")
+ add_definitions(-DHAS_NEON)
+ if(NEON_FLAGS)
+ add_options(ALL_LANGUAGES ALL_BUILDS ${NEON_FLAGS})
+ endif()
+ endif()
+endif()
+
+if(NOT MSVC)
+ # these options affect all code built by cmake including external projects.
+ add_options(ALL_LANGUAGES ALL_BUILDS
+ -Wall
+ -Wdouble-promotion
+ -Wmissing-field-initializers
+ -Wsign-compare
+ -Wextra
+ -Wno-unused-parameter # from -Wextra
+ )
+
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_options(ALL_LANGUAGES ALL_BUILDS
+ -Wno-cast-function-type # from -Wextra
+ )
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ add_options(ALL_LANGUAGES ALL_BUILDS
+ -Wno-bad-function-cast
+ -Wno-deprecated
+ )
+ endif()
+
+ add_options(CXX ALL_BUILDS
+ -Wnon-virtual-dtor
+ )
+
+ add_options(ALL_LANGUAGES DEBUG
+ -g
+ -D_DEBUG
+ )
+
+ # these options affect only core code
+ if(NOT CORE_COMPILE_OPTIONS)
+ set(CORE_COMPILE_OPTIONS
+ -Werror=double-promotion
+ -Werror=missing-field-initializers
+ -Werror=sign-compare
+ )
+ endif()
+endif()
+
+# set for compile info to help detect binary addons
+set(APP_SHARED_LIBRARY_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}")
diff --git a/cmake/scripts/common/CMakeHelpers.cmake b/cmake/scripts/common/CMakeHelpers.cmake
new file mode 100644
index 0000000..995c38a
--- /dev/null
+++ b/cmake/scripts/common/CMakeHelpers.cmake
@@ -0,0 +1,54 @@
+# This file contains functions that support the debugging of the CMake files.
+
+# This file shouldn't be included per default in any CMake file. It should be
+# included and used only on demand. All functions are prefixed with "debug_".
+#
+# Usage:
+# include(scripts/common/CMakeHelpers.cmake)
+# debug_print_variables()
+
+# Print all CMake variables.
+macro(debug_print_variables)
+ get_cmake_property(_variableNames VARIABLES)
+ foreach(_variableName ${_variableNames})
+ message(STATUS "${_variableName} = ${${_variableName}}")
+ endforeach()
+endmacro()
+
+# Get all properties that CMake supports and convert them to a list.
+function(debug_get_properties VAR)
+ execute_process(COMMAND cmake --help-property-list
+ OUTPUT_VARIABLE _properties)
+ string(REGEX REPLACE ";" "\\\\;" _properties "${_properties}")
+ string(REGEX REPLACE "\n" ";" _properties "${_properties}")
+ list(REMOVE_DUPLICATES _properties)
+ list(REMOVE_ITEM _properties LOCATION)
+ set(${VAR} ${_properties} PARENT_SCOPE)
+endfunction()
+
+# List all properties.
+function(debug_list_properties)
+ debug_get_properties(_properties)
+ message("CMake properties = ${_properties}")
+endfunction()
+
+# Print all set properties of a specified target.
+function(debug_print_target_properties target)
+ if(NOT TARGET ${target})
+ message(FATAL_ERROR "There is no target named '${target}'")
+ endif()
+
+ debug_get_properties(_properties)
+
+ # Reading LOCATION property is deprecated and triggers a fatal error.
+ string(REGEX REPLACE ";LOCATION;|LOCATION" "" _properties "${_properties}")
+ string(REGEX REPLACE "<CONFIG>" "${CMAKE_BUILD_TYPE}" _properties
+ "${_properties}")
+ foreach(_property ${_properties})
+ get_property(_value TARGET ${target} PROPERTY ${_property} SET)
+ if(_value)
+ get_target_property(_value ${target} ${_property})
+ message("${target} ${_property} = ${_value}")
+ endif()
+ endforeach()
+endfunction()
diff --git a/cmake/scripts/common/CheckCommits.cmake b/cmake/scripts/common/CheckCommits.cmake
new file mode 100644
index 0000000..304e623
--- /dev/null
+++ b/cmake/scripts/common/CheckCommits.cmake
@@ -0,0 +1,75 @@
+find_package(Git REQUIRED)
+
+macro(sanity_check message)
+ if(status_code)
+ message(FATAL_ERROR "${message}")
+ endif()
+endmacro()
+
+# Check that there are no changes in working-tree
+execute_process(COMMAND ${GIT_EXECUTABLE} diff --quiet
+ RESULT_VARIABLE status_code)
+sanity_check("Cannot run with working tree changes. Commit, stash or drop them.")
+
+# Setup base of tests
+set(check_base $ENV{CHECK_BASE})
+if(NOT check_base)
+ set(check_base origin/master)
+endif()
+
+# Setup end of tests
+set(check_head $ENV{CHECK_HEAD})
+if(NOT check_head)
+ set(check_head HEAD)
+endif()
+
+# Setup target to build
+set(check_target $ENV{CHECK_TARGET})
+if(NOT check_target)
+ set(check_target check)
+endif()
+
+# Build threads
+set(build_threads $ENV{CHECK_THREADS})
+if(NOT build_threads)
+ if(UNIX)
+ execute_process(COMMAND nproc
+ OUTPUT_VARIABLE build_threads)
+ string(REGEX REPLACE "(\r?\n)+$" "" build_threads "${build_threads}")
+ endif()
+endif()
+
+# Record current HEAD
+execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
+ OUTPUT_VARIABLE current_branch)
+
+string(REGEX REPLACE "(\r?\n)+$" "" current_branch "${current_branch}")
+
+# Grab revision list
+execute_process(COMMAND ${GIT_EXECUTABLE} rev-list ${check_base}..${check_head} --reverse
+ OUTPUT_VARIABLE rev_list)
+
+string(REPLACE "\n" ";" rev_list ${rev_list})
+foreach(rev ${rev_list})
+ # Checkout
+ message("Testing revision ${rev}")
+ execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${rev}
+ RESULT_VARIABLE status_code)
+ sanity_check("Failed to checkout ${rev}")
+
+ # Build
+ if(build_threads GREATER 2)
+ execute_process(COMMAND ${CMAKE_COMMAND} "--build" "${CMAKE_BINARY_DIR}" "--target" "${check_target}" "--use-stderr" "--" "-j${build_threads}"
+ RESULT_VARIABLE status_code)
+ else()
+ execute_process(COMMAND ${CMAKE_COMMAND} "--build" "${CMAKE_BINARY_DIR}" "--target" "${check_target}" "--use-stderr"
+ RESULT_VARIABLE status_code)
+ endif()
+ if(status_code)
+ execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${current_branch})
+ endif()
+ sanity_check("Failed to build target for revision ${rev}")
+endforeach()
+
+message("Everything checks out fine")
+execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${current_branch})
diff --git a/cmake/scripts/common/CheckTargetPlatform.cmake b/cmake/scripts/common/CheckTargetPlatform.cmake
new file mode 100644
index 0000000..29206c0
--- /dev/null
+++ b/cmake/scripts/common/CheckTargetPlatform.cmake
@@ -0,0 +1,70 @@
+# handle target platforms
+function(check_target_platform dir target_platform build)
+ # param[in] dir path/directory of the addon/dependency
+ # param[in] target_platform target platform of the build
+ # param[out] build Result whether the addon/dependency should be built for the specified target platform
+
+ set(${build} FALSE)
+ # check if the given directory exists and contains a platforms.txt
+ if(EXISTS ${dir} AND EXISTS ${dir}/platforms.txt)
+ # get all the specified platforms
+ file(STRINGS ${dir}/platforms.txt platforms)
+
+ list( LENGTH platforms listlen )
+ if(${listlen} EQUAL 1)
+ string(REPLACE " " ";" platforms ${platforms})
+ endif()
+
+ # check if the addon/dependency should be built for the current platform
+ foreach(platform ${platforms})
+ if(${platform} STREQUAL "all" OR ${platform} STREQUAL ${target_platform})
+ set(${build} TRUE)
+ else()
+ # check if the platform is defined as "!<platform>"
+ string(SUBSTRING ${platform} 0 1 platform_first)
+ if(${platform_first} STREQUAL "!")
+ # extract the platform
+ string(LENGTH ${platform} platform_length)
+ math(EXPR platform_length "${platform_length} - 1")
+ string(SUBSTRING ${platform} 1 ${platform_length} platform)
+
+ # check if the current platform does not match the extracted platform
+ if(${platform} STREQUAL ${target_platform})
+ set(${build} FALSE)
+ break()
+ elseif(NOT ${platform} STREQUAL ${target_platform})
+ set(${build} TRUE)
+ endif()
+ endif()
+ endif()
+ endforeach()
+ else()
+ set(${build} TRUE)
+ endif()
+
+ # make the ${build} variable available to the calling script
+ set(${build} "${${build}}" PARENT_SCOPE)
+endfunction()
+
+function(check_install_permissions install_dir have_perms)
+ # param[in] install_dir directory to check for write permissions
+ # param[out] have_perms whether we have permissions to install to install_dir
+
+ set(testfile_lib ${install_dir}/lib/kodi/.cmake-inst-test)
+ set(testfile_share ${install_dir}/share/kodi/.cmake-inst-test)
+ get_filename_component(testdir_lib ${testfile_lib} DIRECTORY)
+ get_filename_component(testdir_share ${testfile_share} DIRECTORY)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${testdir_lib})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${testdir_share})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${testfile_lib})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${testfile_share})
+
+ if(EXISTS ${testfile_lib} AND EXISTS ${testfile_share})
+ set(${have_perms} True PARENT_SCOPE)
+ else()
+ message(STATUS "check_install_permissions ${install_dir}: failed to create files")
+ set(${have_perms} False PARENT_SCOPE)
+ endif()
+ file(REMOVE ${testfile_lib} ${testfile_share})
+endfunction()
diff --git a/cmake/scripts/common/CompilerSettings.cmake b/cmake/scripts/common/CompilerSettings.cmake
new file mode 100644
index 0000000..bb0af92
--- /dev/null
+++ b/cmake/scripts/common/CompilerSettings.cmake
@@ -0,0 +1,5 @@
+# Languages and global compiler settings
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp")
diff --git a/cmake/scripts/common/DependencyOptions.cmake b/cmake/scripts/common/DependencyOptions.cmake
new file mode 100644
index 0000000..a45dcec
--- /dev/null
+++ b/cmake/scripts/common/DependencyOptions.cmake
@@ -0,0 +1,23 @@
+# Set Option varname based on USE_INTERNAL_LIBS status
+#
+# Alternative to cmake_dependent_option
+# cmake_dependent_option is restrictive, in the fact that we cannot override the
+# set option value as a cache variable (-Dvar=foo)
+#
+# This allows us to have the same outcome as cmake_dependent_option whilst still allowing
+# user to override for platforms that would normally be forced ON
+#
+function(dependent_option varname optionmessage)
+
+ # If varname already set, accept that, as it was provided by the user
+ if(NOT DEFINED ${varname})
+ # Generally we only define USE_INTERNAL_LIBS as the exception for platforms
+ # we explicitly dont want to build internal libs (eg Linux/Freebsd)
+ if(NOT DEFINED USE_INTERNAL_LIBS)
+ option(${varname} ${optionmessage} ON)
+ else()
+ # Respect Value of USE_INTERNAL_LIBS for ON/OFF
+ option(${varname} ${optionmessage} ${USE_INTERNAL_LIBS})
+ endif()
+ endif()
+endfunction()
diff --git a/cmake/scripts/common/GenerateVersionedFiles.cmake b/cmake/scripts/common/GenerateVersionedFiles.cmake
new file mode 100644
index 0000000..d54b524
--- /dev/null
+++ b/cmake/scripts/common/GenerateVersionedFiles.cmake
@@ -0,0 +1,35 @@
+include(${CORE_SOURCE_DIR}/cmake/scripts/common/Macros.cmake)
+
+core_find_versions()
+
+# configure_file without dependency tracking
+# configure_file would register additional file dependencies that interfere
+# with the ones from add_custom_command (and the generation would happen twice)
+function(generate_versioned_file _SRC _DEST)
+ file(READ ${CORE_SOURCE_DIR}/${_SRC} file_content)
+ string(CONFIGURE "${file_content}" file_content @ONLY)
+ file(WRITE ${CMAKE_BINARY_DIR}/${_DEST} "${file_content}")
+endfunction()
+
+# add-on xml's
+file(GLOB ADDON_XML_IN_FILE ${CORE_SOURCE_DIR}/addons/*/addon.xml.in)
+
+# remove 'xbmc.json', will be created from 'xbmc/interfaces/json-rpc/schema/CMakeLists.txt'
+list(REMOVE_ITEM ADDON_XML_IN_FILE ${CORE_SOURCE_DIR}/addons/xbmc.json/addon.xml.in)
+
+foreach(loop_var ${ADDON_XML_IN_FILE})
+ list(GET loop_var 0 xml_name)
+
+ string(REPLACE "/addon.xml.in" "" source_dir ${xml_name})
+ string(REPLACE ${CORE_SOURCE_DIR} ${CMAKE_BINARY_DIR} dest_dir ${source_dir})
+ file(MAKE_DIRECTORY ${dest_dir})
+
+ configure_file(${source_dir}/addon.xml.in ${dest_dir}/addon.xml @ONLY)
+
+ unset(source_dir)
+ unset(dest_dir)
+ unset(xml_name)
+endforeach()
+
+
+generate_versioned_file(xbmc/CompileInfo.cpp.in ${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp)
diff --git a/cmake/scripts/common/GeneratorSetup.cmake b/cmake/scripts/common/GeneratorSetup.cmake
new file mode 100644
index 0000000..304b504
--- /dev/null
+++ b/cmake/scripts/common/GeneratorSetup.cmake
@@ -0,0 +1,49 @@
+# Configure single-/multiconfiguration generators and variables
+#
+# CORE_BUILD_CONFIG that is set to
+# - CMAKE_BUILD_TYPE for single configuration generators such as make, nmake
+# - a variable that expands on build time to the current configuration for
+# multi configuration generators such as VS or Xcode
+if(CMAKE_CONFIGURATION_TYPES)
+ if(CMAKE_BUILD_TYPE)
+ message(FATAL_ERROR "CMAKE_BUILD_TYPE must not be defined for multi-configuration generators")
+ endif()
+ set(CORE_BUILD_CONFIG ${CMAKE_CFG_INTDIR})
+ message(STATUS "Generator: Multi-configuration (${CMAKE_GENERATOR})")
+else()
+ if(CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
+ CACHE STRING "Choose build type (${CMAKE_BUILD_TYPES})" FORCE)
+ else()
+ # Set default
+ set(CMAKE_BUILD_TYPE Release
+ CACHE STRING "Choose build type (${CMAKE_BUILD_TYPES})" FORCE)
+ endif()
+ set(CORE_BUILD_CONFIG ${CMAKE_BUILD_TYPE})
+ message(STATUS "Generator: Single-configuration: ${CMAKE_BUILD_TYPE} (${CMAKE_GENERATOR})")
+endif()
+
+# Print CMake version
+message(STATUS "CMake Version: ${CMAKE_VERSION}")
+
+# Deal with CMake special cases
+if(CMAKE_VERSION VERSION_EQUAL 3.5.1)
+ message(WARNING "CMake 3.5.1 introduced a crash during configuration. "
+ "Please consider upgrading to 3.5.2 (cmake.org/Bug/view.php?id=16044)")
+endif()
+
+# Darwin needs CMake 3.4
+if(APPLE AND CMAKE_VERSION VERSION_LESS 3.4)
+ message(WARNING "Build on Darwin requires CMake 3.4 or later (tdb library support) "
+ "or the usage of the patched version in depends.")
+endif()
+
+# Windows needs CMake 3.6 (VS_STARTUP_PROJECT)
+if(WIN32 AND CMAKE_VERSION VERSION_LESS 3.6)
+ message(FATAL_ERROR "Build on Windows needs CMake 3.6 or later")
+endif()
+
+# Ninja needs CMake 3.2 due to ExternalProject BUILD_BYPRODUCTS usage
+if(CMAKE_GENERATOR STREQUAL Ninja AND CMAKE_VERSION VERSION_LESS 3.2)
+ message(FATAL_ERROR "Generator: Ninja requires CMake 3.2 or later")
+endif()
diff --git a/cmake/scripts/common/HandleDepends.cmake b/cmake/scripts/common/HandleDepends.cmake
new file mode 100644
index 0000000..dc022ba
--- /dev/null
+++ b/cmake/scripts/common/HandleDepends.cmake
@@ -0,0 +1,301 @@
+include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake)
+
+# handle addon depends
+function(add_addon_depends addon searchpath)
+ # input: string addon string searchpath
+
+ set(OUTPUT_DIR ${ADDON_DEPENDS_PATH})
+ # look for platform-specific dependencies
+ file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt)
+ # backward compatibility
+ if(NOT cmake_input_files AND CORE_SYSTEM_NAME STREQUAL windowsstore)
+ file(GLOB_RECURSE cmake_input_files ${searchpath}/windows/*.txt)
+ endif()
+ file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt)
+ list(APPEND cmake_input_files ${cmake_input_files2})
+
+ foreach(file ${cmake_input_files})
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${file})
+ if(NOT (file MATCHES CMakeLists.txt OR
+ file MATCHES install.txt OR
+ file MATCHES noinstall.txt OR
+ file MATCHES "flags.*[.]txt" OR
+ file MATCHES deps.txt OR
+ file MATCHES "[a-z]+-deps[.]txt" OR
+ file MATCHES platforms.txt))
+ message(STATUS "Processing ${file}")
+ file(STRINGS ${file} def)
+ string(REPLACE " " ";" def ${def})
+ list(LENGTH def deflength)
+ get_filename_component(dir ${file} DIRECTORY)
+
+ # get the id of the dependency
+ if(NOT "${def}" STREQUAL "")
+ # read the id from the file
+ list(GET def 0 id)
+ else()
+ # read the id from the filename
+ get_filename_component(id ${file} NAME_WE)
+ endif()
+
+ # check if the dependency has a platforms.txt
+ set(platform_found FALSE)
+ check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found)
+
+ if(${platform_found} AND NOT TARGET ${id})
+ # determine the download URL of the dependency
+ set(url "")
+ if(deflength GREATER 1)
+ list(GET def 1 url)
+ message(STATUS "${id} url: ${url}")
+ endif()
+
+ # check if there are any library specific flags that need to be passed on
+ if(EXISTS ${dir}/flags.txt)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags.txt)
+ file(STRINGS ${dir}/flags.txt extraflags)
+ string(REPLACE " " ";" extraflags ${extraflags})
+
+ message(STATUS "${id} extraflags: ${extraflags}")
+ endif()
+
+ if(EXISTS ${dir}/flags-${CPU}.txt)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags-${CPU}.txt)
+ file(STRINGS ${dir}/flags-${CPU}.txt archextraflags)
+ string(REPLACE " " ";" archextraflags ${archextraflags})
+
+ message(STATUS "${id} ${CPU} extraflags: ${archextraflags}")
+ list(APPEND extraflags ${archextraflags})
+ endif()
+
+ set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
+ -DOUTPUT_DIR=${OUTPUT_DIR}
+ -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE}
+ -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX}
+ -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR}
+ -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
+ -DENABLE_STATIC=1
+ -DBUILD_SHARED_LIBS=0)
+ # windows args
+ if (CMAKE_SYSTEM_NAME STREQUAL WindowsStore OR CMAKE_SYSTEM_NAME STREQUAL Windows)
+ list(APPEND BUILD_ARGS -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
+ -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION})
+ endif()
+ # if there are no make rules override files available take care of manually passing on ARCH_DEFINES
+ if(NOT CMAKE_USER_MAKE_RULES_OVERRIDE AND NOT CMAKE_USER_MAKE_RULES_OVERRIDE_CXX)
+ # make sure we create strings, not lists
+ set(TMP_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_DEFINES}")
+ set(TMP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_DEFINES}")
+ set(TMP_EXE_LINKER_FLAGS "-L${OUTPUT_DIR}/lib ${CMAKE_EXE_LINKER_FLAGS}")
+ list(APPEND BUILD_ARGS -DCMAKE_C_FLAGS=${TMP_C_FLAGS}
+ -DCMAKE_CXX_FLAGS=${TMP_CXX_FLAGS}
+ -DCMAKE_EXE_LINKER_FLAGS=${TMP_EXE_LINKER_FLAGS})
+ endif()
+
+ if(CMAKE_TOOLCHAIN_FILE)
+ list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
+ message("toolchain specified")
+ message(${BUILD_ARGS})
+ endif()
+
+ if(ADDON_EXTRA_ARGS)
+ string(REPLACE " " ";" ADDON_EXTRA_ARGS ${ADDON_EXTRA_ARGS})
+ list(APPEND BUILD_ARGS ${ADDON_EXTRA_ARGS})
+ message("Addon Extra Args: ${ADDON_EXTRA_ARGS}")
+ endif()
+
+ # used for addons where need special folders to store there content (if
+ # not set the addon define it byself).
+ # e.g. Google Chromium addon where his git bring:
+ # - "unable to create file" ... "Filename too long"
+ # see also WARNING by Windows on: https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart
+ if(THIRD_PARTY_PATH)
+ message(STATUS "Third party lib path specified")
+ message(STATUS ${THIRD_PARTY_PATH})
+ list(APPEND BUILD_ARGS -DTHIRD_PARTY_PATH=${THIRD_PARTY_PATH})
+ endif()
+
+ set(PATCH_COMMAND)
+
+ # if there's a CMakeLists.txt use it to prepare the build
+ if(EXISTS ${dir}/CMakeLists.txt)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/CMakeLists.txt)
+ list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dir}/CMakeLists.txt ${BUILD_DIR}/${id}/src/${id})
+ endif()
+
+ # check if we have patches to apply
+ file(GLOB patches ${dir}/*.patch)
+ list(SORT patches)
+ foreach(patch ${patches})
+ if(NOT PATCH_PROGRAM OR "${PATCH_PROGRAM}" STREQUAL "")
+ if(NOT PATCH_EXECUTABLE)
+ # find the path to the patch executable
+
+ if(WIN32)
+ # On Windows prioritize Git patch.exe
+ find_package(Git)
+ if(Git_FOUND)
+ get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY)
+ get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY)
+ endif()
+ find_program(PATCH_EXECUTABLE NAMES patch.exe HINTS ${GIT_DIR} PATH_SUFFIXES usr/bin)
+ else()
+ find_program(PATCH_EXECUTABLE NAMES patch)
+ endif()
+ if(NOT PATCH_EXECUTABLE)
+ message(FATAL_ERROR "Missing patch command (we looked in ${CMAKE_PREFIX_PATH})")
+ endif()
+ endif()
+
+ set(PATCH_PROGRAM ${PATCH_EXECUTABLE})
+
+ # On Windows "patch.exe" can only handle CR-LF line-endings.
+ # Our patches have LF-only line endings - except when they
+ # have been checked out as part of a dependency hosted on Git
+ # and core.autocrlf=true.
+ if(WIN32)
+ file(READ ${patch} patch_content_hex HEX)
+ # Force handle LF-only line endings
+ if(NOT patch_content_hex MATCHES "0d0a")
+ list(APPEND PATCH_PROGRAM --binary)
+ endif()
+ endif()
+ endif()
+
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${patch})
+ list(APPEND PATCH_COMMAND COMMAND ${PATCH_PROGRAM} -p1 -i ${patch})
+ endforeach()
+
+
+ # if there's an install.txt use it to properly install the built files
+ set(INSTALL_COMMAND "")
+ if(EXISTS ${dir}/install.txt)
+ set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND}
+ -DINPUTDIR=${BUILD_DIR}/${id}/src/${id}-build/
+ -DINPUTFILE=${dir}/install.txt
+ -DDESTDIR=${OUTPUT_DIR}
+ -DENABLE_STATIC=1
+ "${extraflags}"
+ -P ${PROJECT_SOURCE_DIR}/install.cmake)
+ elseif(EXISTS ${dir}/noinstall.txt)
+ set(INSTALL_COMMAND INSTALL_COMMAND "")
+ endif()
+
+ # check if there's a platform-specific or generic deps.txt containing dependencies on other libraries
+ if(EXISTS ${dir}/${CORE_SYSTEM_NAME}-deps.txt)
+ file(STRINGS ${dir}/${CORE_SYSTEM_NAME}-deps.txt deps)
+ message(STATUS "${id} depends: ${deps}")
+ # backward compatibility
+ elseif(CORE_SYSTEM_NAME STREQUAL windowsstore AND EXISTS ${dir}/windows-deps.txt)
+ file(STRINGS ${dir}/windows-deps.txt deps)
+ message(STATUS "${id} depends: ${deps}")
+ elseif(EXISTS ${dir}/deps.txt)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/deps.txt)
+ file(STRINGS ${dir}/deps.txt deps)
+ message(STATUS "${id} depends: ${deps}")
+ else()
+ set(deps)
+ endif()
+
+ if(CROSS_AUTOCONF AND AUTOCONF_FILES)
+ foreach(afile ${AUTOCONF_FILES})
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${afile})
+ list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E echo "AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}")
+ list(APPEND PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${afile} ${BUILD_DIR}/${id}/src/${id})
+ endforeach()
+ endif()
+
+ # prepare the setup of the call to externalproject_add()
+ set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id}
+ CMAKE_ARGS ${extraflags} ${BUILD_ARGS}
+ PATCH_COMMAND ${PATCH_COMMAND}
+ ${INSTALL_COMMAND})
+
+ if(CMAKE_VERSION VERSION_GREATER 3.5.9)
+ list(APPEND EXTERNALPROJECT_SETUP GIT_SHALLOW 1)
+ endif()
+
+ # if there's an url defined we need to pass that to externalproject_add()
+ if(DEFINED url AND NOT "${url}" STREQUAL "")
+ # check if there's a third parameter in the file
+ if(deflength GREATER 2)
+ # the third parameter is considered as a revision of a git repository
+ list(GET def 2 revision)
+
+ externalproject_add(${id}
+ GIT_REPOSITORY ${url}
+ GIT_TAG ${revision}
+ ${EXTERNALPROJECT_SETUP})
+
+ # For patchfiles to work, disable (users globally set) autocrlf=true
+ if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER 3.7)
+ message(AUTHOR_WARNING "Make use of GIT_CONFIG")
+ endif()
+ if(WIN32 AND patches)
+ externalproject_add_step(${id} gitconfig
+ COMMAND git config core.autocrlf false
+ COMMAND git rm -rf --cached .
+ COMMAND git reset --hard HEAD
+ COMMENT "Performing gitconfig step: Disabling autocrlf to enable patching for '${id}'"
+ DEPENDERS patch
+ WORKING_DIRECTORY <SOURCE_DIR>)
+ endif()
+ else()
+ set(CONFIGURE_COMMAND "")
+ if(NOT WIN32)
+ # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH
+ set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig
+ ${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags} ${BUILD_ARGS}
+ ${BUILD_DIR}/${id}/src/${id}
+ -DPACKAGE_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig
+ -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -DOUTPUT_DIR=${OUTPUT_DIR}
+ -DCMAKE_PREFIX_PATH=${OUTPUT_DIR}
+ -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR}
+ -DCMAKE_INCLUDE_PATH=${OUTPUT_DIR}/include)
+ endif()
+
+ set(DOWNLOAD_DIR ${BUILD_DIR}/download)
+ if(EXISTS ${dir}/${id}.sha256)
+ file(STRINGS ${dir}/${id}.sha256 sha256sum)
+ list(GET sha256sum 0 sha256sum)
+ set(URL_HASH_COMMAND URL_HASH SHA256=${sha256sum})
+ if(TARBALL_DIR)
+ set(DOWNLOAD_DIR ${TARBALL_DIR})
+ endif()
+ else()
+ unset(URL_HASH_COMMAND)
+ message(AUTHOR_WARNING "${dir}/${id}.sha256 is missing")
+ endif()
+
+ externalproject_add(${id}
+ URL ${url}
+ "${URL_HASH_COMMAND}"
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+ ${EXTERNALPROJECT_SETUP})
+ endif()
+ else()
+ externalproject_add(${id}
+ SOURCE_DIR ${dir}
+ ${EXTERNALPROJECT_SETUP})
+ endif()
+
+ if(deps)
+ add_dependencies(${id} ${deps})
+ endif()
+ endif()
+
+ # if the dependency is available for the target platform add it to the list of the addon's dependencies
+ # (even if the target already exists as it still has to be built before the addon)
+ if(${platform_found})
+ list(APPEND ${addon}_DEPS ${id})
+ endif()
+ endif()
+ endforeach()
+
+ # make the ${addon}_DEPS variable available to the calling script
+ set(${addon}_DEPS "${${addon}_DEPS}" PARENT_SCOPE)
+endfunction()
+
diff --git a/cmake/scripts/common/Macros.cmake b/cmake/scripts/common/Macros.cmake
new file mode 100644
index 0000000..49198a1
--- /dev/null
+++ b/cmake/scripts/common/Macros.cmake
@@ -0,0 +1,789 @@
+# This script holds the main functions used to construct the build system
+
+# Include system specific macros but only if this file is included from
+# kodi main project. It's not needed for kodi-addons project
+# If CORE_SOURCE_DIR is set, it was called from kodi-addons project
+# TODO: drop check if we ever integrate kodi-addons into kodi project
+if(NOT CORE_SOURCE_DIR)
+ include(${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/Macros.cmake)
+endif()
+
+# IDEs: Group source files in target in folders (file system hierarchy)
+# Source: http://blog.audio-tk.com/2015/09/01/sorting-source-files-and-projects-in-folders-with-cmake-and-visual-studioxcode/
+# Arguments:
+# target The target that shall be grouped by folders.
+# Optional Arguments:
+# RELATIVE allows to specify a different reference folder.
+function(source_group_by_folder target)
+ if(NOT TARGET ${target})
+ message(FATAL_ERROR "There is no target named '${target}'")
+ endif()
+
+ set(SOURCE_GROUP_DELIMITER "/")
+
+ cmake_parse_arguments(arg "" "RELATIVE" "" ${ARGN})
+ if(arg_RELATIVE)
+ set(relative_dir ${arg_RELATIVE})
+ else()
+ set(relative_dir ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
+ get_property(files TARGET ${target} PROPERTY SOURCES)
+ if(files)
+ list(SORT files)
+
+ if(CMAKE_GENERATOR STREQUAL Xcode)
+ set_target_properties(${target} PROPERTIES SOURCES "${files}")
+ endif()
+ endif()
+ foreach(file ${files})
+ if(NOT IS_ABSOLUTE ${file})
+ set(file ${CMAKE_CURRENT_SOURCE_DIR}/${file})
+ endif()
+ file(RELATIVE_PATH relative_file ${relative_dir} ${file})
+ get_filename_component(dir "${relative_file}" DIRECTORY)
+ if(NOT dir STREQUAL "${last_dir}")
+ if(files)
+ source_group("${last_dir}" FILES ${files})
+ endif()
+ set(files "")
+ endif()
+ set(files ${files} ${file})
+ set(last_dir "${dir}")
+ endforeach(file)
+ if(files)
+ source_group("${last_dir}" FILES ${files})
+ endif()
+endfunction()
+
+# Add sources to main application
+# Arguments:
+# name name of the library to add
+# Implicit arguments:
+# ENABLE_STATIC_LIBS Build static libraries per directory
+# SOURCES the sources of the library
+# HEADERS the headers of the library (only for IDE support)
+# OTHERS other library related files (only for IDE support)
+# On return:
+# Library will be built, optionally added to ${core_DEPENDS}
+# Sets CORE_LIBRARY for calls for setting target specific options
+function(core_add_library name)
+ if(ENABLE_STATIC_LIBS)
+ add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
+ set_target_properties(${name} PROPERTIES PREFIX "")
+ set(core_DEPENDS ${name} ${core_DEPENDS} CACHE STRING "" FORCE)
+ add_dependencies(${name} ${GLOBAL_TARGET_DEPS})
+ set(CORE_LIBRARY ${name} PARENT_SCOPE)
+
+ if(NOT MSVC)
+ target_compile_options(${name} PUBLIC ${CORE_COMPILE_OPTIONS})
+ endif()
+
+ # Add precompiled headers to Kodi main libraries
+ if(CORE_SYSTEM_NAME MATCHES windows)
+ add_precompiled_header(${name} pch.h ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/pch.cpp PCH_TARGET kodi)
+ set_language_cxx(${name})
+ target_link_libraries(${name} PUBLIC effects11)
+ endif()
+ else()
+ foreach(src IN LISTS SOURCES HEADERS OTHERS)
+ get_filename_component(src_path "${src}" ABSOLUTE)
+ list(APPEND FILES ${src_path})
+ endforeach()
+ target_sources(lib${APP_NAME_LC} PRIVATE ${FILES})
+ set(CORE_LIBRARY lib${APP_NAME_LC} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Add a test library, and add sources to list for gtest integration macros
+function(core_add_test_library name)
+ if(ENABLE_STATIC_LIBS)
+ add_library(${name} STATIC ${SOURCES} ${SUPPORTED_SOURCES} ${HEADERS} ${OTHERS})
+ set_target_properties(${name} PROPERTIES PREFIX ""
+ EXCLUDE_FROM_ALL 1
+ FOLDER "Build Utilities/tests")
+ add_dependencies(${name} ${GLOBAL_TARGET_DEPS})
+ set(test_archives ${test_archives} ${name} CACHE STRING "" FORCE)
+
+ if(NOT MSVC)
+ target_compile_options(${name} PUBLIC ${CORE_COMPILE_OPTIONS})
+ endif()
+
+ endif()
+ foreach(src IN LISTS SOURCES SUPPORTED_SOURCES HEADERS OTHERS)
+ get_filename_component(src_path "${src}" ABSOLUTE)
+ set(test_sources "${src_path}" ${test_sources} CACHE STRING "" FORCE)
+ endforeach()
+endfunction()
+
+# Add addon dev kit headers to main application
+# Arguments:
+# name name of the header part to add
+function(core_add_devkit_header name)
+ if(NOT ENABLE_STATIC_LIBS)
+ core_add_library(addons_kodi-dev-kit_include_${name})
+ endif()
+endfunction()
+
+# Add an dl-loaded shared library
+# Arguments:
+# name name of the library to add
+# Optional arguments:
+# WRAPPED wrap this library on POSIX platforms to add VFS support for
+# libraries that would otherwise not support it.
+# OUTPUT_DIRECTORY where to create the library in the build dir
+# (default: system)
+# Implicit arguments:
+# SOURCES the sources of the library
+# HEADERS the headers of the library (only for IDE support)
+# OTHERS other library related files (only for IDE support)
+# On return:
+# Library target is defined and added to LIBRARY_FILES
+function(core_add_shared_library name)
+ cmake_parse_arguments(arg "WRAPPED" "OUTPUT_DIRECTORY" "" ${ARGN})
+ if(arg_OUTPUT_DIRECTORY)
+ set(OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY})
+ else()
+ if(NOT CORE_SYSTEM_NAME STREQUAL windows)
+ set(OUTPUT_DIRECTORY system)
+ endif()
+ endif()
+ if(CORE_SYSTEM_NAME STREQUAL windows)
+ set(OUTPUT_NAME lib${name})
+ else()
+ set(OUTPUT_NAME lib${name}-${ARCH})
+ endif()
+
+ if(NOT arg_WRAPPED OR CORE_SYSTEM_NAME STREQUAL windows)
+ add_library(${name} SHARED ${SOURCES} ${HEADERS} ${OTHERS})
+ set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
+ OUTPUT_NAME ${OUTPUT_NAME} PREFIX "")
+ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
+ string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
+ set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}
+ RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY})
+ endforeach()
+
+ set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${OUTPUT_DIRECTORY}/${OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX} CACHE STRING "" FORCE)
+ add_dependencies(${APP_NAME_LC}-libraries ${name})
+ else()
+ add_library(${name} STATIC ${SOURCES} ${HEADERS} ${OTHERS})
+ set_target_properties(${name} PROPERTIES POSITION_INDEPENDENT_CODE 1)
+ core_link_library(${name} ${OUTPUT_DIRECTORY}/lib${name})
+
+ if(NOT MSVC)
+ target_compile_options(${name} PUBLIC ${CORE_COMPILE_OPTIONS})
+ endif()
+ endif()
+endfunction()
+
+# Sets the compile language for all C source files in a target to CXX.
+# Needs to be called from the CMakeLists.txt that defines the target.
+# Arguments:
+# target target
+function(set_language_cxx target)
+ get_property(sources TARGET ${target} PROPERTY SOURCES)
+ foreach(file IN LISTS sources)
+ if(file MATCHES "\.c$")
+ set_source_files_properties(${file} PROPERTIES LANGUAGE CXX)
+ endif()
+ endforeach()
+endfunction()
+
+# Add a data file to installation list with a mirror in build tree
+# Mirroring files in the buildtree allows to execute the app from there.
+# Arguments:
+# file full path to file to mirror
+# Optional Arguments:
+# NO_INSTALL: exclude file from installation target (only mirror)
+# DIRECTORY: directory where the file should be mirrored to
+# (default: preserve tree structure relative to CMAKE_SOURCE_DIR)
+# KEEP_DIR_STRUCTURE: preserve tree structure even when DIRECTORY is set
+# On return:
+# Files is mirrored to the build tree and added to ${install_data}
+# (if NO_INSTALL is not given).
+function(copy_file_to_buildtree file)
+ cmake_parse_arguments(arg "NO_INSTALL" "DIRECTORY;KEEP_DIR_STRUCTURE" "" ${ARGN})
+ if(arg_DIRECTORY)
+ set(outdir ${arg_DIRECTORY})
+ if(arg_KEEP_DIR_STRUCTURE)
+ get_filename_component(srcdir ${arg_KEEP_DIR_STRUCTURE} DIRECTORY)
+ string(REPLACE "${CMAKE_SOURCE_DIR}/${srcdir}/" "" outfile ${file})
+ if(NOT IS_DIRECTORY ${file})
+ set(outdir ${outdir}/${outfile})
+ endif()
+ else()
+ get_filename_component(outfile ${file} NAME)
+ set(outfile ${outdir}/${outfile})
+ endif()
+ else()
+ string(REPLACE "${CMAKE_SOURCE_DIR}/" "" outfile ${file})
+ get_filename_component(outdir ${outfile} DIRECTORY)
+ endif()
+
+ if(NOT TARGET export-files)
+ file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
+ add_custom_target(export-files ALL COMMENT "Copying files into build tree"
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
+ set_target_properties(export-files PROPERTIES FOLDER "Build Utilities")
+ file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake "# Export files to build tree\n")
+ endif()
+
+ # Exclude autotools build artefacts and other blacklisted files in source tree.
+ if(file MATCHES "(Makefile|\\.in|\\.xbt|\\.so|\\.dylib|\\.gitignore)$")
+ if(VERBOSE)
+ message(STATUS "copy_file_to_buildtree - ignoring file: ${file}")
+ endif()
+ return()
+ endif()
+
+ if(NOT file STREQUAL ${CMAKE_BINARY_DIR}/${outfile})
+ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows" OR NOT IS_SYMLINK "${file}")
+ if(VERBOSE)
+ message(STATUS "copy_file_to_buildtree - copying file: ${file} -> ${CMAKE_BINARY_DIR}/${outfile}")
+ endif()
+ file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake
+ "file(COPY \"${file}\" DESTINATION \"${CMAKE_BINARY_DIR}/${outdir}\")\n" )
+ else()
+ if(VERBOSE)
+ message(STATUS "copy_file_to_buildtree - copying symlinked file: ${file} -> ${CMAKE_BINARY_DIR}/${outfile}")
+ endif()
+ file(APPEND ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake
+ "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy_if_different \"${file}\" \"${CMAKE_BINARY_DIR}/${outfile}\")\n")
+ endif()
+ endif()
+
+ if(NOT arg_NO_INSTALL)
+ list(APPEND install_data ${outfile})
+ set(install_data ${install_data} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Add data files to installation list with a mirror in build tree.
+# reads list of files to install from a given list of text files.
+# Arguments:
+# pattern globbing pattern for text files to read
+# Optional Arguments:
+# NO_INSTALL: exclude files from installation target
+# Implicit arguments:
+# CMAKE_SOURCE_DIR - root of source tree
+# On return:
+# Files are mirrored to the build tree and added to ${install_data}
+# (if NO_INSTALL is not given).
+function(copy_files_from_filelist_to_buildtree pattern)
+ # copies files listed in text files to the buildtree
+ # Input: [glob pattern: filepattern]
+ cmake_parse_arguments(arg "NO_INSTALL" "" "" ${ARGN})
+ list(APPEND pattern ${ARGN})
+ list(SORT pattern)
+ if(VERBOSE)
+ message(STATUS "copy_files_from_filelist_to_buildtree - got pattern: ${pattern}")
+ endif()
+ foreach(pat ${pattern})
+ file(GLOB filenames ${pat})
+ foreach(filename ${filenames})
+ string(STRIP ${filename} filename)
+ core_file_read_filtered(fstrings ${filename})
+ foreach(dir ${fstrings})
+ string(CONFIGURE ${dir} dir)
+ string(REPLACE " " ";" dir ${dir})
+ list(GET dir 0 src)
+ list(LENGTH dir len)
+ if(len EQUAL 1)
+ set(dest)
+ elseif(len EQUAL 3)
+ list(GET dir 1 opt)
+ if(opt STREQUAL "KEEP_DIR_STRUCTURE")
+ set(DIR_OPTION ${opt} ${src})
+ if(VERBOSE)
+ message(STATUS "copy_files_from_filelist_to_buildtree - DIR_OPTION: ${DIR_OPTION}")
+ endif()
+ endif()
+ list(GET dir -1 dest)
+ else()
+ list(GET dir -1 dest)
+ endif()
+
+ # If the full path to an existing file is specified then add that single file.
+ # Don't recursively add all files with the given name.
+ if(EXISTS ${CMAKE_SOURCE_DIR}/${src} AND (NOT IS_DIRECTORY ${CMAKE_SOURCE_DIR}/${src} OR DIR_OPTION))
+ set(files ${src})
+ else()
+ file(GLOB_RECURSE files RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/${src})
+ endif()
+
+ foreach(file ${files})
+ if(arg_NO_INSTALL)
+ copy_file_to_buildtree(${CMAKE_SOURCE_DIR}/${file} DIRECTORY ${dest} NO_INSTALL ${DIR_OPTION})
+ else()
+ copy_file_to_buildtree(${CMAKE_SOURCE_DIR}/${file} DIRECTORY ${dest} ${DIR_OPTION})
+ endif()
+ endforeach()
+ set(DIR_OPTION)
+ endforeach()
+ endforeach()
+ endforeach()
+ set(install_data ${install_data} PARENT_SCOPE)
+endfunction()
+
+# helper macro to set modified variables in parent scope
+macro(export_dep)
+ set(SYSTEM_INCLUDES ${SYSTEM_INCLUDES} PARENT_SCOPE)
+ set(DEPLIBS ${DEPLIBS} PARENT_SCOPE)
+ set(DEP_DEFINES ${DEP_DEFINES} PARENT_SCOPE)
+ set(${depup}_FOUND ${${depup}_FOUND} PARENT_SCOPE)
+ mark_as_advanced(${depup}_LIBRARIES)
+endmacro()
+
+# split dependency specification to name and version
+# Arguments:
+# depspec dependency specification that can optionally include a required
+# package version
+# syntax: [package name], [package name]>=[version] (minimum version),
+# or [package name]=[version] (exact version)
+# name_outvar variable that should receive the package name
+# version_outvar variable that should receive the package version part (>=[version])
+# On return:
+# ${name_outvar} and ${version_outvar} in caller scope are set to respective values.
+# ${version_outvar} may be unset if there is no specific version requested.
+function(split_dependency_specification depspec name_outvar version_outvar)
+ if(${depspec} MATCHES "^([^>]*)(>?=[0-9.]+)$")
+ set(${name_outvar} ${CMAKE_MATCH_1} PARENT_SCOPE)
+ set(${version_outvar} ${CMAKE_MATCH_2} PARENT_SCOPE)
+ else()
+ set(${name_outvar} ${depspec} PARENT_SCOPE)
+ unset(${version_outvar} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# helper macro to split version info from req and call find_package
+macro(find_package_with_ver package)
+ set(_find_arguments "${ARGN}")
+ if("${ARGV1}" MATCHES "^(>)?=([0-9.]+)$")
+ # We have a version spec, parse it
+ list(REMOVE_AT _find_arguments 0)
+ # ">" not present? -> exact match
+ if(NOT CMAKE_MATCH_1)
+ list(INSERT _find_arguments 0 "EXACT")
+ endif()
+ find_package(${package} ${CMAKE_MATCH_2} ${_find_arguments})
+ else()
+ find_package(${package} ${_find_arguments})
+ endif()
+ unset(_find_arguments)
+endmacro()
+
+# add required dependencies of main application
+# Arguments:
+# dep_list One or many dependency specifications (see split_dependency_specification)
+# for syntax). The dependency name is used uppercased as variable prefix.
+# On return:
+# dependencies added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
+function(core_require_dep)
+ foreach(depspec ${ARGN})
+ split_dependency_specification(${depspec} dep version)
+ find_package_with_ver(${dep} ${version} REQUIRED)
+ string(TOUPPER ${dep} depup)
+ list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
+ list(APPEND DEPLIBS ${${depup}_LIBRARIES})
+ list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
+ export_dep()
+ endforeach()
+endfunction()
+
+# helper macro for optional deps
+macro(setup_enable_switch)
+ string(TOUPPER ${dep} depup)
+ if(${ARGV1})
+ set(enable_switch ${ARGV1})
+ else()
+ set(enable_switch ENABLE_${depup})
+ endif()
+ # normal options are boolean, so we override set our ENABLE_FOO var to allow "auto" handling
+ set(${enable_switch} "AUTO" CACHE STRING "Enable ${depup} support?")
+endmacro()
+
+# add optional dependencies of main application
+# Arguments:
+# dep_list One or many dependency specifications (see split_dependency_specification)
+# for syntax). The dependency name is used uppercased as variable prefix.
+# On return:
+# dependency optionally added to ${SYSTEM_INCLUDES}, ${DEPLIBS} and ${DEP_DEFINES}
+function(core_optional_dep)
+ foreach(depspec ${ARGN})
+ set(_required False)
+ split_dependency_specification(${depspec} dep version)
+ setup_enable_switch()
+ if(${enable_switch} STREQUAL AUTO)
+ find_package_with_ver(${dep} ${version})
+ elseif(${${enable_switch}})
+ find_package_with_ver(${dep} ${version} REQUIRED)
+ set(_required True)
+ endif()
+
+ if(${depup}_FOUND)
+ list(APPEND SYSTEM_INCLUDES ${${depup}_INCLUDE_DIRS})
+ list(APPEND DEPLIBS ${${depup}_LIBRARIES})
+ list(APPEND DEP_DEFINES ${${depup}_DEFINITIONS})
+ set(final_message ${final_message} "${depup} enabled: Yes")
+ export_dep()
+ elseif(_required)
+ message(FATAL_ERROR "${depup} enabled but not found")
+ else()
+ set(final_message ${final_message} "${depup} enabled: No")
+ endif()
+ endforeach()
+ set(final_message ${final_message} PARENT_SCOPE)
+endfunction()
+
+function(core_file_read_filtered result filepattern)
+ # Reads STRINGS from text files
+ # with comments filtered out
+ # Result: [list: result]
+ # Input: [glob pattern: filepattern]
+ file(GLOB filenames ${filepattern})
+ list(SORT filenames)
+ foreach(filename ${filenames})
+ if(VERBOSE)
+ message(STATUS "core_file_read_filtered - filename: ${filename}")
+ endif()
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename})
+ file(STRINGS ${filename} fstrings REGEX "^[^#//]")
+ foreach(fstring ${fstrings})
+ string(REGEX REPLACE "^(.*)#(.*)" "\\1" fstring ${fstring})
+ string(REGEX REPLACE "[ \n\r\t]//.*" "" fstring ${fstring})
+ string(STRIP ${fstring} fstring)
+ list(APPEND filename_strings ${fstring})
+ endforeach()
+ endforeach()
+ set(${result} ${filename_strings} PARENT_SCOPE)
+endfunction()
+
+function(core_add_subdirs_from_filelist files)
+ # Adds subdirectories from a sorted list of files
+ # Input: [list: filenames] [bool: sort]
+ foreach(arg ${ARGN})
+ list(APPEND files ${arg})
+ endforeach()
+ list(SORT files)
+ if(VERBOSE)
+ message(STATUS "core_add_subdirs_from_filelist - got pattern: ${files}")
+ endif()
+ foreach(filename ${files})
+ string(STRIP ${filename} filename)
+ core_file_read_filtered(fstrings ${filename})
+ foreach(subdir ${fstrings})
+ string(REPLACE " " ";" subdir ${subdir})
+ list(GET subdir 0 subdir_src)
+ list(GET subdir -1 subdir_dest)
+ if(VERBOSE)
+ message(STATUS " core_add_subdirs_from_filelist - adding subdir: ${CMAKE_SOURCE_DIR}/${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
+ endif()
+ add_subdirectory(${CMAKE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
+ endforeach()
+ endforeach()
+endfunction()
+
+macro(core_add_optional_subdirs_from_filelist pattern)
+ # Adds subdirectories from text files
+ # if the option(s) in the 3rd field are enabled
+ # Input: [glob pattern: filepattern]
+ foreach(arg ${ARGN})
+ list(APPEND pattern ${arg})
+ endforeach()
+ foreach(elem ${pattern})
+ string(STRIP ${elem} elem)
+ list(APPEND filepattern ${elem})
+ endforeach()
+
+ file(GLOB filenames ${filepattern})
+ list(SORT filenames)
+ if(VERBOSE)
+ message(STATUS "core_add_optional_subdirs_from_filelist - got pattern: ${filenames}")
+ endif()
+
+ foreach(filename ${filenames})
+ if(VERBOSE)
+ message(STATUS "core_add_optional_subdirs_from_filelist - reading file: ${filename}")
+ endif()
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename})
+ file(STRINGS ${filename} fstrings REGEX "^[^#//]")
+ foreach(line ${fstrings})
+ string(REPLACE " " ";" line "${line}")
+ list(GET line 0 subdir_src)
+ list(GET line 1 subdir_dest)
+ list(GET line 3 opts)
+ foreach(opt ${opts})
+ if(ENABLE_${opt})
+ if(VERBOSE)
+ message(STATUS " core_add_optional_subdirs_from_filelist - adding subdir: ${CMAKE_SOURCE_DIR}/${subdir_src} -> ${CORE_BUILD_DIR}/${subdir_dest}")
+ endif()
+ add_subdirectory(${CMAKE_SOURCE_DIR}/${subdir_src} ${CORE_BUILD_DIR}/${subdir_dest})
+ else()
+ if(VERBOSE)
+ message(STATUS " core_add_optional_subdirs_from_filelist: OPTION ${opt} not enabled for ${subdir_src}, skipping subdir")
+ endif()
+ endif()
+ endforeach()
+ endforeach()
+ endforeach()
+endmacro()
+
+# Generates an RFC2822 timestamp
+#
+# The following variable is set:
+# RFC2822_TIMESTAMP
+function(rfc2822stamp)
+ execute_process(COMMAND date -R
+ OUTPUT_VARIABLE RESULT)
+ set(RFC2822_TIMESTAMP ${RESULT} PARENT_SCOPE)
+endfunction()
+
+# Generates an user stamp from git config info
+#
+# The following variable is set:
+# PACKAGE_MAINTAINER - user stamp in the form of "username <username@example.com>"
+# if no git tree is found, value is set to "nobody <nobody@example.com>"
+function(userstamp)
+ find_package(Git)
+ if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
+ execute_process(COMMAND ${GIT_EXECUTABLE} config user.name
+ OUTPUT_VARIABLE username
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND ${GIT_EXECUTABLE} config user.email
+ OUTPUT_VARIABLE useremail
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(PACKAGE_MAINTAINER "${username} <${useremail}>" PARENT_SCOPE)
+ else()
+ set(PACKAGE_MAINTAINER "nobody <nobody@example.com>" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Parses git info and sets variables used to identify the build
+# Arguments:
+# stamp variable name to return
+# Optional Arguments:
+# FULL: generate git HEAD commit in the form of 'YYYYMMDD-hash'
+# if git tree is dirty, value is set in the form of 'YYYYMMDD-hash-dirty'
+# if no git tree is found, value is set in the form of 'YYYYMMDD-nogitfound'
+# if FULL is not given, stamp is generated following the same process as above
+# but without 'YYYYMMDD'
+# On return:
+# Variable is set with generated stamp to PARENT_SCOPE
+function(core_find_git_rev stamp)
+ # allow manual setting GIT_VERSION
+ if(GIT_VERSION)
+ set(${stamp} ${GIT_VERSION} PARENT_SCOPE)
+ string(TIMESTAMP APP_BUILD_DATE "%Y%m%d" UTC)
+ set(APP_BUILD_DATE ${APP_BUILD_DATE} PARENT_SCOPE)
+ else()
+ find_package(Git)
+ if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
+ # get tree status i.e. clean working tree vs dirty (uncommitted or unstashed changes, etc.)
+ execute_process(COMMAND ${GIT_EXECUTABLE} update-index --ignore-submodules -q --refresh
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ execute_process(COMMAND ${GIT_EXECUTABLE} diff-files --ignore-submodules --quiet --
+ RESULT_VARIABLE status_code
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ if(NOT status_code)
+ execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --ignore-submodules --quiet HEAD --
+ RESULT_VARIABLE status_code
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ endif()
+ # get HEAD commit SHA-1
+ execute_process(COMMAND ${GIT_EXECUTABLE} log -n 1 --pretty=format:"%h" HEAD
+ OUTPUT_VARIABLE HASH
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ string(REPLACE "\"" "" HASH ${HASH})
+
+ if(status_code)
+ string(CONCAT HASH ${HASH} "-dirty")
+ endif()
+
+ # get HEAD commit date
+ execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%cd" --date=short HEAD
+ OUTPUT_VARIABLE DATE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ string(REPLACE "\"" "" DATE ${DATE})
+ string(REPLACE "-" "" DATE ${DATE})
+
+ # build date
+ string(TIMESTAMP APP_BUILD_DATE "%Y%m%d" UTC)
+ set(APP_BUILD_DATE ${APP_BUILD_DATE} PARENT_SCOPE)
+ else()
+ if(EXISTS ${CMAKE_SOURCE_DIR}/BUILDDATE)
+ file(STRINGS ${CMAKE_SOURCE_DIR}/BUILDDATE DATE LIMIT_INPUT 8)
+ else()
+ string(TIMESTAMP DATE "%Y%m%d" UTC)
+ endif()
+ set(APP_BUILD_DATE ${DATE} PARENT_SCOPE)
+
+ if(EXISTS ${CMAKE_SOURCE_DIR}/VERSION)
+ file(STRINGS ${CMAKE_SOURCE_DIR}/VERSION HASH LIMIT_INPUT 16)
+ else()
+ set(HASH "nogitfound")
+ endif()
+ endif()
+ cmake_parse_arguments(arg "FULL" "" "" ${ARGN})
+ if(arg_FULL)
+ set(${stamp} ${DATE}-${HASH} PARENT_SCOPE)
+ else()
+ set(${stamp} ${HASH} PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+# Parses version.txt and versions.h and sets variables
+# used to construct dirs structure, file naming, API version, etc.
+#
+# The following variables are set from version.txt:
+# APP_NAME - app name
+# APP_NAME_LC - lowercased app name
+# APP_NAME_UC - uppercased app name
+# APP_PACKAGE - Android full package name
+# COMPANY_NAME - company name
+# APP_WEBSITE - site url
+# APP_VERSION_MAJOR - the app version major
+# APP_VERSION_MINOR - the app version minor
+# APP_VERSION_TAG - the app version tag
+# APP_VERSION_TAG_LC - lowercased app version tag
+# APP_VERSION - the app version (${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}-${APP_VERSION_TAG})
+# APP_ADDON_API - the addon API version in the form of 16.9.702
+# ADDON_REPOS - official addon repositories and their origin path delimited by pipe
+# - e.g. repository.xbmc.org|https://mirrors.kodi.tv -
+# (multiple repo/path-sets are delimited by comma)
+# FILE_VERSION - file version in the form of 16,9,702,0 - Windows only
+# JSONRPC_VERSION - the json api version in the form of 8.3.0
+#
+# Set various variables defined in "versions.h"
+macro(core_find_versions)
+ # kodi-addons project also calls this macro and uses CORE_SOURCE_DIR
+ # to point to core base dir
+ # Set CORE_SOURCE_DIR here, otherwise kodi main project fails
+ # TODO: drop this code block and refactor the rest to use CMAKE_SOURCE_DIR
+ # if we ever integrate kodi-addons into kodi project
+ if(NOT CORE_SOURCE_DIR)
+ set(CORE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+ endif()
+
+ include(CMakeParseArguments)
+ core_file_read_filtered(version_list ${CORE_SOURCE_DIR}/version.txt)
+ core_file_read_filtered(json_version ${CORE_SOURCE_DIR}/xbmc/interfaces/json-rpc/schema/version.txt)
+ string(REGEX REPLACE "([^ ;]*) ([^;]*)" "\\1;\\2" version_list "${version_list};${json_version}")
+ set(version_props
+ ADDON_API
+ ADDON_REPOS
+ APP_NAME
+ APP_PACKAGE
+ COMPANY_NAME
+ COPYRIGHT_YEARS
+ JSONRPC_VERSION
+ PACKAGE_DESCRIPTION
+ PACKAGE_IDENTITY
+ PACKAGE_PUBLISHER
+ VERSION_MAJOR
+ VERSION_MINOR
+ VERSION_TAG
+ VERSION_CODE
+ WEBSITE
+ )
+ cmake_parse_arguments(APP "" "${version_props}" "" ${version_list})
+
+ if(NOT ${APP_VERSION_CODE} MATCHES "^[0-9]+\\.[0-9][0-9]?\\.[0-9][0-9]?[0-9]?$")
+ message(FATAL_ERROR "VERSION_CODE was set to ${APP_VERSION_CODE} in version.txt, but it has to match '^\\d+\\.\\d{1,2}\\.\\d{1,3}$'")
+ endif()
+ set(APP_NAME ${APP_APP_NAME}) # inconsistency but APP_APP_NAME looks weird
+ string(TOLOWER ${APP_APP_NAME} APP_NAME_LC)
+ string(TOUPPER ${APP_APP_NAME} APP_NAME_UC)
+ set(COMPANY_NAME ${APP_COMPANY_NAME})
+ set(APP_VERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR})
+ # Let Flatpak builders etc override APP_PACKAGE
+ # NOTE: We cannot declare an option() in top-level CMakeLists.txt
+ # because of CMP0077.
+ if(NOT APP_PACKAGE)
+ set(APP_PACKAGE ${APP_APP_PACKAGE})
+ endif()
+ list(APPEND final_message "App package: ${APP_PACKAGE}")
+ if(APP_VERSION_TAG)
+ set(APP_VERSION ${APP_VERSION}-${APP_VERSION_TAG})
+ string(TOLOWER ${APP_VERSION_TAG} APP_VERSION_TAG_LC)
+ endif()
+ string(REPLACE "." "," FILE_VERSION ${APP_ADDON_API}.0)
+ set(ADDON_REPOS ${APP_ADDON_REPOS})
+ set(JSONRPC_VERSION ${APP_JSONRPC_VERSION})
+
+ # Set defines used in addon.xml.in and read from versions.h to set add-on
+ # version parts automatically
+ # This part is nearly identical to "AddonHelpers.cmake", except location of versions.h
+ file(STRINGS ${CORE_SOURCE_DIR}/xbmc/addons/kodi-dev-kit/include/kodi/versions.h BIN_ADDON_PARTS)
+ foreach(loop_var ${BIN_ADDON_PARTS})
+ string(FIND "${loop_var}" "#define ADDON_" matchres)
+ if("${matchres}" EQUAL 0)
+ string(REGEX MATCHALL "[A-Z0-9._]+|[A-Z0-9._]+$" loop_var "${loop_var}")
+ list(GET loop_var 0 include_name)
+ list(GET loop_var 1 include_version)
+ string(REGEX REPLACE ".*\"(.*)\"" "\\1" ${include_name} ${include_version})
+ endif()
+ endforeach(loop_var)
+
+ # unset variables not used anywhere else
+ unset(version_list)
+ unset(APP_APP_NAME)
+ unset(APP_COMPANY_NAME)
+ unset(APP_APP_PACKAGE)
+ unset(APP_JSONRPC_VERSION)
+ unset(BIN_ADDON_PARTS)
+
+ # bail if we can't parse version.txt
+ if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR)
+ message(FATAL_ERROR "Could not determine app version! Make sure that ${CORE_SOURCE_DIR}/version.txt exists")
+ endif()
+ if(NOT DEFINED JSONRPC_VERSION)
+ message(FATAL_ERROR "Could not determine json-rpc version! Make sure that ${CORE_SOURCE_DIR}/xbmc/interfaces/json-rpc/schema/version.txt exists")
+ endif()
+endmacro()
+
+# add-on xml's
+# find all folders containing addon.xml.in and used to define
+# ADDON_XML_OUTPUTS, ADDON_XML_DEPENDS and ADDON_INSTALL_DATA
+macro(find_addon_xml_in_files)
+ set(filter ${ARGV0})
+
+ if(filter AND VERBOSE)
+ message(STATUS "find_addon_xml_in_files: filtering ${filter}")
+ endif()
+
+ file(GLOB ADDON_XML_IN_FILE ${CMAKE_SOURCE_DIR}/addons/*/addon.xml.in)
+ foreach(loop_var ${ADDON_XML_IN_FILE})
+ list(GET loop_var 0 xml_name)
+
+ string(REPLACE "/addon.xml.in" "" xml_name ${xml_name})
+ string(REPLACE "${CORE_SOURCE_DIR}/" "" xml_name ${xml_name})
+
+ list(APPEND ADDON_XML_DEPENDS "${CORE_SOURCE_DIR}/${xml_name}/addon.xml.in")
+ if(filter AND NOT xml_name MATCHES ${filter})
+ list(APPEND ADDON_XML_OUTPUTS "${CMAKE_BINARY_DIR}/${xml_name}/addon.xml")
+ endif()
+
+ # Read content of add-on folder to have on install
+ file(GLOB ADDON_FILES "${CORE_SOURCE_DIR}/${xml_name}/*")
+ foreach(loop_var ${ADDON_FILES})
+ if(loop_var MATCHES "addon.xml.in")
+ string(REPLACE "addon.xml.in" "addon.xml" loop_var ${loop_var})
+
+ list(GET loop_var 0 file_name)
+ string(REPLACE "${CORE_SOURCE_DIR}/" "" file_name ${file_name})
+ list(APPEND ADDON_INSTALL_DATA "${file_name}")
+
+ unset(file_name)
+ endif()
+ endforeach()
+ unset(xml_name)
+ endforeach()
+
+ # Append also versions.h to depends
+ list(APPEND ADDON_XML_DEPENDS "${CORE_SOURCE_DIR}/xbmc/addons/kodi-dev-kit/include/kodi/versions.h")
+endmacro()
diff --git a/cmake/scripts/common/ModuleHelpers.cmake b/cmake/scripts/common/ModuleHelpers.cmake
new file mode 100644
index 0000000..97a3901
--- /dev/null
+++ b/cmake/scripts/common/ModuleHelpers.cmake
@@ -0,0 +1,424 @@
+# This script provides helper functions for FindModules
+
+# Parse and set variables from VERSION dependency file
+# On return:
+# MODULENAME_ARCHIVE will be set to parent scope
+# MODULENAME_VER will be set to parent scope (eg FFMPEG_VER, DAV1D_VER)
+# MODULENAME_BASE_URL will be set to parent scope if exists in VERSION file (eg FFMPEG_BASE_URL)
+# MODULENAME_HASH will be set if either SHA256 or SHA512 exists in VERSION file
+# MODULENAME_BYPRODUCT will be set to parent scope
+function(get_versionfile_data)
+
+ # Dependency path
+ set(MODULE_PATH "${PROJECTSOURCE}/tools/depends/${LIB_TYPE}/${MODULE_LC}")
+
+ if(NOT EXISTS "${MODULE_PATH}/${MODULE}-VERSION")
+ MESSAGE(FATAL_ERROR "${MODULE}-VERSION does not exist at ${MODULE_PATH}.")
+ else()
+ set(${MODULE}_FILE "${MODULE_PATH}/${MODULE}-VERSION")
+ endif()
+
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_LNAME REGEX "^[ \t]*LIBNAME=")
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_VER REGEX "^[ \t]*VERSION=")
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_ARCHIVE REGEX "^[ \t]*ARCHIVE=")
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_BASE_URL REGEX "^[ \t]*BASE_URL=")
+ if(WIN32 OR WINDOWS_STORE)
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_BYPRODUCT REGEX "^[ \t]*BYPRODUCT_WIN=")
+ else()
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_BYPRODUCT REGEX "^[ \t]*BYPRODUCT=")
+ endif()
+
+ # Tarball Hash
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_HASH_SHA256 REGEX "^[ \t]*SHA256=")
+ file(STRINGS ${${MODULE}_FILE} ${MODULE}_HASH_SHA512 REGEX "^[ \t]*SHA512=")
+
+ string(REGEX REPLACE ".*LIBNAME=([^ \t]*).*" "\\1" ${MODULE}_LNAME "${${MODULE}_LNAME}")
+ string(REGEX REPLACE ".*VERSION=([^ \t]*).*" "\\1" ${MODULE}_VER "${${MODULE}_VER}")
+ string(REGEX REPLACE ".*ARCHIVE=([^ \t]*).*" "\\1" ${MODULE}_ARCHIVE "${${MODULE}_ARCHIVE}")
+ string(REGEX REPLACE ".*BASE_URL=([^ \t]*).*" "\\1" ${MODULE}_BASE_URL "${${MODULE}_BASE_URL}")
+ if(WIN32 OR WINDOWS_STORE)
+ string(REGEX REPLACE ".*BYPRODUCT_WIN=([^ \t]*).*" "\\1" ${MODULE}_BYPRODUCT "${${MODULE}_BYPRODUCT}")
+ else()
+ string(REGEX REPLACE ".*BYPRODUCT=([^ \t]*).*" "\\1" ${MODULE}_BYPRODUCT "${${MODULE}_BYPRODUCT}")
+ endif()
+
+ string(REGEX REPLACE "\\$\\(LIBNAME\\)" "${${MODULE}_LNAME}" ${MODULE}_ARCHIVE "${${MODULE}_ARCHIVE}")
+ string(REGEX REPLACE "\\$\\(VERSION\\)" "${${MODULE}_VER}" ${MODULE}_ARCHIVE "${${MODULE}_ARCHIVE}")
+
+ set(${MODULE}_ARCHIVE ${${MODULE}_ARCHIVE} PARENT_SCOPE)
+
+ set(${MODULE}_VER ${${MODULE}_VER} PARENT_SCOPE)
+
+ if (${MODULE}_BASE_URL)
+ set(${MODULE}_BASE_URL ${${MODULE}_BASE_URL} PARENT_SCOPE)
+ else()
+ set(${MODULE}_BASE_URL "http://mirrors.kodi.tv/build-deps/sources" PARENT_SCOPE)
+ endif()
+ set(${MODULE}_BYPRODUCT ${${MODULE}_BYPRODUCT} PARENT_SCOPE)
+
+ # allow user to override the download URL hash with a local tarball hash
+ # needed for offline build envs
+ if (NOT DEFINED ${MODULE}_HASH)
+ if (${MODULE}_HASH_SHA256)
+ set(${MODULE}_HASH ${${MODULE}_HASH_SHA256} PARENT_SCOPE)
+ elseif(${MODULE}_HASH_SHA512)
+ set(${MODULE}_HASH ${${MODULE}_HASH_SHA512} PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+# Parse and set Version from VERSION dependency file
+# Used for retrieving version numbers for dependency libs to allow setting
+# a required version for find_package call
+# On return:
+# LIB_MODULENAME_VER will be set to parent scope (eg LIB_FMT_VER)
+function(get_libversion_data module libtype)
+
+ # Dependency path
+ set(LIB_MODULE_PATH "${CMAKE_SOURCE_DIR}/tools/depends/${libtype}/${module}")
+ string(TOUPPER ${module} MOD_UPPER)
+
+ if(NOT EXISTS "${LIB_MODULE_PATH}/${MOD_UPPER}-VERSION")
+ MESSAGE(FATAL_ERROR "${MOD_UPPER}-VERSION does not exist at ${LIB_MODULE_PATH}.")
+ else()
+ set(${MOD_UPPER}_FILE "${LIB_MODULE_PATH}/${MOD_UPPER}-VERSION")
+ endif()
+
+ file(STRINGS ${${MOD_UPPER}_FILE} ${MOD_UPPER}_VER REGEX "^[ \t]*VERSION=")
+
+ string(REGEX REPLACE ".*VERSION=([^ \t]*).*" "\\1" ${MOD_UPPER}_VER "${${MOD_UPPER}_VER}")
+
+ set(LIB_${MOD_UPPER}_VER ${${MOD_UPPER}_VER} PARENT_SCOPE)
+endfunction()
+
+# Function to loop through list of patch files (full path)
+# Sets to a PATCH_COMMAND variable and set to parent scope (caller)
+# Used to test windows line endings and set appropriate patch commands
+function(generate_patchcommand _patchlist)
+ # find the path to the patch executable
+ find_package(Patch MODULE REQUIRED)
+
+ # Loop through patches and add to PATCH_COMMAND
+ # for windows, check CRLF/LF state
+
+ set(_count 0)
+ foreach(patch ${_patchlist})
+ if(WIN32 OR WINDOWS_STORE)
+ PATCH_LF_CHECK(${patch})
+ endif()
+ if(${_count} EQUAL "0")
+ set(_patch_command ${PATCH_EXECUTABLE} -p1 -i ${patch})
+ else()
+ list(APPEND _patch_command COMMAND ${PATCH_EXECUTABLE} -p1 -i ${patch})
+ endif()
+
+ math(EXPR _count "${_count}+1")
+ endforeach()
+ set(PATCH_COMMAND ${_patch_command} PARENT_SCOPE)
+ unset(_count)
+ unset(_patch_command)
+endfunction()
+
+# Macro to factor out the repetitive URL setup
+macro(SETUP_BUILD_VARS)
+ string(TOUPPER ${MODULE_LC} MODULE)
+
+ # Fall through to target build module dir if not explicitly set
+ if(NOT DEFINED LIB_TYPE)
+ set(LIB_TYPE "target")
+ endif()
+
+ # Location for build type, native or target
+ if(LIB_TYPE STREQUAL "target")
+ set(DEP_LOCATION "${DEPENDS_PATH}")
+ else()
+ set(DEP_LOCATION "${NATIVEPREFIX}")
+ endif()
+
+ # PROJECTSOURCE used in native toolchain to provide core project sourcedir
+ # to externalproject_add targets that have a different CMAKE_SOURCE_DIR (eg jsonschema/texturepacker in-tree)
+ if(NOT PROJECTSOURCE)
+ set(PROJECTSOURCE ${CMAKE_SOURCE_DIR})
+ endif()
+
+ # populate variables of data from VERSION file for MODULE
+ get_versionfile_data()
+
+ # allow user to override the download URL with a local tarball
+ # needed for offline build envs
+ if(${MODULE}_URL)
+ get_filename_component(${MODULE}_URL "${${MODULE}_URL}" ABSOLUTE)
+ else()
+ set(${MODULE}_URL ${${MODULE}_BASE_URL}/${${MODULE}_ARCHIVE})
+ endif()
+ if(VERBOSE)
+ message(STATUS "MODULE: ${MODULE}")
+ message(STATUS "LIB_TYPE: ${LIB_TYPE}")
+ message(STATUS "DEP_LOCATION: ${DEP_LOCATION}")
+ message(STATUS "PROJECTSOURCE: ${PROJECTSOURCE}")
+ message(STATUS "${MODULE}_URL: ${${MODULE}_URL}")
+ endif()
+endmacro()
+
+macro(CLEAR_BUILD_VARS)
+ # unset all generic variables to insure clean state between macro calls
+ # Potentially an issue with scope when a macro is used inside a dep that uses a macro
+ unset(PROJECTSOURCE)
+ unset(LIB_TYPE)
+ unset(BUILD_NAME)
+ unset(INSTALL_DIR)
+ unset(CMAKE_ARGS)
+ unset(PATCH_COMMAND)
+ unset(CONFIGURE_COMMAND)
+ unset(BUILD_COMMAND)
+ unset(INSTALL_COMMAND)
+ unset(BUILD_IN_SOURCE)
+ unset(BUILD_BYPRODUCTS)
+ unset(WIN_DISABLE_PROJECT_FLAGS)
+
+ # unset all module specific variables to insure clean state between macro calls
+ # potentially an issue when a native and a target of the same module exists
+ unset(${MODULE}_LIST_SEPARATOR)
+ unset(${MODULE}_GENERATOR)
+ unset(${MODULE}_GENERATOR_PLATFORM)
+ unset(${MODULE}_INSTALL_PREFIX)
+ unset(${MODULE}_TOOLCHAIN_FILE)
+endmacro()
+
+# Macro to create externalproject_add target
+#
+# Common usage
+#
+# CMAKE_ARGS: cmake(required)
+# PATCH_COMMAND: ALL(optional)
+# CONFIGURE_COMMAND: autoconf(required), meson(required)
+# BUILD_COMMAND: autoconf(required), meson(required), cmake(optional)
+# INSTALL_COMMAND: autoconf(required), meson(required), cmake(optional)
+# BUILD_IN_SOURCE: ALL(optional)
+# BUILD_BYPRODUCTS: ALL(optional)
+#
+# Windows Specific
+# WIN_DISABLE_PROJECT_FLAGS - Set to not use core compiler flags for externalproject_add target
+# This removes CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS
+# from the externalproject_add target. Primarily used for HOST build
+# tools that may have different arch/build requirements to the core app
+# target (eg flatc)
+#
+macro(BUILD_DEP_TARGET)
+ include(ExternalProject)
+
+ # Remove cmake warning when Xcode generator used with "New" build system
+ if(CMAKE_GENERATOR STREQUAL Xcode)
+ # Policy CMP0114 is not set to NEW. In order to support the Xcode "new build
+ # system", this project must be updated to set policy CMP0114 to NEW.
+ if(CMAKE_XCODE_BUILD_SYSTEM STREQUAL 12)
+ cmake_policy(SET CMP0114 NEW)
+ else()
+ cmake_policy(SET CMP0114 OLD)
+ endif()
+ endif()
+
+ if(CMAKE_ARGS)
+ set(CMAKE_ARGS CMAKE_ARGS ${CMAKE_ARGS}
+ -DCMAKE_INSTALL_LIBDIR=lib
+ -DPROJECTSOURCE=${PROJECTSOURCE}
+ "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
+
+ # We dont have a toolchain for windows, so manually add all the cmake
+ # build arguments we may want
+ # We can disable adding them with WIN_DISABLE_PROJECT_FLAGS. This is potentially required
+ # for host build tools (eg flatc) that may be a different arch to the core app
+ if(WIN32 OR WINDOWS_STORE)
+ if(NOT DEFINED WIN_DISABLE_PROJECT_FLAGS)
+ list(APPEND CMAKE_ARGS "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} $<$<CONFIG:Debug>:${CMAKE_C_FLAGS_DEBUG}> $<$<CONFIG:Release>:${CMAKE_C_FLAGS_RELEASE}> ${${MODULE}_C_FLAGS}"
+ "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} $<$<CONFIG:Debug>:${CMAKE_CXX_FLAGS_DEBUG}> $<$<CONFIG:Release>:${CMAKE_CXX_FLAGS_RELEASE}> ${${MODULE}_CXX_FLAGS}"
+ "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} $<$<CONFIG:Debug>:${CMAKE_EXE_LINKER_FLAGS_DEBUG}> $<$<CONFIG:Release>:${CMAKE_EXE_LINKER_FLAGS_RELEASE}> ${${MODULE}_EXE_LINKER_FLAGS}")
+ endif()
+ endif()
+
+ if(${MODULE}_INSTALL_PREFIX)
+ list(APPEND CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${${MODULE}_INSTALL_PREFIX})
+ else()
+ list(APPEND CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DEP_LOCATION})
+ endif()
+
+ if(DEFINED ${MODULE}_TOOLCHAIN_FILE)
+ list(APPEND CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${${MODULE}_TOOLCHAIN_FILE})
+ elseif(CMAKE_TOOLCHAIN_FILE)
+ list(APPEND CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
+ endif()
+
+ # Set build type for dep build.
+ # if MODULE has set a manual build type, use it, otherwise use project build type
+ if(${MODULE}_BUILD_TYPE)
+ list(APPEND CMAKE_ARGS "-DCMAKE_BUILD_TYPE=${${MODULE}_BUILD_TYPE}")
+ # Build_type is forced, so unset the opposite <MODULE>_LIBRARY_<TYPE> to only give
+ # select_library_configurations one library name to choose from
+ if(${MODULE}_BUILD_TYPE STREQUAL "Release")
+ unset(${MODULE}_LIBRARY_DEBUG)
+ else()
+ unset(${MODULE}_LIBRARY_RELEASE)
+ endif()
+ else()
+ # single config generator (ie Make, Ninja)
+ if(CMAKE_BUILD_TYPE)
+ list(APPEND CMAKE_ARGS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
+ else()
+ # Multi-config generators (eg VS, Xcode, Ninja Multi-Config) will not have CMAKE_BUILD_TYPE
+ # Use config genex to generate the types
+ # Potential issue if Build type isnt supported by lib project
+ # eg lib supports Debug/Release, however users selects RelWithDebInfo in project
+ list(APPEND CMAKE_ARGS "-DCMAKE_BUILD_TYPE=$<CONFIG>")
+ endif()
+ endif()
+
+ # Xcode - Default sub projects to makefile builds. More consistent
+ # Windows - Default to same generator version used in parent
+ if(CMAKE_GENERATOR STREQUAL Xcode)
+ if(NOT ${MODULE}_GENERATOR)
+ set(${MODULE}_GENERATOR CMAKE_GENERATOR "Unix Makefiles")
+ endif()
+ elseif(MSVC)
+ if(NOT ${MODULE}_GENERATOR)
+ set(${MODULE}_GENERATOR CMAKE_GENERATOR "${CMAKE_GENERATOR}")
+ endif()
+ if(NOT ${MODULE}_GENERATOR_PLATFORM)
+ set(${MODULE}_GENERATOR_PLATFORM CMAKE_GENERATOR_PLATFORM ${CMAKE_GENERATOR_PLATFORM})
+ endif()
+ endif()
+ endif()
+
+ if(PATCH_COMMAND)
+ set(PATCH_COMMAND PATCH_COMMAND ${PATCH_COMMAND})
+ endif()
+
+ if(CONFIGURE_COMMAND)
+ if(NOT CMAKE_ARGS AND DEP_BUILDENV)
+ # DEP_BUILDENV only used for non cmake externalproject_add builds
+ # iterate through CONFIGURE_COMMAND looking for multiple COMMAND, we need to
+ # add DEP_BUILDENV for each distinct COMMAND
+ set(tmp_config_command ${DEP_BUILDENV})
+ foreach(item ${CONFIGURE_COMMAND})
+ list(APPEND tmp_config_command ${item})
+ if(item STREQUAL "COMMAND")
+ list(APPEND tmp_config_command ${DEP_BUILDENV})
+ endif()
+ endforeach()
+ set(CONFIGURE_COMMAND CONFIGURE_COMMAND ${tmp_config_command})
+ unset(tmp_config_command)
+ else()
+ set(CONFIGURE_COMMAND CONFIGURE_COMMAND ${CONFIGURE_COMMAND})
+ endif()
+ endif()
+
+ if(BUILD_COMMAND)
+ set(BUILD_COMMAND BUILD_COMMAND ${BUILD_COMMAND})
+ endif()
+
+ if(INSTALL_COMMAND)
+ set(INSTALL_COMMAND INSTALL_COMMAND ${INSTALL_COMMAND})
+ endif()
+
+ if(BUILD_IN_SOURCE)
+ set(BUILD_IN_SOURCE BUILD_IN_SOURCE ${BUILD_IN_SOURCE})
+ endif()
+
+ # Set Library names.
+ if(DEFINED ${MODULE}_DEBUG_POSTFIX)
+ set(_POSTFIX ${${MODULE}_DEBUG_POSTFIX})
+ string(REGEX REPLACE "\\.[^.]*$" "" _LIBNAME ${${MODULE}_BYPRODUCT})
+ string(REGEX REPLACE "^.*\\." "" _LIBEXT ${${MODULE}_BYPRODUCT})
+ set(${MODULE}_LIBRARY_DEBUG ${DEP_LOCATION}/lib/${_LIBNAME}${${MODULE}_DEBUG_POSTFIX}.${_LIBEXT})
+ endif()
+ # set <MODULE>_LIBRARY_RELEASE for use of select_library_configurations
+ # any modules that dont use select_library_configurations, we set <MODULE>_LIBRARY
+ # No harm in having either set for both potential paths
+ set(${MODULE}_LIBRARY_RELEASE ${DEP_LOCATION}/lib/${${MODULE}_BYPRODUCT})
+ set(${MODULE}_LIBRARY ${${MODULE}_LIBRARY_RELEASE})
+
+ if(NOT ${MODULE}_INCLUDE_DIR)
+ set(${MODULE}_INCLUDE_DIR ${DEP_LOCATION}/include)
+ endif()
+
+ if(BUILD_BYPRODUCTS)
+ set(BUILD_BYPRODUCTS BUILD_BYPRODUCTS ${BUILD_BYPRODUCTS})
+ else()
+ if(DEFINED ${MODULE}_LIBRARY_DEBUG)
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20")
+ set(BUILD_BYPRODUCTS BUILD_BYPRODUCTS "$<IF:$<CONFIG:Debug,RelWithDebInfo>,${${MODULE}_LIBRARY_DEBUG},${${MODULE}_LIBRARY_RELEASE}>")
+ else()
+ if(DEFINED CMAKE_BUILD_TYPE)
+ if(NOT CMAKE_BUILD_TYPE STREQUAL "Release" AND DEFINED ${MODULE}_LIBRARY_DEBUG)
+ set(BUILD_BYPRODUCTS BUILD_BYPRODUCTS "${${MODULE}_LIBRARY_DEBUG}")
+ else()
+ set(BUILD_BYPRODUCTS BUILD_BYPRODUCTS "${${MODULE}_LIBRARY}")
+ endif()
+ else()
+ message(FATAL_ERROR "MultiConfig Generator usage requires CMake >= 3.20.0 - Generator Expressions in BYPRODUCT option")
+ endif()
+ endif()
+ else()
+ set(BUILD_BYPRODUCTS BUILD_BYPRODUCTS "${${MODULE}_LIBRARY}")
+ endif()
+ endif()
+
+ if(NOT BUILD_NAME)
+ set(BUILD_NAME ${MODULE_LC})
+ endif()
+
+ if(NOT INSTALL_DIR)
+ set(INSTALL_DIR ${DEP_LOCATION})
+ endif()
+
+ # Allow a target to supply in-tree source location. eg TexturePacker, JsonSchemaBuilder
+ if(${MODULE}_SOURCE_DIR)
+ set(BUILD_DOWNLOAD_STEPS SOURCE_DIR "${${MODULE}_SOURCE_DIR}")
+ else()
+ set(BUILD_DOWNLOAD_STEPS URL ${${MODULE}_URL}
+ URL_HASH ${${MODULE}_HASH}
+ DOWNLOAD_DIR ${TARBALL_DIR}
+ DOWNLOAD_NAME ${${MODULE}_ARCHIVE})
+ endif()
+
+ externalproject_add(${BUILD_NAME}
+ ${BUILD_DOWNLOAD_STEPS}
+ PREFIX ${CORE_BUILD_DIR}/${BUILD_NAME}
+ INSTALL_DIR ${INSTALL_DIR}
+ ${${MODULE}_LIST_SEPARATOR}
+ ${CMAKE_ARGS}
+ ${${MODULE}_GENERATOR}
+ ${${MODULE}_GENERATOR_PLATFORM}
+ ${PATCH_COMMAND}
+ ${CONFIGURE_COMMAND}
+ ${BUILD_COMMAND}
+ ${INSTALL_COMMAND}
+ ${BUILD_BYPRODUCTS}
+ ${BUILD_IN_SOURCE})
+
+ set_target_properties(${BUILD_NAME} PROPERTIES FOLDER "External Projects")
+
+ CLEAR_BUILD_VARS()
+endmacro()
+
+# Macro to test format of line endings of a patch
+# Windows Specific
+macro(PATCH_LF_CHECK patch)
+ if(CMAKE_HOST_WIN32)
+ # On Windows "patch.exe" can only handle CR-LF line-endings.
+ # Our patches have LF-only line endings - except when they
+ # have been checked out as part of a dependency hosted on Git
+ # and core.autocrlf=true.
+ file(READ ${ARGV0} patch_content_hex HEX)
+ # Force handle LF-only line endings
+ if(NOT patch_content_hex MATCHES "0d0a")
+ if (NOT "--binary" IN_LIST PATCH_EXECUTABLE)
+ list(APPEND PATCH_EXECUTABLE --binary)
+ endif()
+ else()
+ if ("--binary" IN_LIST PATCH_EXECUTABLE)
+ list(REMOVE_ITEM PATCH_EXECUTABLE --binary)
+ endif()
+ endif()
+ endif()
+ unset(patch_content_hex)
+endmacro()
diff --git a/cmake/scripts/common/PathSetup.cmake b/cmake/scripts/common/PathSetup.cmake
new file mode 100644
index 0000000..4fc888e
--- /dev/null
+++ b/cmake/scripts/common/PathSetup.cmake
@@ -0,0 +1,13 @@
+# Platform path setup
+include(cmake/scripts/${CORE_SYSTEM_NAME}/PathSetup.cmake)
+
+# Fallback install location for dependencies built
+if(NOT DEPENDS_PATH)
+ set(DEPENDS_PATH "${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}")
+endif()
+
+# If a platform sets a Depends_path for libs, prepend to cmake prefix path
+# for when searching for libs (eg find_package)
+if(DEPENDS_PATH)
+ list(PREPEND CMAKE_PREFIX_PATH ${DEPENDS_PATH})
+endif()
diff --git a/cmake/scripts/common/Platform.cmake b/cmake/scripts/common/Platform.cmake
new file mode 100644
index 0000000..397d8d4
--- /dev/null
+++ b/cmake/scripts/common/Platform.cmake
@@ -0,0 +1,57 @@
+if(NOT CORE_SYSTEM_NAME)
+ string(TOLOWER ${CMAKE_SYSTEM_NAME} CORE_SYSTEM_NAME)
+endif()
+
+if(CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd)
+ # Set default CORE_PLATFORM_NAME to X11 WAYLAND GBM
+ # This is overridden by user setting -DCORE_PLATFORM_NAME=<platform>
+ set(_DEFAULT_PLATFORM X11 WAYLAND GBM)
+
+ if(NOT APP_RENDER_SYSTEM)
+ message(SEND_ERROR "You need to decide whether you want to use GL- or GLES-based rendering. Please set APP_RENDER_SYSTEM to either \"gl\" or \"gles\". For normal desktop systems, you will usually want to use \"gl\".")
+ endif()
+else()
+ string(TOLOWER ${CORE_SYSTEM_NAME} _DEFAULT_PLATFORM)
+endif()
+
+set(APP_BINARY_SUFFIX ".bin")
+
+#
+# Note: please do not use CORE_PLATFORM_NAME in any checks,
+# use the normalized to lower case CORE_PLATFORM_NAME_LC (see below) instead
+#
+if(NOT CORE_PLATFORM_NAME)
+ set(CORE_PLATFORM_NAME ${_DEFAULT_PLATFORM})
+endif()
+set(CORE_PLATFORM_NAME ${CORE_PLATFORM_NAME} CACHE STRING "Platform port to build" FORCE)
+unset(_DEFAULT_PLATFORM)
+
+string(REPLACE " " ";" CORE_PLATFORM_NAME "${CORE_PLATFORM_NAME}")
+foreach(platform IN LISTS CORE_PLATFORM_NAME)
+ string(TOLOWER ${platform} platform)
+ list(APPEND CORE_PLATFORM_NAME_LC ${platform})
+endforeach()
+
+string(REPLACE ";" " " CORE_PLATFORM_STRING "${CORE_PLATFORM_NAME_LC}")
+list(APPEND final_message "Platforms: ${CORE_PLATFORM_STRING}")
+
+if(CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd)
+ list(LENGTH CORE_PLATFORM_NAME_LC PLATFORM_COUNT)
+ if(PLATFORM_COUNT EQUAL 1)
+ option(ENABLE_APP_AUTONAME "Enable renaming the binary according to windowing?" ON)
+ if(ENABLE_APP_AUTONAME)
+ set(APP_BINARY_SUFFIX "-${CORE_PLATFORM_NAME_LC}")
+ endif()
+ endif()
+endif()
+
+foreach(CORE_PLATFORM_LC IN LISTS CORE_PLATFORM_NAME_LC)
+ if(EXISTS ${CMAKE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}/${CORE_PLATFORM_LC}.cmake)
+ include(${CMAKE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}/${CORE_PLATFORM_LC}.cmake)
+ else()
+ file(GLOB _platformnames RELATIVE ${CMAKE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}/
+ ${CMAKE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}/*.cmake)
+ string(REPLACE ".cmake" " " _platformnames ${_platformnames})
+ message(FATAL_ERROR "invalid CORE_PLATFORM_NAME: ${CORE_PLATFORM_NAME_LC}\nValid platforms: ${_platformnames}")
+ endif()
+endforeach()
diff --git a/cmake/scripts/common/PrepareEnv.cmake b/cmake/scripts/common/PrepareEnv.cmake
new file mode 100644
index 0000000..559788f
--- /dev/null
+++ b/cmake/scripts/common/PrepareEnv.cmake
@@ -0,0 +1,107 @@
+# parse version.txt and versions.h to get the version and API info
+include(${CORE_SOURCE_DIR}/cmake/scripts/common/Macros.cmake)
+core_find_versions()
+
+# in case we need to download something, set KODI_MIRROR to the default if not already set
+if(NOT DEFINED KODI_MIRROR)
+ set(KODI_MIRROR "http://mirrors.kodi.tv")
+endif()
+
+### copy all the addon binding header files to include/kodi
+# make sure include/kodi exists and is empty
+set(APP_LIB_DIR ${ADDON_DEPENDS_PATH}/lib/${APP_NAME_LC})
+if(NOT EXISTS "${APP_LIB_DIR}/")
+ file(MAKE_DIRECTORY ${APP_LIB_DIR})
+endif()
+
+set(APP_DATA_DIR ${ADDON_DEPENDS_PATH}/share/${APP_NAME_LC})
+if(NOT EXISTS "${APP_DATA_DIR}/")
+ file(MAKE_DIRECTORY ${APP_DATA_DIR})
+endif()
+
+set(APP_INCLUDE_DIR ${ADDON_DEPENDS_PATH}/include/${APP_NAME_LC})
+if(NOT EXISTS "${APP_INCLUDE_DIR}/")
+ file(MAKE_DIRECTORY ${APP_INCLUDE_DIR})
+endif()
+
+if(NOT CORE_SYSTEM_NAME)
+ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ set(CORE_SYSTEM_NAME "osx")
+ else()
+ string(TOLOWER ${CMAKE_SYSTEM_NAME} CORE_SYSTEM_NAME)
+ endif()
+endif()
+
+set(PLATFORM_TAG ${CORE_SYSTEM_NAME})
+
+# The CPU variable is given either by ./tools/depends or by the
+# ./cmake/scripts/common/ArchSetup.cmake (which refers to the Kodi building
+# itself). However, this file is only used by addons, so CPU can not always
+# be defined, so in this case, if empty, the base CPU will be used.
+if(NOT CPU)
+ set(CPU ${CMAKE_SYSTEM_PROCESSOR})
+endif()
+
+if(CORE_SYSTEM_NAME STREQUAL android)
+ if (CPU MATCHES "v7a")
+ set(PLATFORM_TAG ${PLATFORM_TAG}-armv7)
+ elseif (CPU MATCHES "arm64")
+ set(PLATFORM_TAG ${PLATFORM_TAG}-aarch64)
+ elseif (CPU MATCHES "i686")
+ set(PLATFORM_TAG ${PLATFORM_TAG}-i686)
+ elseif (CPU MATCHES "x86_64")
+ set(PLATFORM_TAG ${PLATFORM_TAG}-x86_64)
+ else()
+ message(FATAL_ERROR "Unsupported architecture")
+ endif()
+elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded)
+ set(PLATFORM_TAG ${CORE_PLATFORM_NAME})
+ if (CPU MATCHES arm64)
+ set(PLATFORM_TAG ${PLATFORM_TAG}-aarch64)
+ else()
+ message(FATAL_ERROR "Unsupported architecture")
+ endif()
+elseif(CORE_SYSTEM_NAME STREQUAL osx)
+ set(PLATFORM_TAG ${PLATFORM_TAG}-${CPU})
+elseif(CORE_SYSTEM_NAME STREQUAL windows)
+ include(CheckSymbolExists)
+ check_symbol_exists(_X86_ "Windows.h" _X86_)
+ check_symbol_exists(_AMD64_ "Windows.h" _AMD64_)
+
+ if(_X86_)
+ set(PLATFORM_TAG ${PLATFORM_TAG}-i686)
+ elseif(_AMD64_)
+ set(PLATFORM_TAG ${PLATFORM_TAG}-x86_64)
+ else()
+ message(FATAL_ERROR "Unsupported architecture")
+ endif()
+
+ unset(_X86_)
+ unset(_AMD64_)
+endif()
+
+# generate the proper KodiConfig.cmake file
+configure_file(${CORE_SOURCE_DIR}/cmake/KodiConfig.cmake.in ${APP_LIB_DIR}/KodiConfig.cmake @ONLY)
+
+# copy cmake helpers to lib/kodi
+file(COPY ${CORE_SOURCE_DIR}/cmake/scripts/common/AddonHelpers.cmake
+ ${CORE_SOURCE_DIR}/cmake/scripts/common/AddOptions.cmake
+ DESTINATION ${APP_LIB_DIR})
+
+### copy all the addon binding header files to include/kodi
+include(${CORE_SOURCE_DIR}/xbmc/addons/AddonBindings.cmake)
+file(COPY ${CORE_ADDON_BINDINGS_FILES} ${CORE_ADDON_BINDINGS_DIRS}/
+ DESTINATION ${APP_INCLUDE_DIR}
+ REGEX ".txt" EXCLUDE)
+
+### processing additional tools required by the platform
+if(EXISTS ${CORE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/tools/)
+ file(GLOB platform_tools ${CORE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/tools/*.cmake)
+ foreach(platform_tool ${platform_tools})
+ get_filename_component(platform_tool_name ${platform_tool} NAME_WE)
+ message(STATUS "Processing ${CORE_SYSTEM_NAME} specific tool: ${platform_tool_name}")
+
+ # include the file
+ include(${platform_tool})
+ endforeach()
+endif()
diff --git a/cmake/scripts/common/ProjectMacros.cmake b/cmake/scripts/common/ProjectMacros.cmake
new file mode 100644
index 0000000..3a1910c
--- /dev/null
+++ b/cmake/scripts/common/ProjectMacros.cmake
@@ -0,0 +1,89 @@
+# This script holds macros which are project specific
+
+# Pack a skin xbt file
+# Arguments:
+# input input directory to pack
+# output output xbt file
+# On return:
+# xbt is added to ${XBT_FILES}
+function(pack_xbt input output)
+ file(GLOB_RECURSE MEDIA_FILES ${input}/*)
+ get_filename_component(dir ${output} DIRECTORY)
+ add_custom_command(OUTPUT ${output}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
+ COMMAND TexturePacker::TexturePacker::Executable
+ ARGS -input ${input}
+ -output ${output}
+ -dupecheck
+ DEPENDS ${MEDIA_FILES})
+ list(APPEND XBT_FILES ${output})
+ set(XBT_FILES ${XBT_FILES} PARENT_SCOPE)
+endfunction()
+
+# Add a skin to installation list, mirroring it in build tree, packing textures
+# Arguments:
+# skin skin directory
+# On return:
+# xbt is added to ${XBT_FILES}, data added to ${install_data}, mirror in build tree
+function(copy_skin_to_buildtree skin)
+ file(GLOB_RECURSE FILES ${skin}/*)
+ file(GLOB_RECURSE MEDIA_FILES ${skin}/media/*)
+ list(REMOVE_ITEM FILES ${MEDIA_FILES})
+ foreach(file ${FILES})
+ copy_file_to_buildtree(${file})
+ endforeach()
+ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${dest}/media)
+ string(REPLACE "${CMAKE_SOURCE_DIR}/" "" dest ${skin})
+ pack_xbt(${skin}/media ${CMAKE_BINARY_DIR}/${dest}/media/Textures.xbt)
+
+ file(GLOB THEMES RELATIVE ${skin}/themes ${skin}/themes/*)
+ foreach(theme ${THEMES})
+ pack_xbt(${skin}/themes/${theme} ${CMAKE_BINARY_DIR}/${dest}/media/${theme}.xbt)
+ endforeach()
+
+ set(XBT_FILES ${XBT_FILES} PARENT_SCOPE)
+ set(install_data ${install_data} PARENT_SCOPE)
+endfunction()
+
+# Get GTest tests as CMake tests.
+# Copied from FindGTest.cmake
+# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
+function(GTEST_ADD_TESTS executable extra_args)
+ if(NOT ARGN)
+ message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
+ endif()
+ foreach(source ${ARGN})
+ # This assumes that every source file passed in exists. Consider using
+ # SUPPORT_SOURCES for source files which do not contain tests and might
+ # have to be generated.
+ file(READ "${source}" contents)
+ string(REGEX MATCHALL "TEST_?[F]?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
+ foreach(hit ${found_tests})
+ string(REGEX REPLACE ".*\\( *([A-Za-z_0-9]+), *([A-Za-z_0-9]+) *\\).*" "\\1.\\2" test_name ${hit})
+ add_test(${test_name} ${executable} --gtest_filter=${test_name} ${extra_args})
+ endforeach()
+ # Groups parametrized tests under a single ctest entry
+ string(REGEX MATCHALL "INSTANTIATE_TEST_CASE_P\\(([^,]+), *([^,]+)" found_tests2 ${contents})
+ foreach(hit ${found_tests2})
+ string(SUBSTRING ${hit} 24 -1 test_name)
+ string(REPLACE "," ";" test_name "${test_name}")
+ list(GET test_name 0 filter_name)
+ list(GET test_name 1 test_prefix)
+ string(STRIP ${test_prefix} test_prefix)
+ add_test(${test_prefix}.${filter_name} ${executable} --gtest_filter=${filter_name}* ${extra_args})
+ endforeach()
+ endforeach()
+endfunction()
+
+function(whole_archive output)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+ set(${output} -Wl,--whole-archive ${ARGN} -Wl,--no-whole-archive PARENT_SCOPE)
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL AppleClang)
+ foreach(library ${ARGN})
+ list(APPEND ${output} -Wl,-force_load ${library})
+ set(${output} ${${output}} PARENT_SCOPE)
+ endforeach()
+ else()
+ set(${output} ${ARGN} PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/cmake/scripts/common/StaticAnalysis.cmake b/cmake/scripts/common/StaticAnalysis.cmake
new file mode 100644
index 0000000..f7ffa39
--- /dev/null
+++ b/cmake/scripts/common/StaticAnalysis.cmake
@@ -0,0 +1,39 @@
+include(ProcessorCount)
+ProcessorCount(CPU_CORES)
+
+find_program(CPPCHECK_EXECUTABLE cppcheck)
+
+if(CPPCHECK_EXECUTABLE)
+ add_custom_target(analyze-cppcheck
+ DEPENDS ${APP_NAME_LC} ${APP_NAME_LC}-test
+ COMMAND ${CPPCHECK_EXECUTABLE}
+ -j${CPU_CORES}
+ --project=${CMAKE_BINARY_DIR}/compile_commands.json
+ --std=c++${CMAKE_CXX_STANDARD}
+ --enable=all
+ --xml
+ --xml-version=2
+ --language=c++
+ --relative-paths=${CMAKE_SOURCE_DIR}
+ --rule-file=${CMAKE_SOURCE_DIR}/tools/static-analysis/cppcheck/cppcheck-rules.xml
+ --suppress-xml=${CMAKE_SOURCE_DIR}/tools/static-analysis/cppcheck/cppcheck-suppressions.xml
+ --output-file=${CMAKE_BINARY_DIR}/cppcheck-result.xml
+ COMMENT "Static code analysis using cppcheck")
+endif()
+
+find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy)
+find_program(RUN_CLANG_TIDY NAMES run-clang-tidy.py run-clang-tidy
+ PATHS /usr/share/clang /usr/bin)
+
+if(RUN_CLANG_TIDY AND CLANG_TIDY_EXECUTABLE)
+ add_custom_target(analyze-clang-tidy
+ DEPENDS ${APP_NAME_LC} ${APP_NAME_LC}-test
+ COMMAND ${RUN_CLANG_TIDY}
+ -j${CPU_CORES}
+ -clang-tidy-binary=${CLANG_TIDY_EXECUTABLE}
+ -p=${CMAKE_BINARY_DIR}
+ -header-filter='${CMAKE_BINARY_DIR}/.*/include/.*'
+ | tee ${CMAKE_BINARY_DIR}/clangtidy-result.xml
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Static code analysis using clang-tidy")
+endif()
diff --git a/cmake/scripts/common/Uninstall.cmake b/cmake/scripts/common/Uninstall.cmake
new file mode 100644
index 0000000..5753857
--- /dev/null
+++ b/cmake/scripts/common/Uninstall.cmake
@@ -0,0 +1,58 @@
+macro(remove_empty_dirs)
+ list(REMOVE_DUPLICATES DIRECTORIES)
+ unset(PDIRECTORIES)
+ foreach(dir IN LISTS DIRECTORIES)
+ if(EXISTS $ENV{DESTDIR}${dir})
+ file(GLOB _res $ENV{DESTDIR}${dir}/*)
+ list(LENGTH _res _len)
+ if(_len EQUAL 0 AND EXISTS $ENV{DESTDIR}${dir})
+ message(STATUS "Removing empty dir: ${dir}")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E remove_directory $ENV{DESTDIR}${dir}
+ OUTPUT_VARIABLE rm_out
+ RESULT_VARIABLE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Failed to remove directory: $ENV{DESTDIR}${dir}")
+ endif()
+ get_filename_component(_pdir $ENV{DESTDIR}${dir} DIRECTORY)
+ list(APPEND PDIRECTORIES ${_pdir})
+ endif()
+ endif()
+ endforeach()
+ list(LENGTH PDIRECTORIES _plen)
+ if(_plen GREATER 0)
+ set(DIRECTORIES ${PDIRECTORIES})
+ remove_empty_dirs()
+ endif()
+endmacro()
+
+# Uninstall target
+set(MANIFEST ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt)
+if(EXISTS ${MANIFEST})
+ file(STRINGS ${MANIFEST} files)
+ foreach(file IN LISTS files)
+ if(EXISTS $ENV{DESTDIR}${file})
+ get_filename_component(_dir $ENV{DESTDIR}${file} DIRECTORY)
+ list(APPEND DIRECTORIES $ENV{DESTDIR}${_dir})
+ message(STATUS "Uninstalling: ${file}")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E remove $ENV{DESTDIR}${file}
+ OUTPUT_VARIABLE rm_out
+ RESULT_VARIABLE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Failed to remove file: $ENV{DESTDIR}${file}")
+ endif()
+ else()
+ message(STATUS "File does not exist: $ENV{DESTDIR}${file}")
+ endif()
+ endforeach(file)
+
+ # delete empty dirs
+ if(DIRECTORIES)
+ remove_empty_dirs()
+ endif()
+else()
+ message(STATUS "Cannot find install manifest: '${MANIFEST}'")
+endif()
diff --git a/cmake/scripts/darwin/Macros.cmake b/cmake/scripts/darwin/Macros.cmake
new file mode 100644
index 0000000..9a805c4
--- /dev/null
+++ b/cmake/scripts/darwin/Macros.cmake
@@ -0,0 +1,8 @@
+macro(enable_arc)
+ if(CMAKE_GENERATOR STREQUAL Xcode)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
+ else()
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc")
+ endif()
+endmacro()
diff --git a/cmake/scripts/darwin_embedded/ArchSetup.cmake b/cmake/scripts/darwin_embedded/ArchSetup.cmake
new file mode 100644
index 0000000..b3258be
--- /dev/null
+++ b/cmake/scripts/darwin_embedded/ArchSetup.cmake
@@ -0,0 +1,68 @@
+if(NOT CMAKE_TOOLCHAIN_FILE)
+ message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE required for ios/tvos. See ${CMAKE_SOURCE_DIR}/cmake/README.md")
+endif()
+
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/${CORE_PLATFORM_NAME_LC}/XBMCApplication.mm)
+set(PLATFORM_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/${CORE_PLATFORM_NAME_LC}/Info.plist.in)
+
+list(APPEND ARCH_DEFINES -DTARGET_POSIX -DTARGET_DARWIN -DTARGET_DARWIN_EMBEDDED)
+set(SYSTEM_DEFINES -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+ -D__STDC_CONSTANT_MACROS -DHAS_IOS_NETWORK -DHAS_ZEROCONF)
+set(PLATFORM_DIR platform/darwin)
+set(PLATFORMDEFS_DIR platform/posix)
+set(CMAKE_SYSTEM_NAME Darwin)
+if(WITH_ARCH)
+ set(ARCH ${WITH_ARCH})
+else()
+ if(CPU STREQUAL arm64)
+ set(ARCH aarch64)
+ else()
+ message(SEND_ERROR "Unknown CPU: ${CPU}")
+ endif()
+ set(CMAKE_OSX_ARCHITECTURES ${CPU})
+ set(NEON True)
+endif()
+
+if(NOT APP_RENDER_SYSTEM OR APP_RENDER_SYSTEM STREQUAL "gles")
+ set(PLATFORM_REQUIRED_DEPS OpenGLES)
+ set(APP_RENDER_SYSTEM gles)
+ list(APPEND SYSTEM_DEFINES -DGL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED)
+else()
+ message(SEND_ERROR "Currently only OpenGLES rendering is supported. Please set APP_RENDER_SYSTEM to \"gles\"")
+endif()
+
+list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${NATIVEPREFIX})
+
+list(APPEND DEPLIBS "-framework CoreFoundation" "-framework CoreVideo"
+ "-framework CoreAudio" "-framework AudioToolbox"
+ "-framework QuartzCore" "-framework MediaPlayer"
+ "-framework CFNetwork" "-framework CoreGraphics"
+ "-framework Foundation" "-framework UIKit"
+ "-framework CoreMedia" "-framework AVFoundation"
+ "-framework VideoToolbox" "-lresolv" "-ObjC"
+ "-framework AVKit" "-framework GameController")
+
+# Speech not available on tvOS
+if(NOT CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ list(APPEND DEPLIBS "-framework Speech")
+endif()
+
+set(ENABLE_OPTICAL OFF CACHE BOOL "" FORCE)
+set(CMAKE_XCODE_ATTRIBUTE_INLINES_ARE_PRIVATE_EXTERN OFF)
+set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN OFF)
+set(CMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP OFF)
+
+include(cmake/scripts/darwin/Macros.cmake)
+enable_arc()
+
+# Xcode strips dead code by default which breaks wrapping
+set(CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING OFF)
+
+option(ENABLE_XCODE_ADDONBUILD "Enable Xcode automatic addon building?" OFF)
+
+# Unify output directories for iOS/tvOS packaging scripts
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CORE_BUILD_DIR}/${CORE_BUILD_CONFIG})
+foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
+ string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CORE_BUILD_DIR}/${CORE_BUILD_CONFIG})
+endforeach()
diff --git a/cmake/scripts/darwin_embedded/ExtraTargets.cmake b/cmake/scripts/darwin_embedded/ExtraTargets.cmake
new file mode 100644
index 0000000..01ab632
--- /dev/null
+++ b/cmake/scripts/darwin_embedded/ExtraTargets.cmake
@@ -0,0 +1,32 @@
+if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ # top shelf extension
+ set(TOPSHELF_EXTENSION_NAME "${APP_NAME_LC}-topshelf")
+ set(TOPSHELF_BUNDLE_EXTENSION appex)
+ set(TOPSHELF_DIR "${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/tvos/TopShelf")
+ # same path as the output Info.plist, taken from cmGlobalXCodeGenerator::ComputeInfoPListLocation()
+ set(ENTITLEMENTS_OUT_PATH "${CMAKE_BINARY_DIR}/CMakeFiles/${TOPSHELF_EXTENSION_NAME}.dir/TopShelf.entitlements")
+
+ set(SOURCES
+ ${TOPSHELF_DIR}/../../ios-common/DarwinEmbedUtils.mm
+ ${TOPSHELF_DIR}/ServiceProvider.mm
+ ${TOPSHELF_DIR}/../tvosShared.mm)
+ set(HEADERS
+ ${TOPSHELF_DIR}/../../ios-common/DarwinEmbedUtils.h
+ ${TOPSHELF_DIR}/ServiceProvider.h
+ ${TOPSHELF_DIR}/../tvosShared.h)
+ add_executable(${TOPSHELF_EXTENSION_NAME} MACOSX_BUNDLE ${SOURCES} ${HEADERS})
+
+ configure_file(${TOPSHELF_DIR}/TopShelf.entitlements.in ${ENTITLEMENTS_OUT_PATH} @ONLY)
+ set_target_properties(${TOPSHELF_EXTENSION_NAME} PROPERTIES BUNDLE_EXTENSION ${TOPSHELF_BUNDLE_EXTENSION}
+ MACOSX_BUNDLE_INFO_PLIST ${TOPSHELF_DIR}/Info.plist.in
+ XCODE_PRODUCT_TYPE com.apple.product-type.tv-app-extension
+ XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ENTITLEMENTS_OUT_PATH})
+ target_link_libraries(${TOPSHELF_EXTENSION_NAME} "-framework TVServices" "-framework Foundation")
+
+ add_custom_command(TARGET ${TOPSHELF_EXTENSION_NAME} POST_BUILD
+ COMMAND "NATIVEPREFIX=${NATIVEPREFIX}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/Codesign-topshelf.command
+ )
+
+ add_dependencies(${APP_NAME_LC} ${TOPSHELF_EXTENSION_NAME})
+endif()
diff --git a/cmake/scripts/darwin_embedded/Install.cmake b/cmake/scripts/darwin_embedded/Install.cmake
new file mode 100644
index 0000000..02464ee
--- /dev/null
+++ b/cmake/scripts/darwin_embedded/Install.cmake
@@ -0,0 +1,130 @@
+# IOS/TVOS packaging
+if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ # asset catalog
+ set(ASSET_CATALOG "${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/tvos/Assets.xcassets")
+ set(ASSET_CATALOG_ASSETS Assets)
+ set(ASSET_CATALOG_LAUNCH_IMAGE LaunchImage)
+
+ message("generating missing asset catalog images...")
+ execute_process(COMMAND ${CMAKE_SOURCE_DIR}/tools/darwin/Support/GenerateMissingImages-tvos.py "${ASSET_CATALOG}" ${ASSET_CATALOG_ASSETS} ${ASSET_CATALOG_LAUNCH_IMAGE})
+
+ target_sources(${APP_NAME_LC} PRIVATE "${ASSET_CATALOG}")
+ set_source_files_properties("${ASSET_CATALOG}" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") # adds to Copy Bundle Resources build phase
+
+ # entitlements
+ set(ENTITLEMENTS_OUT_PATH "${CMAKE_BINARY_DIR}/CMakeFiles/${APP_NAME_LC}.dir/Kodi.entitlements")
+ configure_file(${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/tvos/Kodi.entitlements.in ${ENTITLEMENTS_OUT_PATH} @ONLY)
+
+ set_target_properties(${APP_NAME_LC} PROPERTIES XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME ${ASSET_CATALOG_ASSETS}
+ XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME ${ASSET_CATALOG_LAUNCH_IMAGE}
+ XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ENTITLEMENTS_OUT_PATH})
+
+else()
+ set(BUNDLE_RESOURCES ${CMAKE_SOURCE_DIR}/media/splash.jpg
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon29x29.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon29x29@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon40x40.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon40x40@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon50x50.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon50x50@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon57x57.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon57x57@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon60x60.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon60x60@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon72x72.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon72x72@2x.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon76x76.png
+ ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/ios/rounded/AppIcon76x76@2x.png)
+
+ target_sources(${APP_NAME_LC} PRIVATE ${BUNDLE_RESOURCES})
+ foreach(file IN LISTS BUNDLE_RESOURCES)
+ set_source_files_properties(${file} PROPERTIES MACOSX_PACKAGE_LOCATION .)
+ endforeach()
+
+ target_sources(${APP_NAME_LC} PRIVATE ${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/ios/LaunchScreen.storyboard)
+ set_source_files_properties(${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/ios/LaunchScreen.storyboard PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
+
+endif()
+
+# setup code signing
+# dev team ID / identity (certificate)
+set(DEVELOPMENT_TEAM "" CACHE STRING "Development Team")
+set(CODE_SIGN_IDENTITY $<IF:$<BOOL:${DEVELOPMENT_TEAM}>,iPhone\ Developer,> CACHE STRING "Code Sign Identity")
+
+# app provisioning profile
+set(CODE_SIGN_STYLE_APP Automatic)
+set(PROVISIONING_PROFILE_APP "" CACHE STRING "Provisioning profile name for the Kodi app")
+if(PROVISIONING_PROFILE_APP)
+ set(CODE_SIGN_STYLE_APP Manual)
+endif()
+
+# top shelf provisioning profile
+if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ set(CODE_SIGN_STYLE_TOPSHELF Automatic)
+ set(PROVISIONING_PROFILE_TOPSHELF "" CACHE STRING "Provisioning profile name for the Top Shelf")
+ if(PROVISIONING_PROFILE_TOPSHELF)
+ set(CODE_SIGN_STYLE_TOPSHELF Manual)
+ endif()
+ set_target_properties(${TOPSHELF_EXTENSION_NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODE_SIGN_IDENTITY}"
+ XCODE_ATTRIBUTE_CODE_SIGN_STYLE ${CODE_SIGN_STYLE_TOPSHELF}
+ XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${DEVELOPMENT_TEAM}"
+ XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${PROVISIONING_PROFILE_TOPSHELF}")
+ # copy extension inside PlugIns dir of the app bundle
+ add_custom_command(TARGET ${APP_NAME_LC} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory $<TARGET_BUNDLE_DIR:${TOPSHELF_EXTENSION_NAME}>
+ $<TARGET_BUNDLE_DIR:${APP_NAME_LC}>/PlugIns/${TOPSHELF_EXTENSION_NAME}.${TOPSHELF_BUNDLE_EXTENSION}
+ MAIN_DEPENDENCY ${TOPSHELF_EXTENSION_NAME})
+endif()
+set_target_properties(${APP_NAME_LC} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODE_SIGN_IDENTITY}"
+ XCODE_ATTRIBUTE_CODE_SIGN_STYLE ${CODE_SIGN_STYLE_APP}
+ XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${DEVELOPMENT_TEAM}"
+ XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${PROVISIONING_PROFILE_APP}")
+
+# Create xcode target that allows to build binary-addons.
+if(ADDONS_TO_BUILD)
+ set(_addons "ADDONS=${ADDONS_TO_BUILD}")
+endif()
+add_custom_target(binary-addons
+ COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons clean
+ COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons VERBOSE=1 V=99
+ INSTALL_PREFIX="${CMAKE_BINARY_DIR}/addons" CROSS_COMPILING=yes ${_addons})
+if(ENABLE_XCODE_ADDONBUILD)
+ add_dependencies(${APP_NAME_LC} binary-addons)
+endif()
+unset(_addons)
+
+add_custom_command(TARGET ${APP_NAME_LC} POST_BUILD
+ # TODO: Remove in sync with CopyRootFiles-darwin_embedded expecting the ".bin" file
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${APP_NAME_LC}>
+ $<TARGET_FILE_DIR:${APP_NAME_LC}>/${APP_NAME}.bin
+
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/DllPaths_generated.h
+ ${CMAKE_BINARY_DIR}/xbmc/DllPaths_generated.h
+ COMMAND "ACTION=build"
+ "APP_NAME=${APP_NAME}"
+ "XBMC_DEPENDS=${DEPENDS_PATH}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/CopyRootFiles-darwin_embedded.command
+ COMMAND "XBMC_DEPENDS=${DEPENDS_PATH}"
+ "PYTHON_VERSION=${PYTHON_VERSION}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/copyframeworks-darwin_embedded.command
+ COMMAND ${CMAKE_SOURCE_DIR}/tools/darwin/Support/copyframeworks-dylibs2frameworks.command
+ COMMAND "XBMC_DEPENDS=${DEPENDS_PATH}"
+ "NATIVEPREFIX=${NATIVEPREFIX}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/Codesign.command
+)
+
+if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ add_custom_command(TARGET ${APP_NAME_LC} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPENDS_PATH}/share/${APP_NAME_LC} $<TARGET_FILE_DIR:${APP_NAME_LC}>/AppData/AppHome
+ )
+endif()
+
+set(DEPENDS_ROOT_FOR_XCODE ${NATIVEPREFIX}/..)
+configure_file(${CMAKE_SOURCE_DIR}/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh.in
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/darwin_embedded/mkdeb-darwin_embedded.sh @ONLY)
+
+add_custom_target(deb
+ COMMAND sh ./mkdeb-darwin_embedded.sh ${CORE_BUILD_CONFIG}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tools/darwin/packaging/darwin_embedded)
+add_dependencies(deb ${APP_NAME_LC})
+
diff --git a/cmake/scripts/darwin_embedded/Macros.cmake b/cmake/scripts/darwin_embedded/Macros.cmake
new file mode 100644
index 0000000..3e58b0d
--- /dev/null
+++ b/cmake/scripts/darwin_embedded/Macros.cmake
@@ -0,0 +1,119 @@
+function(core_link_library lib wraplib)
+ if(CMAKE_GENERATOR MATCHES "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL Ninja)
+ set(wrapper_obj cores/dll-loader/exports/CMakeFiles/wrapper.dir/wrapper.c.o)
+ elseif(CMAKE_GENERATOR MATCHES "Xcode")
+ # CURRENT_VARIANT is an Xcode env var
+ # CPU is a project cmake var
+ # Xcode new build system (CMAKE_XCODE_BUILD_SYSTEM=12) requires the env var CURRENT_VARIANT to be passed WITHOUT brackets
+ # Xcode Legacy build system (CMAKE_XCODE_BUILD_SYSTEM=1) requires the env var CURRENT_VARIANT to be passed WITH brackets
+ if(CMAKE_XCODE_BUILD_SYSTEM STREQUAL 12)
+ set(wrapper_obj cores/dll-loader/exports/kodi.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/wrapper.build/Objects-$CURRENT_VARIANT/${CPU}/wrapper.o)
+ else()
+ set(wrapper_obj cores/dll-loader/exports/kodi.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/wrapper.build/Objects-$(CURRENT_VARIANT)/${CPU}/wrapper.o)
+ endif()
+ else()
+ message(FATAL_ERROR "Unsupported generator in core_link_library")
+ endif()
+
+ set(export -bundle -undefined dynamic_lookup
+ -Wl,-alias_list,${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/wrapper.def
+ ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${wrapper_obj})
+ set(extension ${CMAKE_SHARED_MODULE_SUFFIX})
+ set(check_arg "")
+ if(TARGET ${lib})
+ set(target ${lib})
+ set(link_lib $<TARGET_FILE:${lib}>)
+ set(check_arg ${ARGV2})
+ set(data_arg ${ARGV3})
+
+ else()
+ set(target ${ARGV2})
+ set(link_lib ${lib})
+ set(check_arg ${ARGV3})
+ set(data_arg ${ARGV4})
+ endif()
+ if(check_arg STREQUAL export)
+ set(export ${export}
+ -Wl,--version-script=${ARGV3})
+ elseif(check_arg STREQUAL extras)
+ foreach(arg ${data_arg})
+ list(APPEND export ${arg})
+ endforeach()
+ elseif(check_arg STREQUAL archives)
+ set(extra_libs ${data_arg})
+ endif()
+ get_filename_component(dir ${wraplib} DIRECTORY)
+
+ # We can't simply pass the linker flags to the args section of the custom command
+ # because cmake will add quotes around it (and the linker will fail due to those).
+ # We need to do this handstand first ...
+ string(REPLACE " " ";" CUSTOM_COMMAND_ARGS_LDFLAGS ${CMAKE_SHARED_LINKER_FLAGS})
+
+ add_custom_command(OUTPUT ${wraplib}-${ARCH}${extension}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
+ COMMAND ${CMAKE_C_COMPILER}
+ ARGS ${CUSTOM_COMMAND_ARGS_LDFLAGS} ${export} -Wl,-force_load ${link_lib} ${extra_libs}
+ -o ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${extension}
+ DEPENDS ${target} wrapper.def wrapper)
+
+ get_filename_component(libname ${wraplib} NAME_WE)
+ add_custom_target(wrap_${libname} ALL DEPENDS ${wraplib}-${ARCH}${extension})
+ set_target_properties(wrap_${libname} PROPERTIES FOLDER lib/wrapped)
+ add_dependencies(${APP_NAME_LC}-libraries wrap_${libname})
+
+ set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${extension} CACHE STRING "" FORCE)
+endfunction()
+
+function(find_soname lib)
+ cmake_parse_arguments(arg "REQUIRED" "" "" ${ARGN})
+
+ string(TOLOWER ${lib} liblow)
+ if(${lib}_LDFLAGS)
+ set(link_lib "${${lib}_LDFLAGS}")
+ else()
+ set(link_lib "${${lib}_LIBRARIES}")
+ endif()
+
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs
+ COMMAND fgrep libraries:
+ COMMAND sed "s/[^=]*=\\(.*\\)/\\1/"
+ COMMAND sed "s/:/ /g"
+ ERROR_QUIET
+ OUTPUT_VARIABLE cc_lib_path
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND echo ${link_lib}
+ COMMAND sed "s/-L[ ]*//g"
+ COMMAND sed "s/-l[^ ]*//g"
+ ERROR_QUIET
+ OUTPUT_VARIABLE env_lib_path
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ foreach(path ${cc_lib_path} ${env_lib_path})
+ if(IS_DIRECTORY ${path})
+ execute_process(COMMAND ls -- ${path}/lib${liblow}.dylib
+ ERROR_QUIET
+ OUTPUT_VARIABLE lib_file
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ set(lib_file ${path})
+ endif()
+ if(lib_file)
+ # we want the path/name that is embedded in the dylib
+ execute_process(COMMAND otool -L ${lib_file}
+ COMMAND grep -v lib${liblow}.dylib
+ COMMAND grep ${liblow}
+ COMMAND awk "{V=1; print $V}"
+ ERROR_QUIET
+ OUTPUT_VARIABLE filename
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ get_filename_component(${lib}_SONAME "${filename}" NAME)
+ if(VERBOSE)
+ message(STATUS "${lib} soname: ${${lib}_SONAME}")
+ endif()
+ endif()
+ endforeach()
+ if(arg_REQUIRED AND NOT ${lib}_SONAME)
+ message(FATAL_ERROR "Could not find dynamically loadable library ${lib}")
+ endif()
+ set(${lib}_SONAME ${${lib}_SONAME} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/scripts/darwin_embedded/PathSetup.cmake b/cmake/scripts/darwin_embedded/PathSetup.cmake
new file mode 100644
index 0000000..efaca0b
--- /dev/null
+++ b/cmake/scripts/darwin_embedded/PathSetup.cmake
@@ -0,0 +1,7 @@
+set(BUNDLE_IDENTIFIER_DESC "Bundle ID")
+if(CORE_PLATFORM_NAME_LC STREQUAL tvos)
+ string(CONCAT BUNDLE_IDENTIFIER_DESC "${BUNDLE_IDENTIFIER_DESC}" " (app, top shelf, group ID)")
+endif()
+set(PLATFORM_BUNDLE_IDENTIFIER "${APP_PACKAGE}-${CORE_PLATFORM_NAME_LC}" CACHE STRING "${BUNDLE_IDENTIFIER_DESC}")
+list(APPEND final_message "Bundle ID: ${PLATFORM_BUNDLE_IDENTIFIER}")
+include(cmake/scripts/osx/PathSetup.cmake)
diff --git a/cmake/scripts/freebsd/ArchSetup.cmake b/cmake/scripts/freebsd/ArchSetup.cmake
new file mode 100644
index 0000000..87f4f0c
--- /dev/null
+++ b/cmake/scripts/freebsd/ArchSetup.cmake
@@ -0,0 +1,46 @@
+# Main cpp
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/posix/main.cpp)
+
+set(ARCH_DEFINES -DTARGET_POSIX -DTARGET_FREEBSD)
+set(SYSTEM_DEFINES -D__STDC_CONSTANT_MACROS -D_LARGEFILE64_SOURCE
+ -D_FILE_OFFSET_BITS=64 -DHAS_OSS)
+set(PLATFORM_DIR platform/linux)
+set(PLATFORMDEFS_DIR platform/posix)
+set(SYSTEM_LDFLAGS -L/usr/local/lib)
+if(WITH_ARCH)
+ set(ARCH ${WITH_ARCH})
+else()
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
+ set(ARCH x86_64-freebsd)
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86")
+ set(ARCH x86-freebsd)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv6)
+ set(ARCH armv6-freebsd)
+ set(NEON True)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7)
+ set(ARCH armv7-freebsd)
+ set(NEON True)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
+ set(ARCH aarch64-freebsd)
+ set(NEON True)
+ else()
+ message(WARNING "unknown CPU: ${CPU}")
+ endif()
+endif()
+
+# Disable ALSA by default
+if(NOT ENABLE_ALSA)
+ option(ENABLE_ALSA "Enable alsa support?" OFF)
+endif()
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_POSIX_NETWORK -DHAS_FREEBSD_NETWORK)
+
+# Build internal libs
+if(NOT USE_INTERNAL_LIBS)
+ if(KODI_DEPENDSBUILD)
+ set(USE_INTERNAL_LIBS ON)
+ else()
+ set(USE_INTERNAL_LIBS OFF)
+ endif()
+endif()
diff --git a/cmake/scripts/freebsd/ExtraTargets.cmake b/cmake/scripts/freebsd/ExtraTargets.cmake
new file mode 100644
index 0000000..9d5d214
--- /dev/null
+++ b/cmake/scripts/freebsd/ExtraTargets.cmake
@@ -0,0 +1 @@
+include(cmake/scripts/linux/ExtraTargets.cmake)
diff --git a/cmake/scripts/freebsd/Install.cmake b/cmake/scripts/freebsd/Install.cmake
new file mode 120000
index 0000000..28ce012
--- /dev/null
+++ b/cmake/scripts/freebsd/Install.cmake
@@ -0,0 +1 @@
+../linux/Install.cmake \ No newline at end of file
diff --git a/cmake/scripts/freebsd/Macros.cmake b/cmake/scripts/freebsd/Macros.cmake
new file mode 100644
index 0000000..ef5aed3
--- /dev/null
+++ b/cmake/scripts/freebsd/Macros.cmake
@@ -0,0 +1,95 @@
+function(core_link_library lib wraplib)
+ set(export -Wl,--unresolved-symbols=ignore-all
+ `cat ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/wrapper.def`
+ ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/CMakeFiles/wrapper.dir/wrapper.c.o)
+ set(check_arg "")
+ if(TARGET ${lib})
+ set(target ${lib})
+ set(link_lib $<TARGET_FILE:${lib}>)
+ set(check_arg ${ARGV2})
+ set(data_arg ${ARGV3})
+ else()
+ set(target ${ARGV2})
+ set(link_lib ${lib})
+ set(check_arg ${ARGV3})
+ set(data_arg ${ARGV4})
+ endif()
+
+ # wrapper has to be adapted in order to support coverage.
+ if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ set(export "")
+ endif()
+
+ if(check_arg STREQUAL export)
+ set(export ${export}
+ -Wl,--version-script=${ARGV3})
+ elseif(check_arg STREQUAL extras)
+ foreach(arg ${data_arg})
+ list(APPEND export ${arg})
+ endforeach()
+ elseif(check_arg STREQUAL archives)
+ set(extra_libs ${data_arg})
+ endif()
+
+ string(REGEX REPLACE "[ ]+" ";" _flags "${CMAKE_SHARED_LINKER_FLAGS}")
+ get_filename_component(dir ${wraplib} DIRECTORY)
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
+ COMMAND ${CMAKE_C_COMPILER}
+ ARGS ${_flags} -Wl,--whole-archive
+ "${link_lib}" ${extra_libs}
+ -Wl,--no-whole-archive -lm
+ -Wl,-soname,${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ -shared -o ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ ${export}
+ DEPENDS ${target} wrapper.def wrapper)
+
+ get_filename_component(libname ${wraplib} NAME_WE)
+ add_custom_target(wrap_${libname} ALL DEPENDS ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX})
+ set_target_properties(wrap_${libname} PROPERTIES FOLDER lib/wrapped)
+ add_dependencies(${APP_NAME_LC}-libraries wrap_${libname})
+
+ set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX} CACHE STRING "" FORCE)
+endfunction()
+
+function(find_soname lib)
+ cmake_parse_arguments(arg "REQUIRED" "" "" ${ARGN})
+
+ string(TOLOWER ${lib} liblow)
+ if(${lib}_LDFLAGS)
+ set(link_lib "${${lib}_LDFLAGS}")
+ else()
+ if(IS_ABSOLUTE "${${lib}_LIBRARIES}")
+ set(link_lib "${${lib}_LIBRARIES}")
+ else()
+ set(link_lib -l${${lib}_LIBRARIES})
+ endif()
+ endif()
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -nostdlib -o /dev/null -Wl,-M ${link_lib}
+ COMMAND grep LOAD.*${liblow}
+ ERROR_QUIET
+ OUTPUT_VARIABLE ${lib}_FILENAME)
+ string(REPLACE "LOAD " "" ${lib}_FILENAME "${${lib}_FILENAME}")
+ string(STRIP "${${lib}_FILENAME}" ${lib}_FILENAME)
+ if(NOT ${lib}_FILENAME)
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -nostdlib -o /dev/null -Wl,-t ${link_lib}
+ ERROR_QUIET
+ OUTPUT_VARIABLE _TMP_FILENAME)
+ string(REGEX MATCH ".*lib${liblow}.so" ${lib}_FILENAME ${_TMP_FILENAME})
+ endif()
+ if(${lib}_FILENAME)
+ execute_process(COMMAND ${CMAKE_OBJDUMP} -p ${${lib}_FILENAME}
+ COMMAND grep SONAME.*${liblow}
+ ERROR_QUIET
+ OUTPUT_VARIABLE ${lib}_SONAME)
+ string(REPLACE "SONAME " "" ${lib}_SONAME ${${lib}_SONAME})
+ string(STRIP ${${lib}_SONAME} ${lib}_SONAME)
+ if(VERBOSE)
+ message(STATUS "${lib} soname: ${${lib}_SONAME}")
+ endif()
+ set(${lib}_SONAME ${${lib}_SONAME} PARENT_SCOPE)
+ endif()
+ if(arg_REQUIRED AND NOT ${lib}_SONAME)
+ message(FATAL_ERROR "Could not find dynamically loadable library ${lib}")
+ endif()
+endfunction()
diff --git a/cmake/scripts/freebsd/PathSetup.cmake b/cmake/scripts/freebsd/PathSetup.cmake
new file mode 120000
index 0000000..6786c1c
--- /dev/null
+++ b/cmake/scripts/freebsd/PathSetup.cmake
@@ -0,0 +1 @@
+../linux/PathSetup.cmake \ No newline at end of file
diff --git a/cmake/scripts/linux/ArchSetup.cmake b/cmake/scripts/linux/ArchSetup.cmake
new file mode 100644
index 0000000..4083483
--- /dev/null
+++ b/cmake/scripts/linux/ArchSetup.cmake
@@ -0,0 +1,207 @@
+include(cmake/scripts/linux/Linkers.txt)
+
+# Main cpp
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/posix/main.cpp)
+
+# we always want to use GNU features if available, so set _GNU_SOURCE
+set(ARCH_DEFINES -DTARGET_POSIX -DTARGET_LINUX -D_GNU_SOURCE)
+set(SYSTEM_DEFINES -D__STDC_CONSTANT_MACROS -D_FILE_OFFSET_BITS=64)
+set(PLATFORM_DIR platform/linux)
+set(PLATFORMDEFS_DIR platform/posix)
+set(CMAKE_SYSTEM_NAME Linux)
+if(WITH_ARCH)
+ set(ARCH ${WITH_ARCH})
+else()
+ if(CPU STREQUAL x86_64)
+ set(ARCH x86_64-linux)
+ set(NEON False)
+ elseif(CPU MATCHES "i.86")
+ set(ARCH i486-linux)
+ set(NEON False)
+ add_options(CXX ALL_BUILDS "-msse")
+ elseif(CPU STREQUAL arm1176jzf-s)
+ set(ARCH arm)
+ set(NEON False)
+ set(NEON_FLAGS "-mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp")
+ elseif(CPU MATCHES "cortex-a7")
+ set(ARCH arm)
+ set(NEON True)
+ set(NEON_FLAGS "-fPIC -mcpu=cortex-a7")
+ elseif(CPU MATCHES "cortex-a53")
+ set(ARCH arm)
+ set(NEON True)
+ set(NEON_FLAGS "-fPIC -mcpu=cortex-a53")
+ elseif(CPU MATCHES arm)
+ set(ARCH arm)
+ set(NEON True)
+ elseif(CPU MATCHES aarch64 OR CPU MATCHES arm64)
+ set(ARCH aarch64)
+ set(NEON True)
+ elseif(CPU MATCHES riscv64)
+ set(ARCH riscv64)
+ set(NEON False)
+ elseif(CPU MATCHES ppc64le)
+ set(ARCH ppc64le)
+ set(NEON False)
+ elseif(CPU MATCHES loongarch64)
+ set(ARCH loongarch64)
+ set(NEON False)
+ else()
+ message(SEND_ERROR "Unknown CPU: ${CPU}")
+ endif()
+endif()
+
+# disable the default gold linker when an alternative was enabled by the user
+if(ENABLE_LLD OR ENABLE_MOLD)
+ set(ENABLE_GOLD OFF CACHE BOOL "" FORCE)
+elseif(ENABLE_GOLD)
+ include(LDGOLD)
+endif()
+if(ENABLE_LLD)
+ set(ENABLE_MOLD OFF CACHE BOOL "" FORCE)
+ include(LLD)
+elseif(ENABLE_MOLD)
+ set(ENABLE_LLD OFF CACHE BOOL "" FORCE)
+ include(MOLD)
+endif()
+
+
+if(CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
+
+ # LTO Support, requires cmake >= 3.9
+ if(CMAKE_VERSION VERSION_EQUAL 3.9.0 OR CMAKE_VERSION VERSION_GREATER 3.9.0)
+ option(USE_LTO "Enable link time optimization. Specify an int for number of parallel jobs" OFF)
+ if(USE_LTO)
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT HAVE_LTO OUTPUT _output)
+ if(HAVE_LTO)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+
+ # override flags to enable parallel processing
+ set(NJOBS 2)
+ if(USE_LTO MATCHES "^[0-9]+$")
+ set(NJOBS ${USE_LTO})
+ endif()
+
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ # GCC
+ # Make sure we strip binaries in Release build
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
+ set(CMAKE_CXX_COMPILE_OPTIONS_IPO -flto=${NJOBS} -fno-fat-lto-objects)
+ set(CMAKE_C_COMPILE_OPTIONS_IPO -flto=${NJOBS} -fno-fat-lto-objects)
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ # CLANG
+ set(ENABLE_GOLD OFF CACHE BOOL "gold linker forced to off" FORCE)
+
+ find_package(LLVM REQUIRED)
+
+ if(NOT CLANG_LTO_CACHE)
+ set(CLANG_LTO_CACHE ${PROJECT_BINARY_DIR}/.clang-lto.cache)
+ endif()
+ if(USE_LTO STREQUAL "all")
+ set(NJOBS ${USE_LTO})
+ endif()
+
+ set(CMAKE_CXX_COMPILE_OPTIONS_IPO -flto=thin)
+ set(CMAKE_C_COMPILE_OPTIONS_IPO -flto=thin)
+ if(LLD_FOUND)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--thinlto-jobs=${NJOBS},--thinlto-cache-dir=${CLANG_LTO_CACHE}")
+ elseif(MOLD_FOUND)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--plugin-opt=jobs=${NJOBS},--plugin-opt=cache-dir=${CLANG_LTO_CACHE}")
+ endif()
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+ endif()
+ else()
+ message(WARNING "LTO optimization not supported: ${_output}")
+ unset(_output)
+ endif()
+ endif()
+ endif()
+endif()
+
+if(KODI_DEPENDSBUILD)
+ # Binaries should be directly runnable from host, so include rpath to depends
+ set(CMAKE_INSTALL_RPATH "${DEPENDS_PATH}/lib")
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+endif()
+
+include(CheckIncludeFiles)
+check_include_files("linux/udmabuf.h" HAVE_LINUX_UDMABUF)
+if(HAVE_LINUX_UDMABUF)
+ list(APPEND ARCH_DEFINES "-DHAVE_LINUX_UDMABUF=1")
+else()
+ message(STATUS "include/linux/udmabuf.h not found")
+endif()
+
+check_include_files("linux/dma-heap.h" HAVE_LINUX_DMA_HEAP)
+if(HAVE_LINUX_DMA_HEAP)
+ list(APPEND ARCH_DEFINES "-DHAVE_LINUX_DMA_HEAP=1")
+else()
+ message(STATUS "include/linux/dma-heap.h not found")
+endif()
+
+check_include_files("linux/dma-buf.h" HAVE_LINUX_DMA_BUF)
+if(HAVE_LINUX_DMA_BUF)
+ list(APPEND ARCH_DEFINES "-DHAVE_LINUX_DMA_BUF=1")
+else()
+ message(STATUS "include/linux/dma-buf.h not found")
+endif()
+
+include(CheckSymbolExists)
+set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
+check_symbol_exists("mkostemp" "stdlib.h" HAVE_MKOSTEMP)
+set(CMAKE_REQUIRED_DEFINITIONS "")
+if(HAVE_MKOSTEMP)
+ list(APPEND ARCH_DEFINES "-DHAVE_MKOSTEMP=1")
+endif()
+
+set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
+check_symbol_exists("memfd_create" "sys/mman.h" HAVE_LINUX_MEMFD)
+set(CMAKE_REQUIRED_DEFINITIONS "")
+if(HAVE_LINUX_MEMFD)
+ list(APPEND ARCH_DEFINES "-DHAVE_LINUX_MEMFD=1")
+else()
+ message(STATUS "memfd_create() not found")
+endif()
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_POSIX_NETWORK -DHAS_LINUX_NETWORK)
+
+# Code Coverage
+if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ set(COVERAGE_TEST_BINARY ${APP_NAME_LC}-test)
+ set(COVERAGE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+ set(COVERAGE_DEPENDS "\${APP_NAME_LC}" "\${APP_NAME_LC}-test")
+ set(COVERAGE_EXCLUDES */test/* lib/* */lib/*)
+endif()
+
+if(NOT "x11" IN_LIST CORE_PLATFORM_NAME_LC)
+ set(ENABLE_VDPAU OFF CACHE BOOL "Disabling VDPAU" FORCE)
+endif()
+
+if("x11" IN_LIST CORE_PLATFORM_NAME_LC AND ENABLE_VDPAU)
+ set(ENABLE_GLX ON CACHE BOOL "Enabling GLX" FORCE)
+endif()
+
+# Architecture endianness detector
+include(TestBigEndian)
+TEST_BIG_ENDIAN(ARCH_IS_BIGENDIAN)
+if(ARCH_IS_BIGENDIAN)
+ message(STATUS "Host architecture is big-endian")
+ list(APPEND ARCH_DEFINES "-DWORDS_BIGENDIAN=1")
+else()
+ message(STATUS "Host architecture is little-endian")
+endif()
+
+# Build internal libs
+if(NOT USE_INTERNAL_LIBS)
+ if(KODI_DEPENDSBUILD)
+ set(USE_INTERNAL_LIBS ON)
+ else()
+ set(USE_INTERNAL_LIBS OFF)
+ endif()
+endif()
+
+# Atomic library
+list(APPEND PLATFORM_REQUIRED_DEPS Atomic)
diff --git a/cmake/scripts/linux/CodeCoverage.cmake b/cmake/scripts/linux/CodeCoverage.cmake
new file mode 100644
index 0000000..f0a36fc
--- /dev/null
+++ b/cmake/scripts/linux/CodeCoverage.cmake
@@ -0,0 +1,97 @@
+# - CodeCoverage
+# Generate code coverage reports with LCOV and GCovr.
+#
+# Configuration:
+# COVERAGE_SOURCE_DIR - Source root directory (default ${CMAKE_SOURCE_DIR}).
+# COVERAGE_BINARY_DIR - Directory where the coverage reports (and intermediate files)
+# are generated to.
+# COVERAGE_EXCLUDES - List of exclude patterns (for example '*/tests/*').
+#
+# The following targets will be generated:
+# coverage - Builds an html report. Requires LCOV.
+# coverage_xml - Builds an xml report (in Cobertura format for Jenkins).
+# Requires Gcovr.
+#
+# Inspired by https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake
+
+# Compiler and linker setup
+set(CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING
+ "Flags used by the C compiler during coverage builds." FORCE)
+set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING
+ "Flags used by the C++ compiler during coverage builds." FORCE)
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING
+ "Flags used for linking binaries during coverage builds." FORCE)
+set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING
+ "Flags used by the shared libraries linker during coverage builds." FORCE)
+mark_as_advanced(
+ CMAKE_C_FLAGS_COVERAGE CMAKE_CXX_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE CMAKE_STATIC_LINKER_FLAGS_COVERAGE
+)
+
+find_program(LCOV_EXECUTABLE lcov)
+find_program(GENINFO_EXECUTABLE geninfo)
+find_program(GENHTML_EXECUTABLE genhtml)
+find_program(GCOVR_EXECUTABLE gcovr)
+mark_as_advanced(LCOV_EXECUTABLE GENINFO_EXECUTABLE GENHTML_EXECUTABLE GCOVR_EXECUTABLE)
+
+# Default options
+if(NOT COVERAGE_SOURCE_DIR)
+ set(COVERAGE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+endif()
+if(NOT COVERAGE_BINARY_DIR)
+ set(COVERAGE_BINARY_DIR ${CMAKE_BINARY_DIR}/coverage)
+endif()
+if(NOT COVERAGE_EXCLUDES)
+ set(COVERAGE_EXCLUDES)
+endif()
+
+# Allow variables in COVERAGE_DEPENDS that are not evaluated before this file is included.
+string(CONFIGURE "${COVERAGE_DEPENDS}" COVERAGE_DEPENDS)
+
+# Add coverage target that generates an HTML report using LCOV
+if(LCOV_EXECUTABLE AND GENINFO_EXECUTABLE AND GENHTML_EXECUTABLE)
+ file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR})
+ add_custom_target(coverage
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_BINARY_DIR}
+ COMMAND ${LCOV_EXECUTABLE} -z -q -d ${CMAKE_BINARY_DIR}
+ COMMAND ${LCOV_EXECUTABLE} -c -q -i -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true
+ COMMAND ${LCOV_EXECUTABLE} -c -q -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info
+ COMMAND ${LCOV_EXECUTABLE} -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info
+ -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info -q
+ COMMAND ${LCOV_EXECUTABLE} -q -r ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ /usr/include/* ${CMAKE_BINARY_DIR}/* ${COVERAGE_EXCLUDES}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ COMMAND ${GENHTML_EXECUTABLE} ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ -o ${COVERAGE_BINARY_DIR}/html -s --legend --highlight --demangle-cpp
+ COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/html/index.html"
+ WORKING_DIRECTORY ${COVERAGE_BINARY_DIR}
+ VERBATIM
+ DEPENDS ${COVERAGE_DEPENDS}
+ COMMENT "Generate code coverage html report"
+ )
+else()
+ message(WARNING "Target coverage not available (lcov, geninfo and genhtml needed).")
+endif()
+
+# Add coverage target that generates an XML report using Gcovr
+if(GCOVR_EXECUTABLE)
+ file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR})
+ string(REGEX REPLACE "([^;]+)" "--exclude=\"\\1\"" _gcovr_excludes "${COVERAGE_EXCLUDES}")
+ string(REPLACE "*" ".*" _gcovr_excludes "${_gcovr_excludes}")
+ add_custom_target(coverage_xml
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true
+ COMMAND ${GCOVR_EXECUTABLE} -x -r ${COVERAGE_SOURCE_DIR} -o ${COVERAGE_BINARY_DIR}/coverage.xml
+ --object-directory ${CMAKE_BINARY_DIR} ${_gcovr_excludes} ${CMAKE_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/coverage.xml"
+ WORKING_DIRECTORY ${COVERAGE_BINARY_DIR}
+ DEPENDS ${COVERAGE_DEPENDS}
+ COMMENT "Generate code coverage xml report"
+ )
+ unset(_gcovr_excludes)
+else()
+ message(WARNING "Target coverage_xml not available (gcovr needed).")
+endif()
diff --git a/cmake/scripts/linux/ExtraTargets.cmake b/cmake/scripts/linux/ExtraTargets.cmake
new file mode 100644
index 0000000..4f5078b
--- /dev/null
+++ b/cmake/scripts/linux/ExtraTargets.cmake
@@ -0,0 +1,32 @@
+# xrandr
+if(X_FOUND AND XRANDR_FOUND)
+ find_package(X QUIET)
+ find_package(XRandR QUIET)
+ add_executable(${APP_NAME_LC}-xrandr ${CMAKE_SOURCE_DIR}/xbmc-xrandr.c)
+ target_link_libraries(${APP_NAME_LC}-xrandr ${SYSTEM_LDFLAGS} ${X_LIBRARIES} m ${XRANDR_LIBRARIES})
+endif()
+
+# WiiRemote
+if(ENABLE_EVENTCLIENTS AND BLUETOOTH_FOUND)
+ find_package(CWiid QUIET)
+ find_package(GLU QUIET)
+ if(CWIID_FOUND AND GLU_FOUND)
+ add_subdirectory(${CMAKE_SOURCE_DIR}/tools/EventClients/Clients/WiiRemote build/WiiRemote)
+ endif()
+endif()
+
+if("wayland" IN_LIST CORE_PLATFORM_NAME_LC)
+ # This cannot go into wayland.cmake since it requires the Wayland dependencies
+ # to already be resolved
+ set(PROTOCOL_XMLS "${WAYLANDPP_PROTOCOLS_DIR}/presentation-time.xml"
+ "${WAYLANDPP_PROTOCOLS_DIR}/xdg-shell.xml"
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-shell/xdg-shell-unstable-v6.xml"
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml")
+ add_custom_command(OUTPUT "${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-extra-protocols.hpp" "${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-extra-protocols.cpp"
+ COMMAND "${WAYLANDPP_SCANNER}" ${PROTOCOL_XMLS} "${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-extra-protocols.hpp" "${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-extra-protocols.cpp"
+ DEPENDS "${WAYLANDPP_SCANNER}" ${PROTOCOL_XMLS}
+ COMMENT "Generating wayland-protocols C++ wrappers")
+
+ # Dummy target for dependencies
+ add_custom_target(generate-wayland-extra-protocols DEPENDS wayland-extra-protocols.hpp)
+endif()
diff --git a/cmake/scripts/linux/Install.cmake b/cmake/scripts/linux/Install.cmake
new file mode 100644
index 0000000..331722c
--- /dev/null
+++ b/cmake/scripts/linux/Install.cmake
@@ -0,0 +1,329 @@
+if(X_FOUND)
+ set(USE_X11 1)
+else()
+ set(USE_X11 0)
+endif()
+if(OPENGL_FOUND)
+ set(USE_OPENGL 1)
+else()
+ set(USE_OPENGL 0)
+endif()
+if(OPENGLES_FOUND)
+ set(USE_OPENGLES 1)
+else()
+ set(USE_OPENGLES 0)
+endif()
+
+# CMake config
+set(APP_BINARY ${APP_NAME_LC}${APP_BINARY_SUFFIX})
+set(APP_PREFIX ${prefix})
+set(APP_LIB_DIR ${libdir}/${APP_NAME_LC})
+set(APP_DATA_DIR ${datarootdir}/${APP_NAME_LC})
+set(APP_INCLUDE_DIR ${includedir}/${APP_NAME_LC})
+
+# Set XBMC_STANDALONE_SH_PULSE so we can insert PulseAudio block into kodi-standalone
+if(EXISTS ${CMAKE_SOURCE_DIR}/tools/Linux/kodi-standalone.sh.pulse)
+ if(ENABLE_PULSEAUDIO AND PULSEAUDIO_FOUND)
+ file(READ "${CMAKE_SOURCE_DIR}/tools/Linux/kodi-standalone.sh.pulse" pulse_content)
+ set(XBMC_STANDALONE_SH_PULSE ${pulse_content})
+ endif()
+endif()
+
+# Configure startup scripts
+configure_file(${CMAKE_SOURCE_DIR}/tools/Linux/kodi.sh.in
+ ${CORE_BUILD_DIR}/scripts/${APP_NAME_LC} @ONLY)
+configure_file(${CMAKE_SOURCE_DIR}/tools/Linux/kodi-standalone.sh.in
+ ${CORE_BUILD_DIR}/scripts/${APP_NAME_LC}-standalone @ONLY)
+
+# Configure cmake files
+configure_file(${CMAKE_SOURCE_DIR}/cmake/KodiConfig.cmake.in
+ ${CORE_BUILD_DIR}/scripts/${APP_NAME}Config.cmake @ONLY)
+
+# Configure xsession entry
+configure_file(${CMAKE_SOURCE_DIR}/tools/Linux/kodi-xsession.desktop.in
+ ${CORE_BUILD_DIR}/${APP_NAME_LC}-xsession.desktop @ONLY)
+
+# Configure desktop entry
+configure_file(${CMAKE_SOURCE_DIR}/tools/Linux/kodi.desktop.in
+ ${CORE_BUILD_DIR}/${APP_NAME_LC}.desktop @ONLY)
+
+# Configure metainfo
+configure_file(${CMAKE_SOURCE_DIR}/tools/Linux/kodi.metainfo.xml.in
+ ${CORE_BUILD_DIR}/${APP_PACKAGE}.metainfo.xml @ONLY)
+
+# Install app
+install(TARGETS ${APP_NAME_LC}
+ DESTINATION ${libdir}/${APP_NAME_LC}
+ COMPONENT kodi-bin)
+if(X_FOUND AND XRANDR_FOUND)
+ install(TARGETS ${APP_NAME_LC}-xrandr
+ DESTINATION ${libdir}/${APP_NAME_LC}
+ COMPONENT kodi-bin)
+endif()
+
+# Install scripts
+install(PROGRAMS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/scripts/${APP_NAME_LC}
+ ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/scripts/${APP_NAME_LC}-standalone
+ DESTINATION ${bindir}
+ COMPONENT kodi-bin)
+
+# Install libraries
+foreach(library ${LIBRARY_FILES})
+ get_filename_component(dir ${library} DIRECTORY)
+ string(REPLACE "${CMAKE_BINARY_DIR}/" "" dir ${dir})
+ install(PROGRAMS ${library}
+ DESTINATION ${libdir}/${APP_NAME_LC}/${dir}
+ COMPONENT kodi-bin)
+endforeach()
+
+# Install add-ons, fonts, icons, keyboard maps, keymaps, etc
+# (addons, media, system, userdata folders in share/kodi/)
+foreach(file ${install_data})
+ get_filename_component(dir ${file} DIRECTORY)
+ install(FILES ${CMAKE_BINARY_DIR}/${file}
+ DESTINATION ${datarootdir}/${APP_NAME_LC}/${dir}
+ COMPONENT kodi)
+endforeach()
+
+# Install xsession entry
+install(FILES ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${APP_NAME_LC}-xsession.desktop
+ RENAME ${APP_NAME_LC}.desktop
+ DESTINATION ${datarootdir}/xsessions
+ COMPONENT kodi)
+
+# Install desktop entry
+install(FILES ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${APP_NAME_LC}.desktop
+ DESTINATION ${datarootdir}/applications
+ COMPONENT kodi)
+
+# Install metainfo
+install(FILES ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${APP_PACKAGE}.metainfo.xml
+ DESTINATION ${datarootdir}/metainfo
+ COMPONENT kodi)
+
+# Install icons
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon16x16.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/16x16/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon22x22.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/22x22/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon24x24.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/24x24/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon32x32.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/32x32/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon48x48.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/48x48/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon64x64.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/64x64/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon128x128.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/128x128/apps
+ COMPONENT kodi)
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/packaging/media/icon256x256.png
+ RENAME ${APP_NAME_LC}.png
+ DESTINATION ${datarootdir}/icons/hicolor/256x256/apps
+ COMPONENT kodi)
+
+# Install firewalld service definitions
+install(FILES ${CMAKE_SOURCE_DIR}/tools/Linux/firewalld-services/kodi-eventserver.xml
+ ${CMAKE_SOURCE_DIR}/tools/Linux/firewalld-services/kodi-http.xml
+ ${CMAKE_SOURCE_DIR}/tools/Linux/firewalld-services/kodi-jsonrpc.xml
+ DESTINATION ${prefix}/lib/firewalld/services
+ COMPONENT kodi)
+
+# Install docs
+install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.md
+ ${CMAKE_SOURCE_DIR}/version.txt
+ ${CMAKE_SOURCE_DIR}/docs/README.Linux.md
+ DESTINATION ${docdir}
+ COMPONENT kodi)
+
+install(FILES ${CMAKE_SOURCE_DIR}/privacy-policy.txt
+ DESTINATION ${datarootdir}/${APP_NAME_LC}
+ COMPONENT kodi)
+
+# Install kodi-tools-texturepacker
+if(INTERNAL_TEXTUREPACKER_INSTALLABLE)
+ install(PROGRAMS $<TARGET_FILE:TexturePacker::TexturePacker::Installable>
+ DESTINATION ${bindir}
+ RENAME "${APP_NAME_LC}-TexturePacker"
+ COMPONENT kodi-tools-texturepacker)
+endif()
+
+# Install kodi-addon-dev headers
+include(${CMAKE_SOURCE_DIR}/xbmc/addons/AddonBindings.cmake)
+install(DIRECTORY ${CORE_ADDON_BINDINGS_DIRS}/
+ DESTINATION ${includedir}/${APP_NAME_LC}
+ COMPONENT kodi-addon-dev
+ REGEX ".txt" EXCLUDE)
+
+install(FILES ${CORE_ADDON_BINDINGS_FILES}
+ DESTINATION ${includedir}/${APP_NAME_LC}
+ COMPONENT kodi-addon-dev)
+
+# Install kodi-addon-dev add-on bindings
+install(FILES ${CMAKE_SOURCE_DIR}/cmake/scripts/common/AddonHelpers.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/AddOptions.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/ArchSetup.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/CheckCommits.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/GenerateVersionedFiles.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/GeneratorSetup.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/HandleDepends.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/Macros.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/PrepareEnv.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/common/ProjectMacros.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/linux/PathSetup.cmake
+ DESTINATION ${datarootdir}/${APP_NAME_LC}/cmake
+ COMPONENT kodi-addon-dev)
+# ${APP_NAME}Config.cmake contains architecture-specific paths so it
+# should be installed in ${libdir}/${APP_NAME_LC}/${dir}
+install(FILES ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/scripts/${APP_NAME}Config.cmake
+ DESTINATION ${libdir}/${APP_NAME_LC}/cmake
+ COMPONENT kodi-addon-dev)
+
+if(ENABLE_EVENTCLIENTS)
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(prefix=''))"
+ OUTPUT_VARIABLE PYTHON_LIB_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
+ # Install kodi-eventclients-common BT python files
+ install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/bt/__init__.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/bt/bt.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/bt/hid.py
+ DESTINATION ${PYTHON_LIB_PATH}/${APP_NAME_LC}/bt
+ COMPONENT kodi-eventclients-common)
+
+ # Install kodi-eventclients-common PS3 python files
+ install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/ps3/__init__.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/ps3/keymaps.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/ps3/sixaxis.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/ps3/sixpair.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/ps3/sixwatch.py
+ DESTINATION ${PYTHON_LIB_PATH}/${APP_NAME_LC}/ps3
+ COMPONENT kodi-eventclients-common)
+
+ # Install kodi-eventclients-common python files
+ file(WRITE ${CMAKE_BINARY_DIR}/packages/deb/defs.py ICON_PATH="/usr/share/pixmaps/${APP_NAME_LC}/")
+ install(PROGRAMS ${CMAKE_BINARY_DIR}/packages/deb/defs.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/__init__.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/xbmcclient.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/zeroconf.py
+ DESTINATION ${PYTHON_LIB_PATH}/${APP_NAME_LC}
+ COMPONENT kodi-eventclients-common)
+
+ # Install kodi-eventclients-common icons
+ install(FILES ${CMAKE_SOURCE_DIR}/tools/EventClients/icons/bluetooth.png
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/icons/phone.png
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/icons/mail.png
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/icons/mouse.png
+ DESTINATION ${datarootdir}/pixmaps/${APP_NAME_LC}
+ COMPONENT kodi-eventclients-common)
+
+ # Install kodi-eventclients-dev headers
+ install(FILES ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/c++/xbmcclient.h
+ DESTINATION ${includedir}/${APP_NAME_LC}
+ COMPONENT kodi-eventclients-dev)
+
+ # Install kodi-eventclients-dev C# examples
+ install(FILES "${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c#/XBMCDemoClient1.cs"
+ DESTINATION "${docdir}/${APP_NAME_LC}-eventclients-dev/examples/C#"
+ COMPONENT kodi-eventclients-dev)
+
+ # Install kodi-eventclients-dev C++ examples
+ install(FILES ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c++/example_notification.cpp
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c++/example_log.cpp
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c++/example_button1.cpp
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c++/example_mouse.cpp
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/c++/example_button2.cpp
+ DESTINATION ${docdir}/${APP_NAME_LC}-eventclients-dev/examples/C++
+ COMPONENT kodi-eventclients-dev)
+
+ # Install kodi-eventclients-dev java examples
+ install(FILES ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/java/XBMCDemoClient1.java
+ DESTINATION ${docdir}/${APP_NAME_LC}-eventclients-dev/examples/java
+ COMPONENT kodi-eventclients-dev)
+
+ # Install kodi-eventclients-dev python examples
+ install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_mouse.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_button1.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_notification.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_action.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_button2.py
+ ${CMAKE_SOURCE_DIR}/tools/EventClients/examples/python/example_simple.py
+ DESTINATION ${docdir}/${APP_NAME_LC}-eventclients-dev/examples/python
+ COMPONENT kodi-eventclients-dev)
+
+ # Install kodi-eventclients-ps3
+ install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py
+ RENAME ${APP_NAME_LC}-ps3remote
+ DESTINATION ${bindir}
+ COMPONENT kodi-eventclients-ps3)
+
+ if(BLUETOOTH_FOUND AND CWIID_FOUND AND GLU_FOUND)
+ # Install kodi-eventclients-wiiremote
+ install(PROGRAMS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/WiiRemote/${APP_NAME_LC}-wiiremote
+ DESTINATION ${bindir}
+ COMPONENT kodi-eventclients-wiiremote)
+ endif()
+
+ # Install kodi-eventclients-kodi-send
+ install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/Clients/KodiSend/kodi-send.py
+ RENAME ${APP_NAME_LC}-send
+ DESTINATION ${bindir}
+ COMPONENT kodi-eventclients-kodi-send)
+endif()
+
+# Install XBT skin files
+foreach(texture ${XBT_FILES})
+ string(REPLACE "${CMAKE_BINARY_DIR}/" "" dir ${texture})
+ get_filename_component(dir ${dir} DIRECTORY)
+ install(FILES ${texture}
+ DESTINATION ${datarootdir}/${APP_NAME_LC}/${dir}
+ COMPONENT kodi)
+endforeach()
+
+# Install extra stuff if it exists
+if(EXISTS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/extra-installs)
+ install(CODE "file(STRINGS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/extra-installs dirs)
+ foreach(dir \${dirs})
+ file(GLOB_RECURSE FILES RELATIVE ${CMAKE_BINARY_DIR} \${dir}/*)
+ foreach(file \${FILES})
+ get_filename_component(dir \${file} DIRECTORY)
+ file(INSTALL \${file} DESTINATION ${datarootdir}/${APP_NAME_LC}/\${dir})
+ endforeach()
+ endforeach()")
+endif()
+
+if(NOT "$ENV{DESTDIR}" STREQUAL "")
+ set(DESTDIR ${CMAKE_BINARY_DIR}/$ENV{DESTDIR})
+endif()
+foreach(subdir ${build_dirs})
+ if(NOT subdir MATCHES kodi-platform)
+ string(REPLACE " " ";" subdir ${subdir})
+ list(GET subdir 0 id)
+ install(CODE "execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${id}/src/${id}-build install DESTDIR=${DESTDIR})")
+ endif()
+endforeach()
+
+# generate packages? yes please, if everything checks out
+if(CPACK_GENERATOR)
+ if(CPACK_GENERATOR STREQUAL DEB AND CORE_SYSTEM_NAME STREQUAL linux)
+ if(CMAKE_BUILD_TYPE STREQUAL Debug)
+ message(STATUS "DEB Generator: Build type is set to 'Debug'. Packaged binaries will be unstripped.")
+ endif()
+ include(${CMAKE_SOURCE_DIR}/cmake/cpack/CPackConfigDEB.cmake)
+ else()
+ message(FATAL_ERROR "DEB Generator: Can't configure CPack to generate Debian packages on non-linux systems.")
+ endif()
+endif()
diff --git a/cmake/scripts/linux/Linkers.txt b/cmake/scripts/linux/Linkers.txt
new file mode 100644
index 0000000..c947ec4
--- /dev/null
+++ b/cmake/scripts/linux/Linkers.txt
@@ -0,0 +1,4 @@
+# Linkers
+option(ENABLE_GOLD "Enable gnu gold linker?" ON)
+option(ENABLE_LLD "Enable llvm lld linker?" OFF)
+option(ENABLE_MOLD "Enable mold linker?" OFF)
diff --git a/cmake/scripts/linux/Macros.cmake b/cmake/scripts/linux/Macros.cmake
new file mode 100644
index 0000000..37243a7
--- /dev/null
+++ b/cmake/scripts/linux/Macros.cmake
@@ -0,0 +1,95 @@
+function(core_link_library lib wraplib)
+ set(export -Wl,--unresolved-symbols=ignore-all
+ `cat ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/wrapper.def`
+ ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/CMakeFiles/wrapper.dir/wrapper.c.o)
+ set(check_arg "")
+ if(TARGET ${lib})
+ set(target ${lib})
+ set(link_lib $<TARGET_FILE:${lib}>)
+ set(check_arg ${ARGV2})
+ set(data_arg ${ARGV3})
+ else()
+ set(target ${ARGV2})
+ set(link_lib ${lib})
+ set(check_arg ${ARGV3})
+ set(data_arg ${ARGV4})
+ endif()
+
+ # wrapper has to be adapted in order to support coverage.
+ if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ set(export "")
+ endif()
+
+ if(check_arg STREQUAL export)
+ set(export ${export}
+ -Wl,--version-script=${ARGV3})
+ elseif(check_arg STREQUAL extras)
+ foreach(arg ${data_arg})
+ list(APPEND export ${arg})
+ endforeach()
+ elseif(check_arg STREQUAL archives)
+ set(extra_libs ${data_arg})
+ endif()
+
+ string(REGEX REPLACE "[ ]+" ";" _flags "${CMAKE_SHARED_LINKER_FLAGS}")
+ get_filename_component(dir ${wraplib} DIRECTORY)
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
+ COMMAND ${CMAKE_C_COMPILER}
+ ARGS ${_flags} -Wl,--whole-archive
+ "${link_lib}" ${extra_libs}
+ -Wl,--no-whole-archive -lm
+ -Wl,-soname,${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ -shared -o ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX}
+ ${export}
+ DEPENDS ${target} wrapper.def wrapper)
+
+ get_filename_component(libname ${wraplib} NAME_WE)
+ add_custom_target(wrap_${libname} ALL DEPENDS ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX})
+ set_target_properties(wrap_${libname} PROPERTIES FOLDER lib/wrapped)
+ add_dependencies(${APP_NAME_LC}-libraries wrap_${libname})
+
+ set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${CMAKE_SHARED_MODULE_SUFFIX} CACHE STRING "" FORCE)
+endfunction()
+
+function(find_soname lib)
+ cmake_parse_arguments(arg "REQUIRED" "" "" ${ARGN})
+
+ string(TOLOWER ${lib} liblow)
+ if(${lib}_LDFLAGS)
+ set(link_lib "${${lib}_LDFLAGS}")
+ else()
+ if(IS_ABSOLUTE "${${lib}_LIBRARIES}")
+ set(link_lib "${${lib}_LIBRARIES}")
+ else()
+ set(link_lib -l${${lib}_LIBRARIES})
+ endif()
+ endif()
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -nostdlib -o /dev/null -Wl,-M ${link_lib}
+ COMMAND grep LOAD.*${liblow}
+ ERROR_QUIET
+ OUTPUT_VARIABLE ${lib}_FILENAME)
+ string(REPLACE "LOAD " "" ${lib}_FILENAME "${${lib}_FILENAME}")
+ string(STRIP "${${lib}_FILENAME}" ${lib}_FILENAME)
+ if(NOT ${lib}_FILENAME)
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -nostdlib -o /dev/null -Wl,-t ${link_lib}
+ OUTPUT_QUIET
+ ERROR_VARIABLE _TMP_FILENAME)
+ string(REGEX MATCH ".*lib${liblow}.so" ${lib}_FILENAME ${_TMP_FILENAME})
+ endif()
+ if(${lib}_FILENAME)
+ execute_process(COMMAND ${CMAKE_OBJDUMP} -p ${${lib}_FILENAME}
+ COMMAND grep SONAME.*${liblow}
+ ERROR_QUIET
+ OUTPUT_VARIABLE ${lib}_SONAME)
+ string(REPLACE "SONAME " "" ${lib}_SONAME ${${lib}_SONAME})
+ string(STRIP ${${lib}_SONAME} ${lib}_SONAME)
+ if(VERBOSE)
+ message(STATUS "${lib} soname: ${${lib}_SONAME}")
+ endif()
+ set(${lib}_SONAME ${${lib}_SONAME} PARENT_SCOPE)
+ endif()
+ if(arg_REQUIRED AND NOT ${lib}_SONAME)
+ message(FATAL_ERROR "Could not find dynamically loadable library ${lib}")
+ endif()
+endfunction()
diff --git a/cmake/scripts/linux/PathSetup.cmake b/cmake/scripts/linux/PathSetup.cmake
new file mode 100644
index 0000000..f9f78ba
--- /dev/null
+++ b/cmake/scripts/linux/PathSetup.cmake
@@ -0,0 +1,40 @@
+include(GNUInstallDirs)
+
+if(NOT prefix)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+else()
+ set(CMAKE_INSTALL_PREFIX ${prefix})
+endif()
+if(NOT exec_prefix)
+ set(exec_prefix ${prefix})
+endif()
+if(NOT libdir)
+ set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
+endif()
+if(NOT bindir)
+ set(bindir ${CMAKE_INSTALL_FULL_BINDIR})
+endif()
+if(NOT includedir)
+ set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
+endif()
+if(NOT datarootdir)
+ set(datarootdir ${CMAKE_INSTALL_FULL_DATAROOTDIR})
+endif()
+if(NOT datadir)
+ set(datadir ${CMAKE_INSTALL_FULL_DATADIR})
+endif()
+if(NOT docdir)
+ set(docdir ${CMAKE_INSTALL_FULL_DOCDIR})
+endif()
+
+list(APPEND final_message "-- PATH config --")
+list(APPEND final_message "Prefix: ${prefix}")
+list(APPEND final_message "Libdir: ${libdir}")
+list(APPEND final_message "Bindir: ${bindir}")
+list(APPEND final_message "Includedir: ${includedir}")
+list(APPEND final_message "Datarootdir: ${datarootdir}")
+list(APPEND final_message "Datadir: ${datadir}")
+list(APPEND final_message "Docdir: ${docdir}")
+
+set(PATH_DEFINES -DBIN_INSTALL_PATH=\"${libdir}/${APP_NAME_LC}\"
+ -DINSTALL_PATH=\"${datarootdir}/${APP_NAME_LC}\")
diff --git a/cmake/scripts/osx/ArchSetup.cmake b/cmake/scripts/osx/ArchSetup.cmake
new file mode 100644
index 0000000..17f8583
--- /dev/null
+++ b/cmake/scripts/osx/ArchSetup.cmake
@@ -0,0 +1,56 @@
+if(NOT CMAKE_TOOLCHAIN_FILE)
+ message(FATAL_ERROR "CMAKE_TOOLCHAIN_FILE required for osx. See ${CMAKE_SOURCE_DIR}/cmake/README.md")
+endif()
+
+list(APPEND CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/osx/XBMCApplication.h)
+
+set(ARCH_DEFINES -DTARGET_POSIX -DTARGET_DARWIN -DTARGET_DARWIN_OSX)
+list(APPEND SYSTEM_DEFINES -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+ -D__STDC_CONSTANT_MACROS)
+set(PLATFORM_DIR platform/darwin)
+set(PLATFORMDEFS_DIR platform/posix)
+set(CMAKE_SYSTEM_NAME Darwin)
+if(WITH_ARCH)
+ set(ARCH ${WITH_ARCH})
+else()
+ if(CPU STREQUAL x86_64 OR CPU STREQUAL i386)
+ set(ARCH x86-osx)
+ set(NEON False)
+ elseif(CPU STREQUAL arm64)
+ set(ARCH aarch64)
+ else()
+ message(SEND_ERROR "Unknown CPU: ${CPU}")
+ endif()
+endif()
+
+# m1 macs can execute x86_64 code via rosetta
+if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64" AND
+ CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+ set(HOST_CAN_EXECUTE_TARGET TRUE)
+endif()
+
+set(CMAKE_OSX_ARCHITECTURES ${CPU})
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_POSIX_NETWORK -DHAS_OSX_NETWORK -DHAS_ZEROCONF)
+
+list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${NATIVEPREFIX})
+
+list(APPEND DEPLIBS "-framework DiskArbitration" "-framework IOKit"
+ "-framework IOSurface" "-framework SystemConfiguration"
+ "-framework ApplicationServices" "-framework AppKit"
+ "-framework CoreAudio" "-framework AudioToolbox"
+ "-framework CoreGraphics" "-framework CoreMedia"
+ "-framework VideoToolbox" "-framework Security"
+ "-framework GameController" "-framework Speech"
+ "-framework AVFoundation")
+
+if(ARCH STREQUAL aarch64)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
+else()
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
+endif()
+set(CMAKE_XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME OFF)
+
+include(cmake/scripts/darwin/Macros.cmake)
+enable_arc()
diff --git a/cmake/scripts/osx/ExtraTargets.cmake b/cmake/scripts/osx/ExtraTargets.cmake
new file mode 100644
index 0000000..28c1e74
--- /dev/null
+++ b/cmake/scripts/osx/ExtraTargets.cmake
@@ -0,0 +1,3 @@
+# XBMCHelper
+add_subdirectory(${CMAKE_SOURCE_DIR}/tools/EventClients/Clients/OSXRemote build/XBMCHelper)
+add_dependencies(${APP_NAME_LC} XBMCHelper)
diff --git a/cmake/scripts/osx/Install.cmake b/cmake/scripts/osx/Install.cmake
new file mode 100644
index 0000000..b4c4cc8
--- /dev/null
+++ b/cmake/scripts/osx/Install.cmake
@@ -0,0 +1,73 @@
+# OSX packaging
+
+set(PACKAGE_OUTPUT_DIR ${CMAKE_BINARY_DIR}/build/${CORE_BUILD_CONFIG})
+
+configure_file(${CMAKE_SOURCE_DIR}/xbmc/platform/darwin/osx/Info.plist.in
+ ${CMAKE_BINARY_DIR}/xbmc/platform/darwin/osx/Info.plist @ONLY)
+execute_process(COMMAND perl -p -i -e "s/r####/${APP_SCMID}/" ${CMAKE_BINARY_DIR}/xbmc/platform/darwin/osx/Info.plist)
+
+# Create xcode target that allows to build binary-addons.
+if(CMAKE_GENERATOR MATCHES "Xcode")
+ if(ADDONS_TO_BUILD)
+ set(_addons "ADDONS=${ADDONS_TO_BUILD}")
+ endif()
+ add_custom_target(binary-addons
+ COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons clean
+ COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons VERBOSE=1 V=99
+ INSTALL_PREFIX="${CMAKE_BINARY_DIR}/addons" CROSS_COMPILING=yes ${_addons})
+ if(ENABLE_XCODE_ADDONBUILD)
+ add_dependencies(${APP_NAME_LC} binary-addons)
+ endif()
+ unset(_addons)
+endif()
+
+add_custom_target(bundle
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${APP_NAME_LC}> ${PACKAGE_OUTPUT_DIR}/${APP_NAME}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/DllPaths_generated.h
+ ${CMAKE_BINARY_DIR}/xbmc/DllPaths_generated.h
+ COMMAND "ACTION=build"
+ "TARGET_BUILD_DIR=${PACKAGE_OUTPUT_DIR}"
+ "TARGET_NAME=${APP_NAME}.app"
+ "APP_NAME=${APP_NAME}"
+ "SRCROOT=${CMAKE_BINARY_DIR}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/CopyRootFiles-osx.command
+ COMMAND "XBMC_DEPENDS=${DEPENDS_PATH}"
+ "TARGET_BUILD_DIR=${PACKAGE_OUTPUT_DIR}"
+ "TARGET_NAME=${APP_NAME}.app"
+ "APP_NAME=${APP_NAME}"
+ "FULL_PRODUCT_NAME=${APP_NAME}.app"
+ "SRCROOT=${CMAKE_BINARY_DIR}"
+ "PYTHON_VERSION=${PYTHON_VERSION}"
+ ${CMAKE_SOURCE_DIR}/tools/darwin/Support/copyframeworks-osx.command)
+set_target_properties(bundle PROPERTIES FOLDER "Build Utilities")
+add_dependencies(bundle ${APP_NAME_LC})
+
+configure_file(${CMAKE_SOURCE_DIR}/tools/darwin/packaging/osx/mkdmg-osx.sh.in
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/osx/mkdmg-osx.sh @ONLY)
+
+string(TOLOWER ${CORE_BUILD_CONFIG} CORE_BUILD_CONFIG_LOWERCASED)
+if(${CORE_BUILD_CONFIG_LOWERCASED} STREQUAL "release")
+ set(ALLOW_DEBUGGER "false")
+else()
+ set(ALLOW_DEBUGGER "true")
+endif()
+configure_file(${CMAKE_SOURCE_DIR}/tools/darwin/packaging/osx/Kodi.entitlements.in
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/osx/Kodi.entitlements @ONLY)
+
+add_custom_target(dmg
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/osx/
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/osx/
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/tools/darwin/packaging/media/osx/
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/media/osx/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/tools/darwin/Support/Codesign.command
+ ${CMAKE_BINARY_DIR}/tools/darwin/packaging/osx/Codesign.command
+ COMMAND "CODESIGNING_FOLDER_PATH=${PACKAGE_OUTPUT_DIR}/${APP_NAME}.app"
+ "NOTARYTOOL_KEYCHAIN_PROFILE=${NOTARYTOOL_KEYCHAIN_PROFILE}"
+ "NOTARYTOOL_KEYCHAIN_PATH=${NOTARYTOOL_KEYCHAIN_PATH}"
+ "EXPANDED_CODE_SIGN_IDENTITY_NAME=${CODE_SIGN_IDENTITY}"
+ "PLATFORM_NAME=${PLATFORM}"
+ "XCODE_BUILDTYPE=${CMAKE_CFG_INTDIR}"
+ ./mkdmg-osx.sh ${CORE_BUILD_CONFIG_LOWERCASED}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tools/darwin/packaging/osx)
+set_target_properties(dmg PROPERTIES FOLDER "Build Utilities")
+add_dependencies(dmg bundle)
diff --git a/cmake/scripts/osx/Macros.cmake b/cmake/scripts/osx/Macros.cmake
new file mode 100644
index 0000000..f81e218
--- /dev/null
+++ b/cmake/scripts/osx/Macros.cmake
@@ -0,0 +1,119 @@
+function(core_link_library lib wraplib)
+ if(CMAKE_GENERATOR MATCHES "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL Ninja)
+ set(wrapper_obj cores/dll-loader/exports/CMakeFiles/wrapper.dir/wrapper.c.o)
+ elseif(CMAKE_GENERATOR MATCHES "Xcode")
+ # CURRENT_VARIANT is an Xcode env var
+ # CPU is a project cmake var
+ # Xcode new build system (CMAKE_XCODE_BUILD_SYSTEM=12) requires the env var CURRENT_VARIANT to be passed WITHOUT brackets
+ # Xcode Legacy build system (CMAKE_XCODE_BUILD_SYSTEM=1) requires the env var CURRENT_VARIANT to be passed WITH brackets
+ if(CMAKE_XCODE_BUILD_SYSTEM STREQUAL 12)
+ set(wrapper_obj cores/dll-loader/exports/kodi.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/wrapper.build/Objects-$CURRENT_VARIANT/${CPU}/wrapper.o)
+ else()
+ set(wrapper_obj cores/dll-loader/exports/kodi.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/wrapper.build/Objects-$(CURRENT_VARIANT)/${CPU}/wrapper.o)
+ endif()
+ else()
+ message(FATAL_ERROR "Unsupported generator in core_link_library")
+ endif()
+
+ set(export -bundle -undefined dynamic_lookup -read_only_relocs suppress
+ -Wl,-alias_list,${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/cores/dll-loader/exports/wrapper.def
+ ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${wrapper_obj})
+ set(extension ${CMAKE_SHARED_MODULE_SUFFIX})
+ set(check_arg "")
+ if(TARGET ${lib})
+ set(target ${lib})
+ set(link_lib $<TARGET_FILE:${lib}>)
+ set(check_arg ${ARGV2})
+ set(data_arg ${ARGV3})
+
+ else()
+ set(target ${ARGV2})
+ set(link_lib ${lib})
+ set(check_arg ${ARGV3})
+ set(data_arg ${ARGV4})
+ endif()
+ if(check_arg STREQUAL export)
+ set(export ${export}
+ -Wl,--version-script=${ARGV3})
+ elseif(check_arg STREQUAL extras)
+ foreach(arg ${data_arg})
+ list(APPEND export ${arg})
+ endforeach()
+ elseif(check_arg STREQUAL archives)
+ set(extra_libs ${data_arg})
+ endif()
+ get_filename_component(dir ${wraplib} DIRECTORY)
+
+ # We can't simply pass the linker flags to the args section of the custom command
+ # because cmake will add quotes around it (and the linker will fail due to those).
+ # We need to do this handstand first ...
+ string(REPLACE " " ";" CUSTOM_COMMAND_ARGS_LDFLAGS ${CMAKE_SHARED_LINKER_FLAGS})
+
+ add_custom_command(OUTPUT ${wraplib}-${ARCH}${extension}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${dir}
+ COMMAND ${CMAKE_C_COMPILER}
+ ARGS ${CUSTOM_COMMAND_ARGS_LDFLAGS} ${export} -Wl,-force_load ${link_lib} ${extra_libs}
+ -o ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${extension}
+ DEPENDS ${target} wrapper.def wrapper)
+
+ get_filename_component(libname ${wraplib} NAME_WE)
+ add_custom_target(wrap_${libname} ALL DEPENDS ${wraplib}-${ARCH}${extension})
+ set_target_properties(wrap_${libname} PROPERTIES FOLDER lib/wrapped)
+ add_dependencies(${APP_NAME_LC}-libraries wrap_${libname})
+
+ set(LIBRARY_FILES ${LIBRARY_FILES} ${CMAKE_BINARY_DIR}/${wraplib}-${ARCH}${extension} CACHE STRING "" FORCE)
+endfunction()
+
+function(find_soname lib)
+ cmake_parse_arguments(arg "REQUIRED" "" "" ${ARGN})
+
+ string(TOLOWER ${lib} liblow)
+ if(${lib}_LDFLAGS)
+ set(link_lib "${${lib}_LDFLAGS}")
+ else()
+ set(link_lib "${${lib}_LIBRARIES}")
+ endif()
+
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs
+ COMMAND fgrep libraries:
+ COMMAND sed "s/[^=]*=\\(.*\\)/\\1/"
+ COMMAND sed "s/:/ /g"
+ ERROR_QUIET
+ OUTPUT_VARIABLE cc_lib_path
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND echo ${link_lib}
+ COMMAND sed "s/-L[ ]*//g"
+ COMMAND sed "s/-l[^ ]*//g"
+ ERROR_QUIET
+ OUTPUT_VARIABLE env_lib_path
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ foreach(path ${cc_lib_path} ${env_lib_path})
+ if(IS_DIRECTORY ${path})
+ execute_process(COMMAND ls -- ${path}/lib${liblow}.dylib
+ ERROR_QUIET
+ OUTPUT_VARIABLE lib_file
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ set(lib_file ${path})
+ endif()
+ if(lib_file)
+ # we want the path/name that is embedded in the dylib
+ execute_process(COMMAND otool -L ${lib_file}
+ COMMAND grep -v lib${liblow}.dylib
+ COMMAND grep ${liblow}
+ COMMAND awk "{V=1; print $V}"
+ ERROR_QUIET
+ OUTPUT_VARIABLE filename
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ get_filename_component(${lib}_SONAME "${filename}" NAME)
+ if(VERBOSE)
+ message(STATUS "${lib} soname: ${${lib}_SONAME}")
+ endif()
+ endif()
+ endforeach()
+ if(arg_REQUIRED AND NOT ${lib}_SONAME)
+ message(FATAL_ERROR "Could not find dynamically loadable library ${lib}")
+ endif()
+ set(${lib}_SONAME ${${lib}_SONAME} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/scripts/osx/PathSetup.cmake b/cmake/scripts/osx/PathSetup.cmake
new file mode 100644
index 0000000..ddb4176
--- /dev/null
+++ b/cmake/scripts/osx/PathSetup.cmake
@@ -0,0 +1,32 @@
+if(NOT prefix)
+ set(prefix ${DEPENDS_PATH})
+endif()
+if(NOT exec_prefix)
+ set(exec_prefix ${prefix})
+endif()
+if(NOT libdir)
+ set(libdir ${prefix}/lib)
+endif()
+if(NOT bindir)
+ set(bindir ${prefix}/bin)
+endif()
+if(NOT includedir)
+ set(includedir ${prefix}/include)
+endif()
+if(NOT datarootdir)
+ set(datarootdir ${prefix}/share)
+endif()
+if(NOT datadir)
+ set(datadir ${datarootdir})
+endif()
+
+list(APPEND final_message "-- PATH config --")
+list(APPEND final_message "Prefix: ${prefix}")
+list(APPEND final_message "Libdir: ${libdir}")
+list(APPEND final_message "Bindir: ${bindir}")
+list(APPEND final_message "Includedir: ${includedir}")
+list(APPEND final_message "Datarootdir: ${datarootdir}")
+list(APPEND final_message "Datadir: ${datadir}")
+
+set(PATH_DEFINES -DBIN_INSTALL_PATH=\"${libdir}/${APP_NAME_LC}\"
+ -DINSTALL_PATH=\"${datarootdir}/${APP_NAME_LC}\")
diff --git a/cmake/scripts/windows/ArchSetup.cmake b/cmake/scripts/windows/ArchSetup.cmake
new file mode 100644
index 0000000..f0f8a08
--- /dev/null
+++ b/cmake/scripts/windows/ArchSetup.cmake
@@ -0,0 +1,128 @@
+# Minimum SDK version we support
+set(VS_MINIMUM_SDK_VERSION 10.0.14393.0)
+
+if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS VS_MINIMUM_SDK_VERSION)
+ message(FATAL_ERROR "Detected Windows SDK version is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}.\n"
+ "Windows SDK ${VS_MINIMUM_SDK_VERSION} or higher is required.\n"
+ "INFO: Windows SDKs can be installed from the Visual Studio installer.")
+endif()
+
+# -------- Host Settings ---------
+
+set(_gentoolset ${CMAKE_GENERATOR_TOOLSET})
+string(REPLACE "host=" "" HOSTTOOLSET "${_gentoolset}")
+unset(_gentoolset)
+
+# -------- Architecture settings ---------
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(ARCH win32)
+ set(SDK_TARGET_ARCH x86)
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(ARCH x64)
+ set(SDK_TARGET_ARCH x64)
+endif()
+
+
+# -------- Paths (mainly for find_package) ---------
+
+set(PLATFORM_DIR platform/win32)
+set(APP_RENDER_SYSTEM dx11)
+
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/WinMain.cpp)
+
+# Precompiled headers fail with per target output directory. (needs CMake 3.1)
+set(PRECOMPILEDHEADER_DIR ${PROJECT_BINARY_DIR}/${CORE_BUILD_CONFIG}/objs)
+set(CMAKE_SYSTEM_NAME Windows)
+set(DEPS_FOLDER_RELATIVE project/BuildDependencies)
+set(NATIVEPREFIX ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/tools)
+set(DEPENDS_PATH ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/${ARCH})
+set(MINGW_LIBS_DIR ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/mingwlibs/${ARCH})
+
+# mingw libs
+list(APPEND CMAKE_PREFIX_PATH ${MINGW_LIBS_DIR})
+list(APPEND CMAKE_LIBRARY_PATH ${MINGW_LIBS_DIR}/bin)
+
+if(NOT TARBALL_DIR)
+ set(TARBALL_DIR "${CMAKE_SOURCE_DIR}/project/BuildDependencies/downloads")
+endif()
+
+# -------- Compiler options ---------
+
+add_options(CXX ALL_BUILDS "/wd\"4996\"")
+set(ARCH_DEFINES -D_WINDOWS -DTARGET_WINDOWS -DTARGET_WINDOWS_DESKTOP -D__SSE__ -D__SSE2__)
+set(SYSTEM_DEFINES -DWIN32_LEAN_AND_MEAN -DNOMINMAX -DHAS_DX -D__STDC_CONSTANT_MACROS
+ -DTAGLIB_STATIC -DNPT_CONFIG_ENABLE_LOGGING
+ -DPLT_HTTP_DEFAULT_USER_AGENT="UPnP/1.0 DLNADOC/1.50 Kodi"
+ -DPLT_HTTP_DEFAULT_SERVER="UPnP/1.0 DLNADOC/1.50 Kodi"
+ -DUNICODE -D_UNICODE
+ -DFRIBIDI_STATIC
+ $<$<CONFIG:Debug>:-DD3D_DEBUG_INFO>)
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_WIN32_NETWORK -DHAS_FILESYSTEM_SMB)
+
+# The /MP option enables /FS by default.
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+ else()
+ set(MP_FLAG "/MP")
+ endif()
+
+ set(CMAKE_CXX_FLAGS "/permissive- ${MP_FLAG} ${CMAKE_CXX_FLAGS}")
+endif()
+
+# Google Test needs to use shared version of runtime libraries
+set(gtest_force_shared_crt ON CACHE STRING "" FORCE)
+
+
+# -------- Linker options ---------
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
+
+# For #pragma comment(lib X)
+# TODO: It would certainly be better to handle these libraries via CMake modules.
+link_directories(${DEPENDS_PATH}/lib)
+
+# Additional libraries
+list(APPEND DEPLIBS bcrypt.lib d3d11.lib DInput8.lib DSound.lib winmm.lib Mpr.lib Iphlpapi.lib WS2_32.lib
+ PowrProf.lib setupapi.lib Shlwapi.lib dwmapi.lib dxguid.lib DelayImp.lib version.lib
+ crypt32.lib)
+
+# NODEFAULTLIB option
+set(_nodefaultlibs_RELEASE libcmt)
+set(_nodefaultlibs_DEBUG libcmt msvcrt)
+foreach(_lib ${_nodefaultlibs_RELEASE})
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:\"${_lib}\"")
+endforeach()
+foreach(_lib ${_nodefaultlibs_DEBUG})
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:\"${_lib}\"")
+endforeach()
+
+# DELAYLOAD option
+set(_delayloadlibs zlib.dll libmariadb.dll libxslt.dll dnssd.dll dwmapi.dll sqlite3.dll
+ d3dcompiler_47.dll)
+foreach(_lib ${_delayloadlibs})
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DELAYLOAD:\"${_lib}\"")
+endforeach()
+
+# Make the Release version create a PDB
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
+# Minimize the size or the resulting DLLs
+set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF")
+
+
+# -------- Visual Studio options ---------
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+ # Generate a batch file that opens Visual Studio with the necessary env variables set.
+ file(WRITE ${CMAKE_BINARY_DIR}/kodi-sln.bat
+ "@echo off\n"
+ "set KODI_HOME=%~dp0\n"
+ "set PATH=%~dp0\\system\n"
+ "set PreferredToolArchitecture=x64\n"
+ "start %~dp0\\${PROJECT_NAME}.sln")
+endif()
diff --git a/cmake/scripts/windows/CFlagOverrides.cmake b/cmake/scripts/windows/CFlagOverrides.cmake
new file mode 100644
index 0000000..cd96689
--- /dev/null
+++ b/cmake/scripts/windows/CFlagOverrides.cmake
@@ -0,0 +1,10 @@
+if(MSVC)
+ if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+ else()
+ set(MP_FLAG "/MP")
+ endif()
+ set(CMAKE_C_FLAGS "/D_UNICODE /DUNICODE /DRPC_USE_NATIVE_WCHAR ${MP_FLAG} /DWIN32 /D_WINDOWS /W3 /Zi /arch:SSE2")
+ set(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /MDd /Ob0 /Od /RTC1 /D_ITERATOR_DEBUG_LEVEL=0")
+ set(CMAKE_C_FLAGS_RELEASE "/MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG")
+endif()
diff --git a/cmake/scripts/windows/CXXFlagOverrides.cmake b/cmake/scripts/windows/CXXFlagOverrides.cmake
new file mode 100644
index 0000000..72df9de
--- /dev/null
+++ b/cmake/scripts/windows/CXXFlagOverrides.cmake
@@ -0,0 +1,10 @@
+if(MSVC)
+ if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+ else()
+ set(MP_FLAG "/MP")
+ endif()
+ set(CMAKE_CXX_FLAGS "/D_UNICODE /DUNICODE /DRPC_USE_NATIVE_WCHAR ${MP_FLAG} /DWIN32 /D_WINDOWS /W3 /GR /Zi /EHsc /arch:SSE2")
+ set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob0 /Od /RTC1 /D_ITERATOR_DEBUG_LEVEL=0")
+ set(CMAKE_CXX_FLAGS_RELEASE "/MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG")
+endif()
diff --git a/cmake/scripts/windows/Install.cmake b/cmake/scripts/windows/Install.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmake/scripts/windows/Install.cmake
diff --git a/cmake/scripts/windows/Macros.cmake b/cmake/scripts/windows/Macros.cmake
new file mode 100644
index 0000000..2d3500d
--- /dev/null
+++ b/cmake/scripts/windows/Macros.cmake
@@ -0,0 +1,66 @@
+function(core_link_library lib wraplib)
+ message(AUTHOR_WARNING "core_link_library is not compatible with windows.")
+endfunction()
+
+function(find_soname lib)
+ # Windows uses hardcoded dlls in xbmc/DllPaths_win32.h.
+ # Therefore the output of this function is unused.
+endfunction()
+
+# Add precompiled header to target
+# Arguments:
+# target existing target that will be set up to compile with a precompiled header
+# pch_header the precompiled header file
+# pch_source the precompiled header source file
+# Optional Arguments:
+# PCH_TARGET build precompiled header as separate target with the given name
+# so that the same precompiled header can be used for multiple libraries
+# EXCLUDE_SOURCES if not all target sources shall use the precompiled header,
+# the relevant files can be listed here
+# On return:
+# Compiles the pch_source into a precompiled header and adds the header to
+# the given target
+function(add_precompiled_header target pch_header pch_source)
+ cmake_parse_arguments(PCH "" "PCH_TARGET" "EXCLUDE_SOURCES" ${ARGN})
+
+ if(PCH_PCH_TARGET)
+ set(pch_binary ${PRECOMPILEDHEADER_DIR}/${PCH_PCH_TARGET}.pch)
+ else()
+ set(pch_binary ${PRECOMPILEDHEADER_DIR}/${target}.pch)
+ endif()
+
+ # Set compile options and dependency for sources
+ get_target_property(sources ${target} SOURCES)
+ list(REMOVE_ITEM sources ${pch_source})
+ foreach(exclude_source IN LISTS PCH_EXCLUDE_SOURCES)
+ list(REMOVE_ITEM sources ${exclude_source})
+ endforeach()
+ set_source_files_properties(${sources}
+ PROPERTIES COMPILE_FLAGS "/Yu\"${pch_header}\" /Fp\"${pch_binary}\" /FI\"${pch_header}\""
+ OBJECT_DEPENDS "${pch_binary}")
+
+ # Set compile options for precompiled header
+ if(NOT PCH_PCH_TARGET OR NOT TARGET ${PCH_PCH_TARGET}_pch)
+ set_source_files_properties(${pch_source}
+ PROPERTIES COMPILE_FLAGS "/Yc\"${pch_header}\" /Fp\"${pch_binary}\""
+ OBJECT_OUTPUTS "${pch_binary}")
+ endif()
+
+ # Compile precompiled header
+ if(PCH_PCH_TARGET)
+ # As own target for usage in multiple libraries
+ if(NOT TARGET ${PCH_PCH_TARGET}_pch)
+ add_library(${PCH_PCH_TARGET}_pch STATIC ${pch_source})
+ set_target_properties(${PCH_PCH_TARGET}_pch PROPERTIES COMPILE_PDB_NAME vc140
+ COMPILE_PDB_OUTPUT_DIRECTORY ${PRECOMPILEDHEADER_DIR}
+ FOLDER "Build Utilities")
+ endif()
+ # From VS2012 onwards, precompiled headers have to be linked against (LNK2011).
+ target_link_libraries(${target} PUBLIC ${PCH_PCH_TARGET}_pch)
+ set_target_properties(${target} PROPERTIES COMPILE_PDB_NAME vc140
+ COMPILE_PDB_OUTPUT_DIRECTORY ${PRECOMPILEDHEADER_DIR})
+ else()
+ # As part of the target
+ target_sources(${target} PRIVATE ${pch_source})
+ endif()
+endfunction()
diff --git a/cmake/scripts/windows/PathSetup.cmake b/cmake/scripts/windows/PathSetup.cmake
new file mode 100644
index 0000000..f6defde
--- /dev/null
+++ b/cmake/scripts/windows/PathSetup.cmake
@@ -0,0 +1,34 @@
+if(NOT prefix)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+else()
+ set(CMAKE_INSTALL_PREFIX ${prefix})
+endif()
+if(NOT exec_prefix)
+ set(exec_prefix ${prefix})
+endif()
+if(NOT libdir)
+ set(libdir ${prefix}/lib)
+endif()
+if(NOT bindir)
+ set(bindir ${prefix}/bin)
+endif()
+if(NOT includedir)
+ set(includedir ${prefix}/include)
+endif()
+if(NOT datarootdir)
+ set(datarootdir ${prefix}/share)
+endif()
+if(NOT datadir)
+ set(datadir ${datarootdir})
+endif()
+
+list(APPEND final_message "-- PATH config --")
+list(APPEND final_message "Prefix: ${prefix}")
+list(APPEND final_message "Libdir: ${libdir}")
+list(APPEND final_message "Bindir: ${bindir}")
+list(APPEND final_message "Includedir: ${includedir}")
+list(APPEND final_message "Datarootdir: ${datarootdir}")
+list(APPEND final_message "Datadir: ${datadir}")
+
+set(PATH_DEFINES -DBIN_INSTALL_PATH=\"${libdir}/${APP_NAME_LC}\"
+ -DINSTALL_PATH=\"${datarootdir}/${APP_NAME_LC}\")
diff --git a/cmake/scripts/windows/tools/patch.cmake b/cmake/scripts/windows/tools/patch.cmake
new file mode 100644
index 0000000..451fc66
--- /dev/null
+++ b/cmake/scripts/windows/tools/patch.cmake
@@ -0,0 +1,50 @@
+# prioritize Git patch.exe
+find_package(Git)
+if(Git_FOUND)
+ get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY)
+ get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY)
+endif()
+
+find_program(PATCH_FOUND NAMES patch.exe HINTS ${GIT_DIR} PATH_SUFFIXES usr/bin)
+
+if(PATCH_FOUND)
+ message(STATUS "patch utility found at ${PATCH_FOUND}")
+else()
+ set(PATCH_ARCHIVE_NAME "patch-2.7.6-bin")
+ set(PATCH_ARCHIVE "${PATCH_ARCHIVE_NAME}.zip")
+ set(PATCH_URL "${KODI_MIRROR}/build-deps/win32/${PATCH_ARCHIVE}")
+ set(PATCH_DOWNLOAD ${BUILD_DIR}/download/${PATCH_ARCHIVE})
+
+ # download the archive containing patch.exe
+ message(STATUS "Downloading patch utility from ${PATCH_URL}...")
+ file(DOWNLOAD "${PATCH_URL}" "${PATCH_DOWNLOAD}" STATUS PATCH_DL_STATUS LOG PATCH_LOG SHOW_PROGRESS)
+ list(GET PATCH_DL_STATUS 0 PATCH_RETCODE)
+ if(NOT PATCH_RETCODE EQUAL 0)
+ message(FATAL_ERROR "ERROR downloading ${PATCH_URL} - status: ${PATCH_DL_STATUS} log: ${PATCH_LOG}")
+ endif()
+
+ # extract the archive containing patch.exe
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzvf ${PATCH_DOWNLOAD}
+ WORKING_DIRECTORY ${BUILD_DIR})
+
+ # make sure the extraction worked and that patch.exe is there
+ set(PATCH_PATH ${BUILD_DIR}/${PATCH_ARCHIVE_NAME})
+ set(PATCH_BINARY_PATH ${PATCH_PATH}/bin/patch.exe)
+ if(NOT EXISTS ${PATCH_PATH} OR NOT EXISTS ${PATCH_BINARY_PATH})
+ message(FATAL_ERROR "ERROR extracting patch utility from ${PATCH_PATH}")
+ endif()
+
+ # copy patch.exe into the output directory
+ file(INSTALL ${PATCH_BINARY_PATH} DESTINATION ${ADDON_DEPENDS_PATH}/bin)
+ # copy patch depends
+ file(GLOB PATCH_BINARIES ${PATCH_PATH}/bin/*.dll)
+ if(NOT "${PATCH_BINARIES}" STREQUAL "")
+ file(INSTALL ${PATCH_BINARIES} DESTINATION ${ADDON_DEPENDS_PATH}/bin)
+ endif()
+
+ # make sure that cmake can find the copied patch.exe
+ find_program(PATCH_FOUND NAMES patch patch.exe)
+ if(NOT PATCH_FOUND)
+ message(FATAL_ERROR "ERROR installing patch utility from ${PATCH_BINARY_PATH} to ${ADDON_DEPENDS_PATH}/bin")
+ endif()
+endif()
diff --git a/cmake/scripts/windowsstore/ArchSetup.cmake b/cmake/scripts/windowsstore/ArchSetup.cmake
new file mode 100644
index 0000000..f71ca7a
--- /dev/null
+++ b/cmake/scripts/windowsstore/ArchSetup.cmake
@@ -0,0 +1,127 @@
+# Minimum SDK version we support
+set(VS_MINIMUM_SDK_VERSION 10.0.17763.0)
+
+if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS VS_MINIMUM_SDK_VERSION)
+ message(FATAL_ERROR "Detected Windows SDK version is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}.\n"
+ "Windows SDK ${VS_MINIMUM_SDK_VERSION} or higher is required.\n"
+ "INFO: Windows SDKs can be installed from the Visual Studio installer.")
+endif()
+
+# -------- Host Settings ---------
+
+set(_gentoolset ${CMAKE_GENERATOR_TOOLSET})
+string(REPLACE "host=" "" HOSTTOOLSET ${_gentoolset})
+unset(_gentoolset)
+
+# -------- Architecture settings ---------
+
+check_symbol_exists(_X86_ "Windows.h" _X86_)
+check_symbol_exists(_AMD64_ "Windows.h" _AMD64_)
+check_symbol_exists(_ARM_ "Windows.h" _ARM_)
+
+if(_X86_)
+ set(ARCH win32)
+ set(SDK_TARGET_ARCH x86)
+elseif(_AMD64_)
+ set(ARCH x64)
+ set(SDK_TARGET_ARCH x64)
+elseif(_ARM_)
+ set(ARCH arm)
+ set(SDK_TARGET_ARCH arm)
+else()
+ message(FATAL_ERROR "Unsupported architecture")
+endif()
+
+unset(_X86_)
+unset(_AMD64_)
+unset(_ARM_)
+
+# -------- Paths (mainly for find_package) ---------
+
+set(PLATFORM_DIR platform/win32)
+set(APP_RENDER_SYSTEM dx11)
+set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/win10/main.cpp)
+
+# Precompiled headers fail with per target output directory. (needs CMake 3.1)
+set(PRECOMPILEDHEADER_DIR ${PROJECT_BINARY_DIR}/${CORE_BUILD_CONFIG}/objs)
+
+set(CMAKE_SYSTEM_NAME WindowsStore)
+set(CORE_SYSTEM_NAME "windowsstore")
+set(PACKAGE_GUID "281d668b-5739-4abd-b3c2-ed1cda572ed2")
+set(APP_MANIFEST_NAME package.appxmanifest)
+set(DEPS_FOLDER_RELATIVE project/BuildDependencies)
+
+set(NATIVEPREFIX ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/tools)
+set(DEPENDS_PATH ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/win10-${ARCH})
+set(MINGW_LIBS_DIR ${CMAKE_SOURCE_DIR}/${DEPS_FOLDER_RELATIVE}/mingwlibs/win10-${ARCH})
+
+# mingw libs
+list(APPEND CMAKE_PREFIX_PATH ${MINGW_LIBS_DIR})
+list(APPEND CMAKE_LIBRARY_PATH ${MINGW_LIBS_DIR}/bin)
+
+if(NOT TARBALL_DIR)
+ set(TARBALL_DIR "${CMAKE_SOURCE_DIR}/project/BuildDependencies/downloads")
+endif()
+
+# -------- Compiler options ---------
+
+add_options(CXX ALL_BUILDS "/wd\"4996\"")
+add_options(CXX ALL_BUILDS "/wd\"4146\"")
+add_options(CXX ALL_BUILDS "/wd\"4251\"")
+add_options(CXX ALL_BUILDS "/wd\"4668\"")
+add_options(CXX ALL_BUILDS "/wd\"5033\"")
+set(ARCH_DEFINES -D_WINDOWS -DTARGET_WINDOWS -DTARGET_WINDOWS_STORE -DXBMC_EXPORT -DMS_UWP -DMS_STORE)
+if(NOT SDK_TARGET_ARCH STREQUAL arm)
+ list(APPEND ARCH_DEFINES -D__SSE__ -D__SSE2__)
+endif()
+set(SYSTEM_DEFINES -DWIN32_LEAN_AND_MEAN -DNOMINMAX -DHAS_DX -D__STDC_CONSTANT_MACROS
+ -DTAGLIB_STATIC -DNPT_CONFIG_ENABLE_LOGGING
+ -DPLT_HTTP_DEFAULT_USER_AGENT="UPnP/1.0 DLNADOC/1.50 Kodi"
+ -DPLT_HTTP_DEFAULT_SERVER="UPnP/1.0 DLNADOC/1.50 Kodi"
+ -DUNICODE -D_UNICODE
+ -DFRIBIDI_STATIC
+ $<$<CONFIG:Debug>:-DD3D_DEBUG_INFO>)
+
+# Additional SYSTEM_DEFINES
+list(APPEND SYSTEM_DEFINES -DHAS_WIN10_NETWORK)
+
+# The /MP option enables /FS by default.
+if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+else()
+ set(MP_FLAG "/MP")
+endif()
+set(CMAKE_CXX_FLAGS "${MP_FLAG} ${CMAKE_CXX_FLAGS} /EHsc /await /permissive-")
+# Google Test needs to use shared version of runtime libraries
+set(gtest_force_shared_crt ON CACHE STRING "" FORCE)
+
+
+# -------- Linker options ---------
+
+# For #pragma comment(lib X)
+# TODO: It would certainly be better to handle these libraries via CMake modules.
+link_directories(${MINGW_LIBS_DIR}/lib
+ ${DEPENDS_PATH}/lib)
+
+list(APPEND DEPLIBS bcrypt.lib d3d11.lib WS2_32.lib dxguid.lib dloadhelper.lib WindowsApp.lib)
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /WINMD:NO")
+set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:msvcrt /DEBUG:FASTLINK /OPT:NOREF /OPT:NOICF")
+
+# Make the Release version create a PDB
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
+# Minimize the size or the resulting DLLs
+set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF")
+# remove warning
+set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4264")
+
+
+# -------- Visual Studio options ---------
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+endif()
+
+# -------- Build options ---------
+
+set(ENABLE_OPTICAL OFF CACHE BOOL "" FORCE)
diff --git a/cmake/scripts/windowsstore/CFlagOverrides.cmake b/cmake/scripts/windowsstore/CFlagOverrides.cmake
new file mode 100644
index 0000000..ab2f59c
--- /dev/null
+++ b/cmake/scripts/windowsstore/CFlagOverrides.cmake
@@ -0,0 +1,17 @@
+# compiler flags
+if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+else()
+ set(MP_FLAG "/MP")
+endif()
+string(APPEND CMAKE_C_FLAGS_INIT " /D_UNICODE /DUNICODE ${MP_FLAG} /DWIN32 /D_WINDOWS /W3 /Zi /DTARGET_WINDOWS")
+string(APPEND CMAKE_C_FLAGS_INIT " /DWINAPI_FAMILY=2 /DTARGET_WINDOWS_STORE /D_WINSOCK_DEPRECATED_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE")
+string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " /D_DEBUG /MDd /Ob0 /Od /RTC1 /D_ITERATOR_DEBUG_LEVEL=0")
+string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " /MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG")
+# linker flags
+string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " /DYNAMICBASE /NXCOMPAT /APPCONTAINER")
+# win32 specific flags
+if("$ENV{Platform}" STREQUAL X86)
+ string(APPEND CMAKE_C_FLAGS_INIT " /arch:SSE2")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " /SAFESEH")
+endif()
diff --git a/cmake/scripts/windowsstore/CXXFlagOverrides.cmake b/cmake/scripts/windowsstore/CXXFlagOverrides.cmake
new file mode 100644
index 0000000..4ae3ac3
--- /dev/null
+++ b/cmake/scripts/windowsstore/CXXFlagOverrides.cmake
@@ -0,0 +1,17 @@
+# compiler flags
+if(DEFINED ENV{MAXTHREADS})
+ set(MP_FLAG "/MP$ENV{MAXTHREADS}")
+else()
+ set(MP_FLAG "/MP")
+endif()
+string(APPEND CMAKE_CXX_FLAGS_INIT " /D_UNICODE /DUNICODE ${MP_FLAG} /DWIN32 /D_WINDOWS /W3 /GR /Zi /EHsc /DTARGET_WINDOWS")
+string(APPEND CMAKE_CXX_FLAGS_INIT " /DWINAPI_FAMILY=2 /DTARGET_WINDOWS_STORE /D_WINSOCK_DEPRECATED_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE")
+string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " /D_DEBUG /MDd /Ob0 /Od /RTC1 /D_ITERATOR_DEBUG_LEVEL=0")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " /MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG")
+# linker flags
+string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " /DYNAMICBASE /NXCOMPAT /APPCONTAINER")
+# win32 specific flags
+if("$ENV{Platform}" STREQUAL X86)
+ string(APPEND CMAKE_CXX_FLAGS_INIT " /arch:SSE2")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " /SAFESEH")
+endif()
diff --git a/cmake/scripts/windowsstore/Install.cmake b/cmake/scripts/windowsstore/Install.cmake
new file mode 100644
index 0000000..a0522d3
--- /dev/null
+++ b/cmake/scripts/windowsstore/Install.cmake
@@ -0,0 +1,10 @@
+# Fix UWP addons security issue caused by empty __init__.py Python Lib files packaged with Kodi
+set(uwp_pythonlibinit_filepattern "${DEPENDS_PATH}/bin/Python/Lib/__init__.py")
+file(GLOB_RECURSE uwp_pythonlibinit_foundfiles "${uwp_pythonlibinit_filepattern}")
+foreach(uwp_pythonlibinit_file ${uwp_pythonlibinit_foundfiles})
+ file(SIZE "${uwp_pythonlibinit_file}" uwp_pythonlibinit_filesize)
+ if(${uwp_pythonlibinit_filesize} EQUAL 0)
+ message("Adding hash comment character in the following empty file: ${uwp_pythonlibinit_file}")
+ file(APPEND ${uwp_pythonlibinit_file} "#")
+ endif()
+endforeach()
diff --git a/cmake/scripts/windowsstore/Macros.cmake b/cmake/scripts/windowsstore/Macros.cmake
new file mode 100644
index 0000000..713e878
--- /dev/null
+++ b/cmake/scripts/windowsstore/Macros.cmake
@@ -0,0 +1,182 @@
+function(core_link_library lib wraplib)
+ message(AUTHOR_WARNING "core_link_library is not compatible with windows.")
+endfunction()
+
+function(find_soname lib)
+ # Windows uses hardcoded dlls in xbmc/DllPaths_win32.h.
+ # Therefore the output of this function is unused.
+endfunction()
+
+# Add precompiled header to target
+# Arguments:
+# target existing target that will be set up to compile with a precompiled header
+# pch_header the precompiled header file
+# pch_source the precompiled header source file
+# Optional Arguments:
+# PCH_TARGET build precompiled header as separate target with the given name
+# so that the same precompiled header can be used for multiple libraries
+# EXCLUDE_SOURCES if not all target sources shall use the precompiled header,
+# the relevant files can be listed here
+# On return:
+# Compiles the pch_source into a precompiled header and adds the header to
+# the given target
+function(add_precompiled_header target pch_header pch_source)
+ cmake_parse_arguments(PCH "" "PCH_TARGET" "EXCLUDE_SOURCES" ${ARGN})
+
+ if(PCH_PCH_TARGET)
+ set(pch_binary ${PRECOMPILEDHEADER_DIR}/${PCH_PCH_TARGET}.pch)
+ else()
+ set(pch_binary ${PRECOMPILEDHEADER_DIR}/${target}.pch)
+ endif()
+
+ # Set compile options and dependency for sources
+ get_target_property(sources ${target} SOURCES)
+ list(REMOVE_ITEM sources ${pch_source})
+ foreach(exclude_source IN LISTS PCH_EXCLUDE_SOURCES)
+ list(REMOVE_ITEM sources ${exclude_source})
+ endforeach()
+ set_source_files_properties(${sources}
+ PROPERTIES COMPILE_FLAGS "/Yu\"${pch_header}\" /Fp\"${pch_binary}\" /FI\"${pch_header}\""
+ OBJECT_DEPENDS "${pch_binary}")
+
+ # Set compile options for precompiled header
+ if(NOT PCH_PCH_TARGET OR NOT TARGET ${PCH_PCH_TARGET}_pch)
+ set_source_files_properties(${pch_source}
+ PROPERTIES COMPILE_FLAGS "/Yc\"${pch_header}\" /Fp\"${pch_binary}\""
+ OBJECT_OUTPUTS "${pch_binary}")
+ endif()
+
+ # Compile precompiled header
+ if(PCH_PCH_TARGET)
+ # As own target for usage in multiple libraries
+ if(NOT TARGET ${PCH_PCH_TARGET}_pch)
+ add_library(${PCH_PCH_TARGET}_pch STATIC ${pch_source})
+ set_target_properties(${PCH_PCH_TARGET}_pch PROPERTIES COMPILE_PDB_NAME vc140
+ COMPILE_PDB_OUTPUT_DIRECTORY ${PRECOMPILEDHEADER_DIR}
+ FOLDER "Build Utilities")
+ endif()
+ # From VS2012 onwards, precompiled headers have to be linked against (LNK2011).
+ target_link_libraries(${target} PUBLIC ${PCH_PCH_TARGET}_pch)
+ set_target_properties(${target} PROPERTIES COMPILE_PDB_NAME vc140
+ COMPILE_PDB_OUTPUT_DIRECTORY ${PRECOMPILEDHEADER_DIR})
+ else()
+ # As part of the target
+ target_sources(${target} PRIVATE ${pch_source})
+ endif()
+endfunction()
+
+macro(winstore_set_assets target)
+ file(GLOB ASSET_FILES "${CMAKE_SOURCE_DIR}/tools/windows/packaging/uwp/media/*.png")
+ set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+ set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "media")
+ source_group("media" FILES ${ASSET_FILES})
+ set(RESOURCES ${RESOURCES} ${ASSET_FILES}
+ "${CMAKE_SOURCE_DIR}/tools/windows/packaging/uwp/kodi_temp_key.pfx")
+
+ set(LICENSE_FILES
+ ${CMAKE_SOURCE_DIR}/LICENSE.md
+ ${CMAKE_SOURCE_DIR}/privacy-policy.txt)
+ if(EXISTS "${CMAKE_SOURCE_DIR}/known_issues.txt")
+ list(APPEND LICENSE_FILES ${CMAKE_SOURCE_DIR}/known_issues.txt)
+ endif()
+ set_property(SOURCE ${LICENSE_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+ list(APPEND RESOURCES ${LICENSE_FILES})
+endmacro()
+
+macro(winstore_generate_manifest target)
+ configure_file(
+ ${CMAKE_SOURCE_DIR}/tools/windows/packaging/uwp/${APP_MANIFEST_NAME}.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME}
+ @ONLY)
+ set(RESOURCES ${RESOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME})
+endmacro()
+
+macro(add_deployment_content_group path link match exclude)
+ set(_link "")
+ set(_exclude "")
+ file(TO_NATIVE_PATH ${path} _path)
+ file(TO_NATIVE_PATH ${match} _match)
+ if (NOT "${link}" STREQUAL "")
+ file(TO_NATIVE_PATH ${link} _link)
+ set(_link "${_link}\\")
+ endif()
+ if(NOT "${exclude}" STREQUAL "")
+ string(REPLACE "/" "\\" _exclude ${exclude})
+ endif()
+ string(CONCAT UWP_DEPLOYMENT_CONTENT_STR "${UWP_DEPLOYMENT_CONTENT_STR}"
+ " <EmbedResources Include=\"${_path}\\${_match}\" Exclude=\"${_exclude}\">\n"
+ " <Link>${_link}%(RecursiveDir)%(FileName)%(Extension)</Link>\n"
+ " <DeploymentContent>true</DeploymentContent>\n"
+ " </EmbedResources>\n")
+endmacro()
+
+macro(winstore_append_props target)
+ # exclude debug dlls from packaging
+ set(DEBUG_DLLS zlibd.dll)
+ foreach(_dll ${DEBUG_DLLS})
+ if (DEBUG_DLLS_EXCLUDE)
+ list(APPEND DEBUG_DLLS_EXCLUDE "\;$(BuildRootPath)/dlls/${_dll}")
+ else()
+ list(APPEND DEBUG_DLLS_EXCLUDE "$(BuildRootPath)/dlls/${_dll}")
+ endif()
+ string(CONCAT DEBUG_DLLS_LINKAGE_PROPS "${DEBUG_DLLS_LINKAGE_PROPS}"
+ " <ItemGroup Label=\"Binaries\">\n"
+ " <None Include=\"$(BinPath)\\${_dll}\" Condition=\"'$(Configuration)'=='Debug'\">\n"
+ " <DeploymentContent>true</DeploymentContent>\n"
+ " </None>\n"
+ " </ItemGroup>\n")
+ endforeach(_dll DEBUG_DLLS)
+
+ add_deployment_content_group($(BuildRootPath)/dlls "" *.dll "${DEBUG_DLLS_EXCLUDE}")
+ add_deployment_content_group($(BuildRootPath)/system system **/* "$(BuildRootPath)/**/shaders/**")
+ add_deployment_content_group($(BuildRootPath)/system/shaders system/shaders **/*.fx "")
+ add_deployment_content_group($(BuildRootPath)/media media **/* "")
+ add_deployment_content_group($(BuildRootPath)/userdata userdata **/* "")
+ add_deployment_content_group($(BuildRootPath)/addons addons **/* "")
+ add_deployment_content_group($(BinaryAddonsPath) addons **/* "")
+
+ foreach(xbt_file ${XBT_FILES})
+ file(RELATIVE_PATH relative ${CMAKE_CURRENT_BINARY_DIR} ${xbt_file})
+ file(TO_NATIVE_PATH ${relative} relative)
+ string(CONCAT XBT_FILE_PROPS "${XBT_FILE_PROPS}"
+ " <ItemGroup Label=\"SkinsMedia\">\n"
+ " <None Include=\"$(BuildRootPath)\\${relative}\">\n"
+ " <Link>${relative}</Link>\n"
+ " <DeploymentContent>true</DeploymentContent>\n"
+ " </None>\n"
+ " </ItemGroup>\n")
+ endforeach()
+
+ set(VCPROJECT_PROPS_FILE "${CMAKE_CURRENT_BINARY_DIR}/${target}.props")
+ file(TO_NATIVE_PATH ${DEPENDS_PATH} DEPENDENCIES_DIR_NATIVE)
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} CMAKE_CURRENT_BINARY_DIR_NATIVE)
+ file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR}/project/Win32BuildSetup/BUILD_WIN32/addons BINARY_ADDONS_DIR_NATIVE)
+
+ file(WRITE ${VCPROJECT_PROPS_FILE}
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
+ " <ImportGroup Label=\"PropertySheets\" />\n"
+ " <PropertyGroup Label=\"APP_DLLS\">\n"
+ " <BinPath>${DEPENDENCIES_DIR_NATIVE}\\bin</BinPath>\n"
+ " <BuildRootPath>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</BuildRootPath>\n"
+ " <BinaryAddonsPath>${BINARY_ADDONS_DIR_NATIVE}</BinaryAddonsPath>\n"
+ " </PropertyGroup>\n"
+ "${DEBUG_DLLS_LINKAGE_PROPS}"
+ "${XBT_FILE_PROPS}"
+ " <ItemGroup>\n"
+ "${UWP_DEPLOYMENT_CONTENT_STR}"
+ " </ItemGroup>\n"
+ " <Target Name=\"_CollectCustomResources\" Inputs=\"@(EmbedResources)\" Outputs=\"@(EmbedResources->'$(OutputPath)\\PackageLayout\\%(Link)')\" BeforeTargets=\"AssignTargetPaths\">\n"
+ " <Message Text=\"Collecting package resources...\"/>\n"
+ " <ItemGroup>\n"
+ " <None Include=\"@(EmbedResources)\" />\n"
+ " </ItemGroup>\n"
+ " </Target>\n"
+ "</Project>")
+endmacro()
+
+macro(winstore_add_target_properties target)
+ winstore_set_assets(${target})
+ winstore_generate_manifest(${target})
+ winstore_append_props(${target})
+endmacro()
diff --git a/cmake/scripts/windowsstore/PathSetup.cmake b/cmake/scripts/windowsstore/PathSetup.cmake
new file mode 100644
index 0000000..8550616
--- /dev/null
+++ b/cmake/scripts/windowsstore/PathSetup.cmake
@@ -0,0 +1,34 @@
+if(NOT prefix)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+else()
+ set(CMAKE_INSTALL_PREFIX ${prefix})
+endif()
+if(NOT exec_prefix)
+ set(exec_prefix ${prefix})
+endif()
+if(NOT libdir)
+ set(libdir ${prefix}/lib)
+endif()
+if(NOT bindir)
+ set(bindir ${prefix}/bin)
+endif()
+if(NOT includedir)
+ set(includedir ${prefix}/include)
+endif()
+if(NOT datarootdir)
+ set(datarootdir ${prefix}/share)
+endif()
+if(NOT datadir)
+ set(datadir ${datarootdir})
+endif()
+
+list(APPEND final_message "-- PATH config --")
+list(APPEND final_message "Prefix: ${prefix}")
+list(APPEND final_message "Libdir: ${libdir}")
+list(APPEND final_message "Bindir: ${bindir}")
+list(APPEND final_message "Includedir: ${includedir}")
+list(APPEND final_message "Datarootdir: ${datarootdir}")
+list(APPEND final_message "Datadir: ${datadir}")
+
+set(PATH_DEFINES -DBIN_INSTALL_PATH=\"${libdir}/kodi\"
+ -DINSTALL_PATH=\"${datarootdir}/kodi\")
diff --git a/cmake/scripts/windowsstore/tools/patch.cmake b/cmake/scripts/windowsstore/tools/patch.cmake
new file mode 100644
index 0000000..451fc66
--- /dev/null
+++ b/cmake/scripts/windowsstore/tools/patch.cmake
@@ -0,0 +1,50 @@
+# prioritize Git patch.exe
+find_package(Git)
+if(Git_FOUND)
+ get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY)
+ get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY)
+endif()
+
+find_program(PATCH_FOUND NAMES patch.exe HINTS ${GIT_DIR} PATH_SUFFIXES usr/bin)
+
+if(PATCH_FOUND)
+ message(STATUS "patch utility found at ${PATCH_FOUND}")
+else()
+ set(PATCH_ARCHIVE_NAME "patch-2.7.6-bin")
+ set(PATCH_ARCHIVE "${PATCH_ARCHIVE_NAME}.zip")
+ set(PATCH_URL "${KODI_MIRROR}/build-deps/win32/${PATCH_ARCHIVE}")
+ set(PATCH_DOWNLOAD ${BUILD_DIR}/download/${PATCH_ARCHIVE})
+
+ # download the archive containing patch.exe
+ message(STATUS "Downloading patch utility from ${PATCH_URL}...")
+ file(DOWNLOAD "${PATCH_URL}" "${PATCH_DOWNLOAD}" STATUS PATCH_DL_STATUS LOG PATCH_LOG SHOW_PROGRESS)
+ list(GET PATCH_DL_STATUS 0 PATCH_RETCODE)
+ if(NOT PATCH_RETCODE EQUAL 0)
+ message(FATAL_ERROR "ERROR downloading ${PATCH_URL} - status: ${PATCH_DL_STATUS} log: ${PATCH_LOG}")
+ endif()
+
+ # extract the archive containing patch.exe
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzvf ${PATCH_DOWNLOAD}
+ WORKING_DIRECTORY ${BUILD_DIR})
+
+ # make sure the extraction worked and that patch.exe is there
+ set(PATCH_PATH ${BUILD_DIR}/${PATCH_ARCHIVE_NAME})
+ set(PATCH_BINARY_PATH ${PATCH_PATH}/bin/patch.exe)
+ if(NOT EXISTS ${PATCH_PATH} OR NOT EXISTS ${PATCH_BINARY_PATH})
+ message(FATAL_ERROR "ERROR extracting patch utility from ${PATCH_PATH}")
+ endif()
+
+ # copy patch.exe into the output directory
+ file(INSTALL ${PATCH_BINARY_PATH} DESTINATION ${ADDON_DEPENDS_PATH}/bin)
+ # copy patch depends
+ file(GLOB PATCH_BINARIES ${PATCH_PATH}/bin/*.dll)
+ if(NOT "${PATCH_BINARIES}" STREQUAL "")
+ file(INSTALL ${PATCH_BINARIES} DESTINATION ${ADDON_DEPENDS_PATH}/bin)
+ endif()
+
+ # make sure that cmake can find the copied patch.exe
+ find_program(PATCH_FOUND NAMES patch patch.exe)
+ if(NOT PATCH_FOUND)
+ message(FATAL_ERROR "ERROR installing patch utility from ${PATCH_BINARY_PATH} to ${ADDON_DEPENDS_PATH}/bin")
+ endif()
+endif()