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