[video] Fix the refresh of movies with additional versions or extras
[xbmc.git] / CMakeLists.txt
blob6013c616391f64da1cebce833f9da878fb78c200
1 cmake_minimum_required(VERSION 3.12)
2 if(WIN32)
3   # Version 3.20 is required for multi-config generator expressions to work
4   cmake_minimum_required(VERSION 3.20)
5 endif()
6 project(kodi LANGUAGES CXX C ASM)
8 if(POLICY CMP0069)
9   set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
10   cmake_policy(SET CMP0069 NEW)
11 endif()
13 if(POLICY CMP0135)
14   set(CMAKE_POLICY_DEFAULT_CMP0135 NEW)
15   cmake_policy(SET CMP0135 NEW)
16 endif()
18 list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
19 list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules/buildtools)
20 if(DEPENDS_DIR)
21   list(APPEND CMAKE_PREFIX_PATH ${DEPENDS_DIR})
22 endif()
24 # Variable to indicate if the project is targeting a Multi Config Generator (VS/Xcode primarily)
25 get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
26 if(_multiconfig_generator)
27   # Target to encompass an optional way to build all internal dependencies
28   # Must set EXCLUDE_FROM_ALL property so the ALL target doesnt include this, and therefore
29   # build all internal dependencies
30   add_custom_target(build_internal_depends)
31   set_target_properties(build_internal_depends PROPERTIES EXCLUDE_FROM_ALL TRUE)
32 endif()
34 # Set CORE_BUILD_DIR
35 set(CORE_BUILD_DIR build)
36 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
38 # set KODI_MIRROR to the default if not already set
39 if(NOT DEFINED KODI_MIRROR)
40   set(KODI_MIRROR "http://mirrors.kodi.tv")
41 endif()
43 message(STATUS "Mirror download location: ${KODI_MIRROR}")
44 message(STATUS "Source directory: ${CMAKE_SOURCE_DIR}")
45 message(STATUS "Build directory: ${CMAKE_BINARY_DIR}")
46 if(CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)
47   message(WARNING "In-source build detected. It is recommended to build out-of-source.")
48 endif()
50 # Hide messages from Check*.cmake (e.g. CheckCSourceCompiles)
51 if(NOT VERBOSE)
52   set(CMAKE_REQUIRED_QUIET ON)
53 endif()
55 # Includes
56 include(cmake/modules/extra/ECMEnableSanitizers.cmake)
57 include(cmake/scripts/common/GeneratorSetup.cmake)
58 include(cmake/scripts/common/AddOptions.cmake)
59 include(cmake/scripts/common/Platform.cmake)
60 include(cmake/scripts/common/ArchSetup.cmake)
61 include(cmake/scripts/common/Macros.cmake)
62 include(cmake/scripts/common/ProjectMacros.cmake)
63 core_find_versions()
64 include(cmake/scripts/common/PathSetup.cmake)
65 include(cmake/scripts/common/CompilerSettings.cmake)
66 include(ExternalProject)
67 include(CMakeDependentOption)
68 include(cmake/scripts/common/DependencyOptions.cmake)
70 # general
71 option(VERBOSE            "Enable verbose output?" OFF)
72 option(ENABLE_CLANGTIDY   "Enable clang-tidy support?" OFF)
73 option(ENABLE_CPPCHECK    "Enable cppcheck support?" OFF)
74 option(ENABLE_DVDCSS      "Enable libdvdcss support?" ON)
75 option(ENABLE_INCLUDEWHATYOUUSE "Enable include-what-you-use support?" OFF)
76 option(ENABLE_UPNP        "Enable UPnP support?" ON)
77 option(ENABLE_AIRTUNES    "Enable AirTunes support?" ON)
78 option(ENABLE_OPTICAL     "Enable optical support?" ON)
79 option(ENABLE_PYTHON      "Enable python support?" ON)
80 option(ENABLE_TESTING     "Enable testing support?" ON)
82 # Internal Depends - supported on all platforms
84 # These are required enabled for all CI platforms, and recommended for all builds
85 option(ENABLE_INTERNAL_CROSSGUID "Enable internal crossguid?" ON)
87 # use ffmpeg from depends or system
88 option(ENABLE_INTERNAL_FFMPEG "Enable internal ffmpeg?" OFF)
90 # These are built for all platforms not using system libs or disabled by user
91 dependent_option(ENABLE_INTERNAL_CEC "Enable internal libcec?")
92 dependent_option(ENABLE_INTERNAL_FLATBUFFERS "Enable internal flatbuffers?")
93 dependent_option(ENABLE_INTERNAL_FMT "Enable internal fmt?")
94 dependent_option(ENABLE_INTERNAL_NFS "Enable internal libnfs?")
95 dependent_option(ENABLE_INTERNAL_PCRE "Enable internal pcre?")
96 dependent_option(ENABLE_INTERNAL_RapidJSON "Enable internal rapidjson?")
98 # If ENABLE_INTERNAL_FMT is ON, we force ENABLE_INTERNAL_SPDLOG ON as it has a hard
99 # dependency on fmt
100 if(ENABLE_INTERNAL_FMT)
101   option(ENABLE_INTERNAL_SPDLOG "Enable internal spdlog Forced" ON)
102 else()
103   dependent_option(ENABLE_INTERNAL_SPDLOG "Enable internal spdlog?")
104 endif()
106 dependent_option(ENABLE_INTERNAL_TAGLIB "Enable internal taglib?")
108 if(KODI_DEPENDSBUILD OR WIN32 OR WINDOWS_STORE)
109   dependent_option(ENABLE_INTERNAL_TINYXML2 "Enable internal TinyXML2?")
110 endif()
112 # Internal Depends - supported on UNIX platforms
113 if(UNIX)
114   option(FFMPEG_PATH        "Path to external ffmpeg?" "")
115   option(ENABLE_INTERNAL_FSTRCMP "Enable internal fstrcmp?" OFF)
116   option(ENABLE_INTERNAL_DAV1D "Enable internal dav1d?" OFF)
117   option(ENABLE_INTERNAL_GTEST "Enable internal gtest?" OFF)
118   option(ENABLE_INTERNAL_UDFREAD "Enable internal udfread?" OFF)
119 endif()
120 # prefer kissfft from xbmc/contrib but let use system one on unices
121 cmake_dependent_option(ENABLE_INTERNAL_KISSFFT "Enable internal kissfft?" ON "UNIX" ON)
122 # System options
123 if(NOT WIN32)
124   option(WITH_ARCH              "build with given arch" OFF)
125   option(WITH_CPU               "build with given cpu" OFF)
126 endif()
127 if(CORE_SYSTEM_NAME STREQUAL linux)
128   option(ENABLE_EVENTCLIENTS    "Enable event clients support?" OFF)
129   option(ADDONS_CONFIGURE_AT_STARTUP "Configure binary addons at startup?" ON)
130 endif()
132 # set scope of INTERNAL_DEPS
133 set_property(GLOBAL PROPERTY INTERNAL_DEPS_PROP)
135 # Build static libraries per directory
136 if(NOT CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_GENERATOR STREQUAL Xcode)
137   set(ENABLE_STATIC_LIBS TRUE)
138 else()
139   set(ENABLE_STATIC_LIBS FALSE)
140 endif()
142 core_find_git_rev(APP_SCMID FULL)
144 set(AUDIO_BACKENDS_LIST "" CACHE STRING "Available audio backends")
145 set(GL_INTERFACES_LIST "" CACHE STRING "Available GL interfaces")
147 # Dynamically loaded libraries built with the project
148 add_custom_target(${APP_NAME_LC}-libraries)
149 set(LIBRARY_FILES "" CACHE STRING "" FORCE)
150 mark_as_advanced(LIBRARY_FILES)
152 set(INCLUDES ${CMAKE_SOURCE_DIR}
153              ${CMAKE_SOURCE_DIR}/lib
154              ${CMAKE_SOURCE_DIR}/xbmc
155              ${CMAKE_SOURCE_DIR}/xbmc/${PLATFORM_DIR}
156              ${CMAKE_SOURCE_DIR}/xbmc/cores/VideoPlayer
157              ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
158              ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
160 if (NOT PLATFORMDEFS_DIR STREQUAL "")
161   list(APPEND INCLUDES ${CMAKE_SOURCE_DIR}/xbmc/${PLATFORMDEFS_DIR})
162 endif()
164 find_package(PkgConfig)
165 set(THREADS_PREFER_PTHREAD_FLAG ON)
166 find_package(Threads REQUIRED QUIET)
167 list(APPEND DEPLIBS ${CMAKE_THREAD_LIBS_INIT})
169 # Clean any existing generated build dir cmake files
170 file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/ExportFiles.cmake)
171 file(REMOVE ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/GeneratedPackSkins.cmake)
173 foreach(depspec ${PLATFORM_REQUIRED_DEPS})
174   # We need to specify ENABLE_${PLATFORM_REQUIRED_DEPS} in order for the
175   # optional subdirectory for the specified platform to get built.
176   split_dependency_specification(${depspec} dep version)
177   string(TOUPPER ${dep} depup)
178   if(NOT ${ENABLE_${depup}} STREQUAL AUTO AND NOT ${ENABLE_${depup}})
179     message(WARNING "Your request to disable the dependency ${dep} required on platform ${CORE_PLATFORM_NAME} was ignored. Please choose another platform or add \"-DENABLE_${depup}=ON\" to your CMake command line to resolve this warning.")
180   endif()
181   set(ENABLE_${depup} "ON" CACHE BOOL "Force enabling required ${depup} support" FORCE)
182 endforeach()
184 # Required tools. Keep in alphabetical order please
185 set(required_buildtools FlatC
186                         JsonSchemaBuilder
187                         TexturePacker
190 # Optional build tools
191 set(optional_buildtools CCache
192                         ClangFormat
193                         ClangTidy
194                         Cppcheck
195                         IncludeWhatYouUse)
197 # Find build tools - Optional and required
198 core_optional_dep(${optional_buildtools})
199 core_require_dep(${required_buildtools})
201 # Required dependencies. Keep in alphabetical order please
202 set(required_deps ASS>=0.15.0
203                   Cdio
204                   CrossGUID
205                   Curl
206                   FFMPEG
207                   FlatBuffers
208                   Fmt
209                   FreeType
210                   FriBidi
211                   Fstrcmp
212                   HarfBuzz
213                   Iconv
214                   KissFFT
215                   LibDvd
216                   Lzo2
217                   OpenSSL>=1.1.0
218                   PCRE
219                   RapidJSON>=1.0.2
220                   Spdlog
221                   Sqlite3
222                   TagLib>=1.9.0
223                   TinyXML
224                   TinyXML2
225                   ZLIB
226                   ${PLATFORM_REQUIRED_DEPS})
228 # Optional dependencies. Keep in alphabetical order please
229 set(optional_deps Alsa
230                   Avahi
231                   Bluetooth
232                   Bluray
233                   CAP
234                   CEC>=4.0.0
235                   Dav1d
236                   DBus
237                   Iso9660pp
238                   LCMS2
239                   LircClient
240                   MDNS
241                   MicroHttpd
242                   NFS
243                   Pipewire>=0.3.50
244                   Plist
245                   PulseAudio
246                   Python
247                   SmbClient
248                   Sndio
249                   UDEV
250                   Udfread
251                   XSLT
252                   ${PLATFORM_OPTIONAL_DEPS})
254 # Remove excluded platform specific optional_deps
255 foreach(excludedep ${PLATFORM_OPTIONAL_DEPS_EXCLUDE})
256   list(FILTER optional_deps EXCLUDE REGEX ${excludedep})
257 endforeach()
259 # Check optional deps first, since their availability can influence required ones, e.g. ffmpeg
260 core_optional_dep(${optional_deps})
261 core_require_dep(${required_deps})
263 if(ENABLE_MARIADBCLIENT AND NOT ENABLE_MARIADBCLIENT STREQUAL AUTO AND ENABLE_MYSQLCLIENT AND NOT ENABLE_MYSQLCLIENT STREQUAL AUTO)
264   MESSAGE(FATAL_ERROR "You can not use MySql and MariaDB at the same time. Disable one by adding -DENABLE_MYSQLCLIENT=OFF or -DENABLE_MARIADBCLIENT=OFF.")
265 elseif(ENABLE_MYSQLCLIENT AND NOT ENABLE_MYSQLCLIENT STREQUAL AUTO)
266   set(ENABLE_MARIADBCLIENT OFF CACHE BOOL "")
267 endif()
269 core_optional_dep(MariaDBClient)
270 if(NOT TARGET MariaDBClient::MariaDBClient)
271   core_optional_dep(MySqlClient)
272 endif()
274 if(NOT TARGET UDEV::UDEV)
275   core_optional_dep(LibUSB)
276 endif()
278 if(ENABLE_UPNP)
279   list(APPEND DEP_DEFINES "-DHAS_UPNP=1")
280 endif()
282 if(ENABLE_OPTICAL)
283   list(APPEND DEP_DEFINES -DHAS_OPTICAL_DRIVE -DHAS_CDDA_RIPPER)
284 endif()
286 if(ENABLE_AIRTUNES)
287   find_package(Shairplay)
288   if(TARGET Shairplay::Shairplay)
289     core_require_dep(Shairplay)
290   endif()
291 endif()
293 # find all folders containing addon.xml.in
294 # used to define ADDON_XML_OUTPUTS, ADDON_XML_DEPENDS and ADDON_INSTALL_DATA
295 # Function defined in ./cmake/scripts/common/Macros.cmake
296 set(outputFilterRegex "addons/xbmc.json")
297 find_addon_xml_in_files(${outputFilterRegex})
299 if(TARGET ALSA::ALSA AND TARGET PulseAudio::PulseAudio)
300   list(APPEND AUDIO_BACKENDS_LIST "alsa+pulseaudio")
301 endif()
303 # Compile Info
304 add_custom_command(OUTPUT ${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp
305                    COMMAND ${CMAKE_COMMAND} -DCORE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
306                                             -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
307                                             -DCORE_PLATFORM_NAME_LC="${CORE_PLATFORM_NAME_LC}"
308                                             -DAUDIO_BACKENDS="${AUDIO_BACKENDS_LIST}"
309                                             -DGL_INTERFACES="${GL_INTERFACES_LIST}"
310                                             -DCORE_BUILD_DIR=${CORE_BUILD_DIR}
311                                             -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}
312                                             -DARCH_DEFINES="${ARCH_DEFINES}"
313                                             -DAPP_SCMID=${APP_SCMID}
314                                             -DAPP_COPYRIGHT_YEARS=${APP_COPYRIGHT_YEARS}
315                                             -DAPP_BUILD_DATE=${APP_BUILD_DATE}
316                                             -DAPP_SHARED_LIBRARY_SUFFIX="${APP_SHARED_LIBRARY_SUFFIX}"
317                                             -DPYTHON_VERSION=${PYTHON_VERSION}
318                                             -Dprefix=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
319                                             -DKODI_WEBSERVER_EXTRA_WHITELIST="${KODI_WEBSERVER_EXTRA_WHITELIST}"
320                                             -P ${CMAKE_SOURCE_DIR}/cmake/scripts/common/GenerateCompileInfo.cmake
321                    DEPENDS ${CMAKE_SOURCE_DIR}/version.txt
322                            ${CMAKE_SOURCE_DIR}/xbmc/CompileInfo.cpp.in)
323 list(APPEND install_data ${ADDON_INSTALL_DATA})
324 add_library(compileinfo OBJECT ${CORE_BUILD_DIR}/xbmc/CompileInfo.cpp)
325 set_target_properties(compileinfo PROPERTIES FOLDER "Build Utilities")
326 target_compile_options(compileinfo PRIVATE ${SYSTEM_DEFINES} ${ARCH_DEFINES})
327 add_dependencies(compileinfo fmt::fmt)
329 if(NOT MSVC)
330   target_compile_options(compileinfo PUBLIC ${CORE_COMPILE_OPTIONS})
331 endif()
333 # RC File
334 if(WIN32)
335   configure_file(${CMAKE_SOURCE_DIR}/xbmc/platform/win32/XBMC_PC.rc.in
336                  ${CORE_BUILD_DIR}/xbmc/platform/win32/XBMC_PC.rc @ONLY)
337   add_library(resources OBJECT ${CORE_BUILD_DIR}/xbmc/platform/win32/XBMC_PC.rc)
338   set_target_properties(resources PROPERTIES FOLDER "Build Utilities")
339   target_include_directories(resources PRIVATE ${CMAKE_SOURCE_DIR}/tools/windows/packaging/media)
340   set(RESOURCES $<TARGET_OBJECTS:resources>)
341 endif()
343 # Generate messages
344 core_add_subdirs_from_filelist(${CMAKE_SOURCE_DIR}/cmake/messages/flatbuffers/*.txt)
346 include_directories(${INCLUDES} SYSTEM ${SYSTEM_INCLUDES})
347 add_compile_options(${ARCH_DEFINES} "${SYSTEM_DEFINES}" ${DEP_DEFINES} ${PATH_DEFINES})
349 set(core_DEPENDS "" CACHE STRING "" FORCE)
350 set(test_archives "" CACHE STRING "" FORCE)
351 set(test_sources "" CACHE STRING "" FORCE)
352 mark_as_advanced(core_DEPENDS)
353 mark_as_advanced(test_archives)
354 mark_as_advanced(test_sources)
356 # copy files to build tree
357 copy_files_from_filelist_to_buildtree(${CMAKE_SOURCE_DIR}/cmake/installdata/common/*.txt
358                                       ${CMAKE_SOURCE_DIR}/cmake/installdata/${CORE_SYSTEM_NAME}/*.txt)
360 list(APPEND SKINS "${CMAKE_SOURCE_DIR}/addons/skin.estuary\;${CMAKE_SOURCE_DIR}")
361 list(APPEND SKINS "${CMAKE_SOURCE_DIR}/addons/skin.estouchy\;${CMAKE_SOURCE_DIR}")
363 if(NOT ${CORE_SYSTEM_NAME} MATCHES "windows")
364   file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/system/players/VideoPlayer)
365 endif()
367 set(LIBCEC_SONAME "${CEC_SONAME}")
368 if(NOT CORE_SYSTEM_NAME STREQUAL windows AND NOT CORE_SYSTEM_NAME STREQUAL android AND NOT CORE_SYSTEM_NAME STREQUAL windowsstore)
369   configure_file(${CMAKE_SOURCE_DIR}/xbmc/DllPaths_generated.h.in
370                  ${CORE_BUILD_DIR}/DllPaths_generated.h @ONLY)
371 elseif(CORE_SYSTEM_NAME STREQUAL android)
372   configure_file(${CMAKE_SOURCE_DIR}/xbmc/DllPaths_generated_android.h.in
373                  ${CORE_BUILD_DIR}/DllPaths_generated_android.h @ONLY)
374 endif()
376 get_property(INTERNAL_DEPS GLOBAL PROPERTY INTERNAL_DEPS_PROP)
377 set(GLOBAL_TARGET_DEPS ${INTERNAL_DEPS} ${PLATFORM_GLOBAL_TARGET_DEPS})
379 # main library (used for main binary and tests)
380 if(CORE_SYSTEM_NAME STREQUAL "darwin_embedded")
381   # $<TARGET_OBJECTS:> as at 3.26.4 provides incorrect paths for ios/tvos platforms
382   # Even if XCODE_EMIT_EFFECTIVE_PLATFORM_NAME global property is used, the xcode project
383   # still sets int dir paths to $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) and the generator
384   # expression only provides a path using $(CONFIGURATION)
385   add_library(compileinfo_obj OBJECT IMPORTED)
386   set_property(TARGET compileinfo_obj PROPERTY IMPORTED_OBJECTS
387     "${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/compileinfo.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/$(OBJECT_FILE_DIR_normal:base)/$(CURRENT_ARCH)/CompileInfo.o"
388   )
389   add_library(lib${APP_NAME_LC} STATIC)
390   add_dependencies(lib${APP_NAME_LC} compileinfo)
391   target_link_libraries(lib${APP_NAME_LC} PUBLIC compileinfo_obj)
392 else()
393   add_library(lib${APP_NAME_LC} STATIC $<TARGET_OBJECTS:compileinfo>)
394 endif()
395 add_dependencies(lib${APP_NAME_LC} ${GLOBAL_TARGET_DEPS})
396 set_target_properties(lib${APP_NAME_LC} PROPERTIES PREFIX "")
398 # Other files (IDE)
399 set(OTHER_FILES cmake/README.md)
401 # Subdirs
402 foreach(CORE_PLATFORM_LC ${CORE_PLATFORM_NAME_LC})
403   core_add_subdirs_from_filelist(${CMAKE_SOURCE_DIR}/cmake/treedata/common/${CORE_PLATFORM_LC}/*.txt
404                                  ${CMAKE_SOURCE_DIR}/cmake/treedata/${CORE_SYSTEM_NAME}/${CORE_PLATFORM_LC}/*.txt)
405 endforeach()
407 core_add_subdirs_from_filelist(${CMAKE_SOURCE_DIR}/cmake/treedata/common/*.txt
408                                ${CMAKE_SOURCE_DIR}/cmake/treedata/${CORE_SYSTEM_NAME}/*.txt)
409 core_add_optional_subdirs_from_filelist(${CMAKE_SOURCE_DIR}/cmake/treedata/optional/common/*.txt
410                                         ${CMAKE_SOURCE_DIR}/cmake/treedata/optional/${CORE_SYSTEM_NAME}/*.txt)
412 target_link_libraries(lib${APP_NAME_LC} PUBLIC ${core_DEPENDS} ${SYSTEM_LDFLAGS} ${DEPLIBS} ${CMAKE_DL_LIBS} ${GLOBAL_TARGET_DEPS})
413 set_target_properties(lib${APP_NAME_LC} PROPERTIES PROJECT_LABEL "xbmc")
414 source_group_by_folder(lib${APP_NAME_LC} RELATIVE ${CMAKE_SOURCE_DIR}/xbmc)
415 if(WIN32)
416   add_precompiled_header(lib${APP_NAME_LC} pch.h ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/pch.cpp)
417   set_language_cxx(lib${APP_NAME_LC})
418 endif()
420 # main binary
421 if(NOT CORE_SYSTEM_NAME STREQUAL android)
422   if(CORE_SYSTEM_NAME STREQUAL windowsstore)
423     winstore_add_target_properties(${APP_NAME_LC})
424   endif()
425   add_executable(${APP_NAME_LC} ${CORE_MAIN_SOURCE} "${RESOURCES}" ${OTHER_FILES})
426   set_target_properties(${APP_NAME_LC} PROPERTIES ENABLE_EXPORTS ON)
427 else()
428   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
429   add_library(${APP_NAME_LC} SHARED ${CORE_MAIN_SOURCE} "${RESOURCES}" ${OTHER_FILES})
431   # Statically resolve global references to shared library (ie. ffmpeg) definitions.
432   # Related to https://stackoverflow.com/questions/46307266/including-objects-to-a-shared-library-from-a-c-archive-a
433   set_target_properties(${APP_NAME_LC} PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic")
434 endif()
435 add_dependencies(${APP_NAME_LC} ${APP_NAME_LC}-libraries)
437 whole_archive(_MAIN_LIBRARIES ${FSTRCMP_LIBRARY} ${core_DEPENDS})
438 target_link_libraries(${APP_NAME_LC} ${_MAIN_LIBRARIES} lib${APP_NAME_LC} ${DEPLIBS})
439 unset(_MAIN_LIBRARIES)
441 if(${CORE_SYSTEM_NAME} MATCHES "windows")
442   set(_bundle_dir $<TARGET_FILE_DIR:${APP_NAME_LC}>)
443 else()
444   set(_bundle_dir ${CMAKE_BINARY_DIR})
445 endif()
447 # These are skins that are copied into place from the source tree
448 set(XBT_SOURCE_FILELIST "")
449 foreach(skin ${SKINS})
450   list(GET skin 0 dir)
451   list(GET skin 1 relative)
452   copy_skin_to_buildtree(${dir} ${relative})
453 endforeach()
455 # Generate system addons
456 add_custom_target(gen_system_addons
457                     COMMAND ${CMAKE_COMMAND} -DCORE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
458                                              -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
459                                              -DCORE_PLATFORM_NAME_LC="${CORE_PLATFORM_NAME_LC}"
460                                              -DCORE_BUILD_DIR=${CORE_BUILD_DIR}
461                                              -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}
462                                              -DBUNDLEDIR=${_bundle_dir}
463                                              -P ${CMAKE_SOURCE_DIR}/cmake/scripts/common/GenerateSystemAddons.cmake
464                     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
466 if(_multiconfig_generator)
467   # Generator expressions in add_custom_command(OUTPUT) are only available in cmake 3.20+
468   # we dont really need config aware locations for a single config generator, so we only
469   # set this for multi config generators who all use newer cmake
470   set(CONFIG_VAR $<CONFIG>)
471 endif()
473 # Pack skins and copy to correct build dir (MultiConfig Generator aware)
474 add_custom_command(
475   OUTPUT ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${CONFIG_VAR}/gen_skin.timestamp
476   COMMAND ${CMAKE_COMMAND} -DBUNDLEDIR=${_bundle_dir}
477                            -DTEXTUREPACKER_EXECUTABLE=$<TARGET_FILE:TexturePacker::TexturePacker::Executable>
478                            -P ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/GeneratedPackSkins.cmake
479   COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${CONFIG_VAR}
480   COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${CONFIG_VAR}/gen_skin.timestamp
481   DEPENDS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/GeneratedPackSkins.cmake
482           ${XBT_SOURCE_FILELIST}
483   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
484   COMMENT "Generating skin xbt"
486 add_custom_target(gen_skin_pack DEPENDS ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/${CONFIG_VAR}/gen_skin.timestamp)
488 # Packaging target. This generates system addon, xbt creation, copy files to build tree
489 add_custom_target(generate-packaging ALL
490                   DEPENDS TexturePacker::TexturePacker::Executable export-files gen_skin_pack gen_system_addons)
491 # Make sure we build any libs before we look to export-files.
492 # We may need to export some shared libs/data (eg Python)
493 add_dependencies(export-files ${GLOBAL_TARGET_DEPS})
495 # Add to lib${APP_NAME_LC} solely for Win UWP. msix building doesnt seem to pick up the
496 # generated buildtree if we do it later. Other platforms dont care when this happens.
497 add_dependencies(lib${APP_NAME_LC} generate-packaging)
499 set_target_properties(generate-packaging PROPERTIES FOLDER "Build Utilities")
501 if(WIN32)
502   set_target_properties(${APP_NAME_LC} PROPERTIES WIN32_EXECUTABLE ON)
503   set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${APP_NAME_LC})
504   if(NOT CORE_SYSTEM_NAME STREQUAL windowsstore)
505     target_sources(${APP_NAME_LC} PRIVATE ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/app.manifest)
506   else()
507     set_target_properties(${APP_NAME_LC} PROPERTIES VS_USER_PROPS ${VCPROJECT_PROPS_FILE}
508                           VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION ${VS_MINIMUM_SDK_VERSION})
509   endif()
510 elseif(CORE_SYSTEM_NAME STREQUAL android)
511   # Nothing
512 elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded OR CORE_SYSTEM_NAME STREQUAL osx)
513   # Build all apple app target as bundled and dont sign.
514   # We do all signing post build of the app target manually
515   set_target_properties(${APP_NAME_LC} PROPERTIES OUTPUT_NAME ${APP_NAME}
516                                                   MACOSX_BUNDLE YES
517                                                   MACOSX_BUNDLE_INFO_PLIST ${PLATFORM_BUNDLE_INFO_PLIST}
518                                                   XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
519                                                   XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
520 else()
521   set_target_properties(${APP_NAME_LC} PROPERTIES SUFFIX ${APP_BINARY_SUFFIX})
522 endif()
524 # testing
525 if(HOST_CAN_EXECUTE_TARGET AND ENABLE_TESTING)
526   find_package(Gtest)
528   copy_files_from_filelist_to_buildtree(${CMAKE_SOURCE_DIR}/cmake/installdata/test-reference-data.txt NO_INSTALL)
529   add_executable(${APP_NAME_LC}-test EXCLUDE_FROM_ALL ${CMAKE_SOURCE_DIR}/xbmc/test/xbmc-test.cpp ${test_sources})
531   set_target_properties(PROPERTIES ENABLE_EXPORTS ON)
533   whole_archive(_TEST_LIBRARIES ${core_DEPENDS} ${GTEST_LIBRARY})
534   target_link_libraries(${APP_NAME_LC}-test PRIVATE ${SYSTEM_LDFLAGS} ${_TEST_LIBRARIES} lib${APP_NAME_LC} ${DEPLIBS} ${CMAKE_DL_LIBS})
535   unset(_TEST_LIBRARIES)
537   if (ENABLE_INTERNAL_GTEST)
538     add_dependencies(${APP_NAME_LC}-test ${APP_NAME_LC}-libraries generate-packaging gtest)
539   endif()
541   # Enable unit-test related targets
542   enable_testing()
543   gtest_add_tests(${APP_NAME_LC}-test "" ${test_sources})
544   add_custom_target(check ${CMAKE_CTEST_COMMAND} WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
545   add_dependencies(check ${APP_NAME_LC}-test)
547   # Valgrind (memcheck)
548   find_program(VALGRIND_EXECUTABLE NAMES valgrind)
549   if(VALGRIND_EXECUTABLE)
550     set(CTEST_MEMORYCHECK_COMMAND ${VALGRIND_EXECUTABLE})
551     set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "-q --trace-children=yes --leak-check=yes --track-origins=yes")
552     include(CTest)
553     add_custom_target(check-valgrind ${CMAKE_CTEST_COMMAND} -D ExperimentalMemCheck \${ARGS} WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
554     add_dependencies(check-valgrind ${APP_NAME_LC}-test)
555   endif()
557   # For testing commit series
558   add_custom_target(check-commits ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/scripts/common/CheckCommits.cmake
559                                                    -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR})
560   set_target_properties(check-commits PROPERTIES FOLDER "Build Utilities")
562   include(${CMAKE_SOURCE_DIR}/cmake/scripts/common/StaticAnalysis.cmake)
564   # code coverage
565   if(CMAKE_BUILD_TYPE STREQUAL Coverage)
566     if(EXISTS ${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake)
567       include(${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake)
568     else()
569       message(FATAL_ERROR "Code coverage not (yet) implemented for platform ${CORE_SYSTEM_NAME}")
570     endif()
571   endif()
572 endif()
574 # Documentation
575 find_package(Doxygen)
576 if(DOXYGEN_FOUND)
577   add_custom_target(doc
578                     COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.doxy
579                     COMMAND ${CMAKE_COMMAND} -E echo "Documentation built to: file://${CMAKE_SOURCE_DIR}/docs/html/index.html"
580                     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
581                     COMMENT "Generating Doxygen documentation" VERBATIM)
582 endif()
584 # link wrapper
585 if(FFMPEG_LINK_EXECUTABLE)
586   set(CMAKE_CXX_LINK_EXECUTABLE "${FFMPEG_LINK_EXECUTABLE}")
587 endif()
588 if(FFMPEG_CREATE_SHARED_LIBRARY)
589   set(CMAKE_CXX_CREATE_SHARED_LIBRARY "${FFMPEG_CREATE_SHARED_LIBRARY}")
590 endif()
592 # Platform specific additional extra targets
593 if(EXISTS ${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/ExtraTargets.cmake)
594   include(${CMAKE_SOURCE_DIR}/cmake/scripts/${CORE_SYSTEM_NAME}/ExtraTargets.cmake)
595 endif()
597 include(cmake/scripts/${CORE_SYSTEM_NAME}/Install.cmake)
599 # Add uninstall target
600 if(CMAKE_GENERATOR MATCHES Makefile)
601   add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/scripts/common/Uninstall.cmake)
602   set_target_properties(uninstall PROPERTIES FOLDER "Build Utilities")
603 endif()
605 # Create target that allows to build binary-addons.
606 # Use make binary-addons ADDONS="visualization.spectrum" to select the addons to build.
607 if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
608   if(CMAKE_CROSSCOMPILING)
609     set(_cross_args CROSS_COMPILING=yes)
610   endif()
611   if(NOT CORE_SYSTEM_NAME STREQUAL android)
612     set(_prefix ${CMAKE_BINARY_DIR}/addons)
613     set(_extra "CMAKE_EXTRA=-DPACKAGE_ZIP=ON")
614   else()
615     set(_prefix ${CMAKE_INSTALL_PREFIX})
616   endif()
617   add_custom_target(binary-addons
618     COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons clean
619     COMMAND $(MAKE) -C ${CMAKE_SOURCE_DIR}/tools/depends/target/binary-addons VERBOSE=1 V=99
620                     PREFIX=${_prefix} INSTALL_PREFIX=${_prefix} ${_cross_args} ${_extra})
621   unset(_cross_args)
622   unset(_prefix)
623 endif()
625 # Prepare add-on build env
626 include(${CORE_SOURCE_DIR}/xbmc/addons/AddonBindings.cmake)
627 file(COPY ${CORE_ADDON_BINDINGS_FILES} ${CORE_ADDON_BINDINGS_DIRS}/
628      DESTINATION ${CORE_BUILD_DIR}/include/${APP_NAME_LC}
629      REGEX ".txt" EXCLUDE)
631 set(APP_LIB_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/lib/${APP_NAME_LC})
632 set(APP_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include/${APP_NAME_LC})
633 configure_file(${CMAKE_SOURCE_DIR}/cmake/KodiConfig.cmake.in
634                ${CORE_BUILD_DIR}/lib/${APP_NAME_LC}/${APP_NAME}Config.cmake @ONLY)
635 configure_file(${CMAKE_SOURCE_DIR}/cmake/scripts/common/AddonHelpers.cmake
636                ${CORE_BUILD_DIR}/lib/${APP_NAME_LC}/AddonHelpers.cmake COPYONLY)
637 configure_file(${CMAKE_SOURCE_DIR}/cmake/scripts/common/AddOptions.cmake
638                ${CORE_BUILD_DIR}/lib/${APP_NAME_LC}/AddOptions.cmake COPYONLY)
640 # Status
641 message(STATUS "#---- CONFIGURATION ----#")
642 foreach(msg ${final_message})
643   message(STATUS ${msg})
644 endforeach()
646 if(VERBOSE)
647   message(STATUS "\n#--------------- Internal Variables -------------#")
648   message(STATUS "DEPLIBS: ${DEPLIBS}")
649   message(STATUS "core_DEPENDS: ${core_DEPENDS}")
650   message(STATUS "#---------------------------------------------#")
651   message(STATUS "SYSTEM_LDFLAGS        : ${SYSTEM_LDFLAGS}")
652   message(STATUS "CMAKE_DL_LIBS         : ${CMAKE_DL_LIBS}")
653   message(STATUS "CMAKE_C_FLAGS         : ${CMAKE_C_FLAGS}")
654   message(STATUS "CMAKE_CXX_FLAGS       : ${CMAKE_CXX_FLAGS}")
655   message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
656   message(STATUS "LTO_OPTIMIZATION      : ${CMAKE_INTERPROCEDURAL_OPTIMIZATION}")
657   if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
658     message(STATUS "CMAKE_CXX_COMPILE_OPTIONS_IPO: ${CMAKE_CXX_COMPILE_OPTIONS_IPO}")
659     message(STATUS "CMAKE_C_COMPILE_OPTIONS_IPO  : ${CMAKE_C_COMPILE_OPTIONS_IPO}")
660     message(STATUS "CMAKE_AR                     : ${CMAKE_AR}")
661     message(STATUS "CMAKE_NM                     : ${CMAKE_NM}")
662     message(STATUS "CMAKE_LINKER                 : ${CMAKE_LINKER}")
663   endif()
664   message(STATUS "#---------------------------------------------#")
665   message(STATUS "bindir     : ${bindir}")
666   message(STATUS "includedir : ${includedir}")
667   message(STATUS "libdir     : ${libdir}")
668   message(STATUS "datarootdir: ${datarootdir}")
669   message(STATUS "#---------------------------------------------#")
670   message(STATUS "BINARY: ${APP_NAME_LC}${APP_BINARY_SUFFIX}")
671   message(STATUS "#---------------------------------------------#")
672   message(STATUS "GIT_REV: ${APP_SCMID}")
673   message(STATUS "Build date: ${APP_BUILD_DATE}")
674   message(STATUS "#---------------------------------------------#")
675   message(STATUS "CPACK_GENERATOR       : ${CPACK_GENERATOR}")
676   message(STATUS "CPACK_SOURCE_GENERATOR: ${CPACK_SOURCE_GENERATOR}")
677   message(STATUS "#---------------------------------------------#")
678 endif()