[videoplayer] No external subs search for uPnP sources
[xbmc.git] / cmake / addons / CMakeLists.txt
blob74328e91583acd37ba3046268bca05d30f7c0b35
1 cmake_minimum_required(VERSION 3.12)
2 project(kodi-addons)
4 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
6 option(ADDON_TARBALL_CACHING "Cache downloaded addon source tarballs?" ON)
7 if(ADDON_TARBALL_CACHING)
8   message(STATUS "Addon source tarball caching is enabled")
9 else()
10   message(STATUS "Addon source tarball caching is disabled")
11 endif()
13 if(NOT CMAKE_BUILD_TYPE)
14   set(CMAKE_BUILD_TYPE Release)
15 endif()
17 if(NOT CORE_SYSTEM_NAME)
18   if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
19     set(CORE_SYSTEM_NAME "osx")
20   else()
21     string(TOLOWER ${CMAKE_SYSTEM_NAME} CORE_SYSTEM_NAME)
22   endif()
23 endif()
25 include(ExternalProject)
27 ### setup all the necessary paths
28 if(APP_ROOT)
29   set(CORE_SOURCE_DIR ${APP_ROOT})
30   unset(APP_ROOT)
31   message(WARNING "APP_ROOT is deprecated. Please use CORE_SOURCE_DIR instead.")
32 endif()
33 if(NOT CORE_SOURCE_DIR)
34   set(CORE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../..)
35 else()
36   file(TO_CMAKE_PATH "${CORE_SOURCE_DIR}" CORE_SOURCE_DIR)
37 endif()
38 get_filename_component(CORE_SOURCE_DIR "${CORE_SOURCE_DIR}" ABSOLUTE)
40 if(NOT BUILD_DIR)
41   set(BUILD_DIR "${CMAKE_BINARY_DIR}/build")
42 else()
43   file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR)
44 endif()
45 get_filename_component(BUILD_DIR "${BUILD_DIR}" ABSOLUTE)
47 if(NOT ADDON_DEPENDS_PATH)
48   set(ADDON_DEPENDS_PATH "${BUILD_DIR}/depends")
49 else()
50   file(TO_CMAKE_PATH "${ADDON_DEPENDS_PATH}" ADDON_DEPENDS_PATH)
51 endif()
52 get_filename_component(ADDON_DEPENDS_PATH "${ADDON_DEPENDS_PATH}" ABSOLUTE)
54 if(NOT PLATFORM_DIR)
55   set(PLATFORM_DIR ${CORE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME})
56   file(TO_CMAKE_PATH "${PLATFORM_DIR}" PLATFORM_DIR)
57 endif()
59 # make sure CMAKE_PREFIX_PATH is set
60 if(NOT CMAKE_PREFIX_PATH)
61   set(CMAKE_PREFIX_PATH "${ADDON_DEPENDS_PATH}")
62 else()
63   file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH)
64   list(APPEND CMAKE_PREFIX_PATH "${ADDON_DEPENDS_PATH}")
65 endif()
67 # check for autoconf stuff to pass on
68 if(AUTOCONF_FILES)
69   string(REPLACE " " ";" AUTOCONF_FILES ${AUTOCONF_FILES})
70   set(CROSS_AUTOCONF "yes")
71 endif()
73 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT OR NOT CMAKE_INSTALL_PREFIX)
74   set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/output/addons")
75 endif()
76 list(APPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
78 if (CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
79   set(BUILD_ARGS_ext -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
80                      -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION})
81 endif()
83 include(${CORE_SOURCE_DIR}/cmake/scripts/common/CompilerSettings.cmake)
85 set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
86                -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
87                -DPACKAGE_CONFIG_PATH=${ADDON_DEPENDS_PATH}/lib/pkgconfig
88                -DADDON_DEPENDS_PATH=${ADDON_DEPENDS_PATH}
89                -DOVERRIDE_PATHS=${OVERRIDE_PATHS}
90                -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
91                -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE}
92                -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX}
93                -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME}
94                -DBUILD_SHARED_LIBS=1
95                -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
96                -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
97                ${BUILD_ARGS_ext})
99 if(MSVC)
100   # move cmake specific targets to a CMakePredefinedTargets folder in Visual Studio
101   set_property(GLOBAL PROPERTY USE_FOLDERS ON)
102 endif()
104 option(PACKAGE_ZIP "Prepare built addons for packaging" OFF)
105 if(PACKAGE_ZIP)
106   # needed for project installing
107   list(APPEND BUILD_ARGS -DPACKAGE_ZIP=ON)
109   # figure out where to store the packaged ZIP archives
110   if(NOT PACKAGE_DIR)
111     set(PACKAGE_DIR "${BUILD_DIR}/zips")
112   else()
113     file(TO_CMAKE_PATH "${PACKAGE_DIR}" PACKAGE_DIR)
114   endif()
115   list(APPEND BUILD_ARGS -DPACKAGE_DIR=${PACKAGE_DIR})
117   message(STATUS "ZIP packaging enabled (destination: ${PACKAGE_DIR})")
118 endif()
120 if(CMAKE_TOOLCHAIN_FILE)
121   list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
122   message(STATUS "Toolchain specified")
123   message(STATUS ${BUILD_ARGS})
124 endif()
126 # used for addons where need special folders to store there content (if
127 # not set the addon define it byself).
128 # e.g. Google Chromium addon where his git bring:
129 # - "unable to create file" ... "Filename too long"
130 # see also WARNING by Windows on: https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart
131 if(THIRD_PARTY_PATH)
132   message(STATUS "Third party lib path specified")
133   message(STATUS ${THIRD_PARTY_PATH})
134   list(APPEND BUILD_ARGS -DTHIRD_PARTY_PATH=${THIRD_PARTY_PATH})
135 endif()
137 if(NOT ADDONS_TO_BUILD)
138   set(ADDONS_TO_BUILD "all")
139 else()
140   string(STRIP "${ADDONS_TO_BUILD}" ADDONS_TO_BUILD)
141   message(STATUS "Building following addons: ${ADDONS_TO_BUILD}")
142   string(REPLACE " " ";" ADDONS_TO_BUILD ${ADDONS_TO_BUILD})
143 endif()
145 if(NOT ADDONS_DEFINITION_DIR)
146   set(ADDONS_DEFINITION_DIR ${PROJECT_SOURCE_DIR}/addons)
147 else()
148   file(TO_CMAKE_PATH "${ADDONS_DEFINITION_DIR}" ADDONS_DEFINITION_DIR)
149 endif()
150 get_filename_component(ADDONS_DEFINITION_DIR "${ADDONS_DEFINITION_DIR}" ABSOLUTE)
152 if(ADDON_SRC_PREFIX)
153   if(NOT IS_ABSOLUTE ${ADDON_SRC_PREFIX})
154     get_filename_component(ADDON_SRC_PREFIX "${CMAKE_BINARY_DIR}/${ADDON_SRC_PREFIX}" ABSOLUTE)
155   endif()
156   message(STATUS "Overriding addon source directory prefix: ${ADDON_SRC_PREFIX}")
157 endif()
159 if(NOT APP_LIB_DIR)
160   set(APP_LIB_DIR "${ADDON_DEPENDS_PATH}/lib/kodi")
161 else()
162   file(TO_CMAKE_PATH "${APP_LIB_DIR}" APP_LIB_DIR)
163 endif()
165 set(APP_PREFIX "${CMAKE_INSTALL_PREFIX}")
167 # check for platform specific stuff
168 if(EXISTS ${PLATFORM_DIR}/defines.txt)
169   file(STRINGS ${PLATFORM_DIR}/defines.txt platformdefines)
171   if(NOT ARCH_DEFINES AND platformdefines)
172     set(ARCH_DEFINES ${platformdefines})
173   endif()
174 endif()
176 # include check_target_platform() function
177 include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake)
179 set(ADDON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
180 if(NOT WIN32)
181   # check install permissions
182   check_install_permissions(${CMAKE_INSTALL_PREFIX} can_write)
183   if(NOT ${can_write} AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
184     set(NEED_SUDO TRUE)
185     set(ADDON_INSTALL_DIR ${CMAKE_BINARY_DIR}/.install)
186     list(APPEND BUILD_ARGS -DOVERRIDE_PATHS=ON)
187     message(STATUS "NEED_SUDO: ${NEED_SUDO} (no write permission for ${CMAKE_INSTALL_PREFIX})")
188   endif()
189 endif()
191 ### prepare the build environment for the binary addons
192 # copy the PrepareEnv.cmake script to the depends path so that we can include it
193 file(COPY ${CORE_SOURCE_DIR}/cmake/scripts/common/PrepareEnv.cmake DESTINATION ${APP_LIB_DIR})
195 # add the location of PrepareEnv.cmake to CMAKE_MODULE_PATH so that it is found
196 list(APPEND CMAKE_MODULE_PATH ${APP_LIB_DIR})
198 # include PrepareEnv.cmake which contains the logic to install the addon header bindings etc
199 include(PrepareEnv)
201 ### add the depends subdirectory for any general dependencies
202 message(STATUS "\n-- ---- Preparing general dependencies ----")
203 add_subdirectory(depends)
205 # add a custom target "package-addons" which will package and install all addons
206 add_custom_target(package-addons)
208 ### get and build all the binary addons
209 # look for all the addons to be built
210 file(GLOB_RECURSE addons ${ADDONS_DEFINITION_DIR}/*.txt)
212 #if there are no addons assume that bootstrapping hasn't happened yet
213 if(NOT addons)
214   message(STATUS "Bootstrapping all default repositories as no addons were found...")
215   set(BOOTSTRAP_BUILD_DIR "${BUILD_DIR}/bootstrap")
217   # make sure that the bootstraps build addon exists
218   if(NOT EXISTS ${BOOTSTRAP_BUILD_DIR})
219     file(MAKE_DIRECTORY ${BOOTSTRAP_BUILD_DIR})
220   endif()
222   string(REPLACE ";" " " ADDONS_TO_BUILD_STR "${ADDONS_TO_BUILD}")
223   # generate the bootstrap buildsystem
224   execute_process(COMMAND ${CMAKE_COMMAND} ${PROJECT_SOURCE_DIR}/bootstrap
225                                            -DCMAKE_INSTALL_PREFIX:PATH=${ADDONS_DEFINITION_DIR}
226                                            -DBUILD_DIR:PATH=${BOOTSTRAP_BUILD_DIR}
227                                            -DADDONS_TO_BUILD:STRING=${ADDONS_TO_BUILD_STR}
228                                            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
229                   WORKING_DIRECTORY ${BOOTSTRAP_BUILD_DIR})
231   # execute the generated bootstrap buildsystem
232   execute_process(COMMAND ${CMAKE_COMMAND} --build ${BOOTSTRAP_BUILD_DIR}
233                   WORKING_DIRECTORY ${BOOTSTRAP_BUILD_DIR})
235   # now look for all the addons to be built again
236   file(GLOB_RECURSE addons ${ADDONS_DEFINITION_DIR}/*.txt)
238   if(NOT addons)
239     message(FATAL_ERROR "No addons available to be built")
240   endif()
241 endif()
243 # Track if at least one addon has been found. Everything else is likely an
244 # error either in ADDONS_TO_BUILD or in the directory configuration.
245 set(SUPPORTED_ADDON_FOUND FALSE)
247 if(NOT ADDONS_TO_BUILD)
248   set(ADDONS_TO_BUILD "all")
249 endif()
251 if(NOT ADDONS_TO_BUILD STREQUAL "all")
252   # Exact addon match list
253   set(REGEX_ADDONS_TO_BUILD ${ADDONS_TO_BUILD})
254   set(EXACT_MATCH_ADDON_LIST "")
255   set(EXCLUDE_ADDONS "")
257   foreach(addon ${ADDONS_TO_BUILD})
258     set(FOUND_EXCLUSION "")
259     string(REGEX MATCH "^[-](.*)" FOUND_EXCLUSION "${addon}")
260     if(NOT FOUND_EXCLUSION STREQUAL "")
261       list(APPEND EXCLUDE_ADDONS ${CMAKE_MATCH_1})
262       list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "-${CMAKE_MATCH_1}")
263     else()
264       foreach(addonrepoitem ${addons})
265         if(NOT (addonrepoitem MATCHES platforms.txt))
266           # need to strip regex chars, or the filter regex will use
267           string(REPLACE "*" "" strippedregex ${addon})
268           if(${addonrepoitem} MATCHES "^.*\/(${strippedregex}).txt")
269             list(APPEND EXACT_MATCH_ADDON_LIST ${addon})
270             # remove exact matches from addons_to_build
271             list(REMOVE_ITEM REGEX_ADDONS_TO_BUILD "${addon}")
272           endif()
273         endif()
274       endforeach()
275     endif()
276   endforeach()
278   message(STATUS "Exclusion list: ${EXCLUDE_ADDONS}")
279   message(STATUS "Exact Match list: ${EXACT_MATCH_ADDON_LIST}")
280   message(STATUS "Regex list: ${REGEX_ADDONS_TO_BUILD}")
281 endif()
283 foreach(addon ${addons})
284   if(NOT (addon MATCHES platforms.txt))
285     file(STRINGS ${addon} def)
286     string(REPLACE " " ";" def ${def})
287     list(GET def 0 id)
289     if("${ADDONS_TO_BUILD}" STREQUAL "all")
290       set(ADDON_FOUND TRUE)
291     else()
292       set(ADDON_EXCLUDE FALSE)
293       set(ADDON_FOUND FALSE)
294       foreach(exclusion ${EXCLUDE_ADDONS})
295         if(id MATCHES "${exclusion}")
296           set(ADDON_EXCLUDE TRUE)
297           message(STATUS "Addon ${id} matches exclusion rule -${exclusion}")
298           break()
299         endif()
300       endforeach()
302       if(ADDON_EXCLUDE)
303         continue()
304       endif()
306       list(FIND EXACT_MATCH_ADDON_LIST ${id} idx)
307       if(idx GREATER -1)
308         # exact match, so build
309         message(STATUS "Exact match ${id}, building addon")
310         set(ADDON_FOUND TRUE)
311       else()
312         # regex search
313         foreach(ADDONLISTITEM ${REGEX_ADDONS_TO_BUILD})
314           if(id MATCHES "${ADDONLISTITEM}")
315             message(STATUS "Pattern ${ADDONLISTITEM} matches ${id}, building addon")
316             set(ADDON_FOUND TRUE)
317             break()
318           endif()
319         endforeach()
320       endif()
321     endif()
323     if(ADDON_FOUND)
324       message(STATUS "\n-- ---- Configuring addon ${addon} ----")
325       set(SUPPORTED_ADDON_FOUND TRUE)
327       get_filename_component(dir ${addon} DIRECTORY)
329       # check if the addon has a platforms.txt
330       set(platform_found FALSE)
331       check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found)
333       if(${platform_found})
334         # make sure the output directory is clean
335         file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/${id}/")
337         # get the URL and revision of the addon
338         list(LENGTH def deflength)
339         list(GET def 1 url)
341         set(archive_name ${id})
342         if(ADDON_SRC_PREFIX)
343           set(SOURCE_DIR ${ADDON_SRC_PREFIX}/${id})
344           set(archive_name "")
345         else()
346           set(SOURCE_DIR "")
347         endif()
349         # if there is a 3rd parameter in the file, we consider it a git revision
350         if(deflength GREATER 2 AND "${SOURCE_DIR}" STREQUAL "")
351           list(GET def 2 revision)
353           # we need access to a git executable
354           find_package(Git REQUIRED)
356           # resolve revision to git hash
357           execute_process(COMMAND ${GIT_EXECUTABLE} ls-remote ${url} ${revision} OUTPUT_VARIABLE revision_hash)
358           # git ls-remote only works on branches and tag names but not on revisions
359           if(NOT "${revision_hash}" STREQUAL "")
360             string(REPLACE "\t" ";" revision_list ${revision_hash})
361             list(GET revision_list 0 revision_hash)
362             message(STATUS "${id}: git branch/tag ${revision} resolved to hash: ${revision_hash}")
363             set(revision ${revision_hash})
364           endif()
366           # Note: downloading specific revisions via http in the format below is probably github specific
367           # if we ever use other repositories, this might need adapting
368           set(url ${url}/archive/${revision}.tar.gz)
369           set(archive_name ${archive_name}-${revision})
370         elseif("${SOURCE_DIR}" STREQUAL "")
371           # check if the URL starts with file://
372           string(REGEX MATCH "^file://.*$" local_url "${url}")
374           #if not we assume this to be a local directory
375           if(local_url)
376             # this is not an archive
377             set(archive_name "")
379             # remove the file:// protocol from the URL
380             string(REPLACE "file://" "" SOURCE_DIR "${url}")
382             # on win32 we may have to remove another leading /
383             if(WIN32)
384               # check if the path is a local path
385               string(REGEX MATCH "^/.*$" local_path "${SOURCE_DIR}")
386               if(local_path)
387                 string(SUBSTRING "${SOURCE_DIR}" 1 -1 SOURCE_DIR)
388               endif()
389             endif()
390           endif()
391         endif()
393         # download the addon if necessary
394         if(NOT "${archive_name}" STREQUAL "")
395           # download and extract the addon
396           if(NOT ADDON_TARBALL_CACHING OR NOT EXISTS ${BUILD_DIR}/download/${archive_name}.tar.gz)
397             # cleanup any of the previously downloaded archives of this addon
398             file(GLOB archives "${BUILD_DIR}/download/${id}*.tar.gz")
399             if(archives)
400               message(STATUS "Removing old archives of ${id}: ${archives}")
401               file(REMOVE ${archives})
402             endif()
404             # download the addon
405             file(DOWNLOAD "${url}" "${BUILD_DIR}/download/${archive_name}.tar.gz" STATUS dlstatus LOG dllog SHOW_PROGRESS)
406             list(GET dlstatus 0 retcode)
407             if(NOT ${retcode} EQUAL 0)
408               file(REMOVE ${BUILD_DIR}/download/${archive_name}.tar.gz)
409               message(STATUS "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}")
410               # add a dummy target for addons to get it in addons failure file
411               list(APPEND ALL_ADDONS_BUILDING ${id})
412               add_custom_target(${id} COMMAND ${CMAKE_COMMAND} -E echo "IGNORED ${id} - download failed" COMMAND exit 1)
413               continue()
414             endif()
415           endif()
417           # remove any previously extracted version of the addon
418           file(REMOVE_RECURSE "${BUILD_DIR}/${id}")
420           # extract the addon from the archive
421           execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzvf ${BUILD_DIR}/download/${archive_name}.tar.gz
422                           WORKING_DIRECTORY ${BUILD_DIR})
423           file(GLOB extract_dir "${BUILD_DIR}/${archive_name}*")
424           if(extract_dir STREQUAL "")
425             message(FATAL_ERROR "${id}: error extracting ${BUILD_DIR}/download/${archive_name}.tar.gz")
426           else()
427             file(RENAME "${extract_dir}" "${BUILD_DIR}/${id}")
428           endif()
430           set(SOURCE_DIR ${BUILD_DIR}/${id})
431         endif()
433         if(NOT "${SOURCE_DIR}" STREQUAL "" AND EXISTS ${SOURCE_DIR})
434           # create a list of addons we are building
435           list(APPEND ALL_ADDONS_BUILDING ${id})
437           # setup the buildsystem for the addon
438           externalproject_add(${id}
439                               SOURCE_DIR ${SOURCE_DIR}
440                               INSTALL_DIR ${ADDON_INSTALL_DIR}
441                               CMAKE_ARGS ${BUILD_ARGS})
443           # add a custom step to the external project between the configure and the build step which will always
444           # be executed and therefore forces a re-build of all changed files
445           externalproject_add_step(${id} forcebuild
446                                    COMMAND ${CMAKE_COMMAND} -E echo "Force build of ${id}"
447                                    DEPENDEES configure
448                                    DEPENDERS build
449                                    ALWAYS 1)
451           set(${id}_DEPENDS_DIR ${SOURCE_DIR}/depends)
453           if(EXISTS ${${id}_DEPENDS_DIR})
454             include(${CORE_SOURCE_DIR}/cmake/scripts/common/HandleDepends.cmake)
455             add_addon_depends(${id} ${${id}_DEPENDS_DIR})
456             if(${id}_DEPS AND NOT "${${id}_DEPS}" STREQUAL "")
457               message(STATUS "${id} DEPENDENCIES: ${${id}_DEPS}")
458               add_dependencies(${id} ${${id}_DEPS})
459             endif()
460           endif()
462           if(CROSS_AUTOCONF AND AUTOCONF_FILES)
463             if(EXISTS ${SOURCE_DIR}/bootstrap/autoreconf.txt)
464               file(STRINGS ${SOURCE_DIR}/bootstrap/autoreconf.txt conf_dirs)
465               foreach(conf_dir ${conf_dirs})
466                 foreach(afile ${AUTOCONF_FILES})
467                   message(STATUS "copying ${afile} to ${SOURCE_DIR}/${conf_dir}")
468                   file(COPY ${afile} DESTINATION ${SOURCE_DIR}/${conf_dir})
469                 endforeach()
470               endforeach()
471             endif()
472           endif()
474           # create a forwarding target to the addon-package target
475           get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
476           if(_isMultiConfig)
477             set(config --config $<CONFIG>)
478           endif()
479           add_custom_target(package-${id}
480                     COMMAND ${CMAKE_COMMAND} --build ${id}-prefix/src/${id}-build ${config} --target addon-package
481                     DEPENDS ${id})
482           add_dependencies(package-addons package-${id})
484         else()
485           message(FATAL_ERROR "${id}: invalid or missing addon source directory at ${SOURCE_DIR}")
486         endif()
487       else()
488         # add a dummy target for addons that are unsupported on this platform
489         add_custom_target(${id} COMMAND ${CMAKE_COMMAND} -E echo "IGNORED ${id} - not supported on ${CORE_SYSTEM_NAME}\n")
490       endif()
491     endif()
492   endif()
493 endforeach()
494 message(STATUS "")
496 if(NEED_SUDO)
497   add_custom_target(sudo-install
498                     COMMAND ${CMAKE_COMMAND} -E echo "sudo rights needed to install to ${CMAKE_INSTALL_PREFIX}\n"
499                     COMMAND sudo ${CMAKE_COMMAND} -E copy_directory ${ADDON_INSTALL_DIR}/ ${CMAKE_INSTALL_PREFIX}/
500                     COMMAND sudo -k)
502   foreach(_id ${ALL_ADDONS_BUILDING})
503     add_dependencies(sudo-install ${_id})
504   endforeach()
505   message(WARNING "sudo rights needed to install to ${CMAKE_INSTALL_PREFIX}")
506   message(STATUS "\nplease type \"make sudo-install\"\n\n")
507 endif()
509 if(NOT SUPPORTED_ADDON_FOUND)
510   message(FATAL_ERROR "${ADDONS_TO_BUILD} did not match any of the supported addons. \
511                        A list of supported addons can be viewed by building the 'supported_addons' target. \
512                        Addon definitions are loaded from ADDONS_DEFINITION_DIR (${ADDONS_DEFINITION_DIR}).")
513 endif()
515 # add custom target "supported_addons" that returns all addons that are supported on this platform
516 string(REPLACE ";" " " ALL_ADDONS_BUILDING "${ALL_ADDONS_BUILDING}")
517 add_custom_target(supported_addons COMMAND ${CMAKE_COMMAND} -E echo "ALL_ADDONS_BUILDING: ${ALL_ADDONS_BUILDING}" VERBATIM)
518 add_custom_target(need-sudo COMMAND ${CMAKE_COMMAND} -E echo ${NEED_SUDO} VERBATIM)