diff options
Diffstat (limited to 'project/cmake/scripts')
| -rw-r--r-- | project/cmake/scripts/common/addon-helpers.cmake | 113 | ||||
| -rw-r--r-- | project/cmake/scripts/common/addoptions.cmake | 82 | ||||
| -rw-r--r-- | project/cmake/scripts/common/check_target_platform.cmake | 61 | ||||
| -rw-r--r-- | project/cmake/scripts/common/handle-depends.cmake | 191 | ||||
| -rw-r--r-- | project/cmake/scripts/common/prepare-env.cmake | 88 | ||||
| -rw-r--r-- | project/cmake/scripts/windows/c-flag-overrides.cmake | 5 | ||||
| -rw-r--r-- | project/cmake/scripts/windows/cxx-flag-overrides.cmake | 5 |
7 files changed, 545 insertions, 0 deletions
diff --git a/project/cmake/scripts/common/addon-helpers.cmake b/project/cmake/scripts/common/addon-helpers.cmake new file mode 100644 index 0000000..b94df2a --- /dev/null +++ b/project/cmake/scripts/common/addon-helpers.cmake | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | # Workaround for the fact that cpack's filenames are not customizable. | ||
| 2 | # Each add-on is added as a separate component to facilitate zip/tgz packaging. | ||
| 3 | # The filenames are always of the form basename-component, which is | ||
| 4 | # incompatible with the addonid-version scheme we want. This hack renames | ||
| 5 | # the files from the file names generated by the 'package' target. | ||
| 6 | # Sadly we cannot extend the 'package' target, as it is a builtin target, see | ||
| 7 | # http://public.kitware.com/Bug/view.php?id=8438 | ||
| 8 | # Thus, we have to add an 'addon-package' target. | ||
| 9 | add_custom_target(addon-package | ||
| 10 | COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package) | ||
| 11 | |||
| 12 | macro(add_cpack_workaround target version ext) | ||
| 13 | add_custom_command(TARGET addon-package PRE_BUILD | ||
| 14 | COMMAND ${CMAKE_COMMAND} -E rename addon-${target}-${version}.${ext} ${target}-${version}.${ext}) | ||
| 15 | endmacro() | ||
| 16 | |||
| 17 | # Grab the version from a given add-on's addon.xml | ||
| 18 | macro (addon_version dir prefix) | ||
| 19 | FILE(READ ${dir}/addon.xml ADDONXML) | ||
| 20 | STRING(REGEX MATCH "<addon[^>]*version.?=.?.[0-9\\.]+" VERSION_STRING ${ADDONXML}) | ||
| 21 | STRING(REGEX REPLACE ".*version=.([0-9\\.]+).*" "\\1" ${prefix}_VERSION ${VERSION_STRING}) | ||
| 22 | message(STATUS ${prefix}_VERSION=${${prefix}_VERSION}) | ||
| 23 | endmacro() | ||
| 24 | |||
| 25 | # Build, link and optionally package an add-on | ||
| 26 | macro (build_addon target prefix libs) | ||
| 27 | ADD_LIBRARY(${target} ${${prefix}_SOURCES}) | ||
| 28 | TARGET_LINK_LIBRARIES(${target} ${${libs}}) | ||
| 29 | addon_version(${target} ${prefix}) | ||
| 30 | SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${${prefix}_VERSION} | ||
| 31 | SOVERSION ${APP_VERSION_MAJOR}.${APP_VERSION_MINOR} | ||
| 32 | PREFIX "") | ||
| 33 | IF(OS STREQUAL "android") | ||
| 34 | SET_TARGET_PROPERTIES(${target} PROPERTIES PREFIX "lib") | ||
| 35 | ENDIF(OS STREQUAL "android") | ||
| 36 | |||
| 37 | # set zip as default if addon-package is called without PACKAGE_XXX | ||
| 38 | SET(CPACK_GENERATOR "ZIP") | ||
| 39 | SET(ext "zip") | ||
| 40 | IF(PACKAGE_ZIP OR PACKAGE_TGZ) | ||
| 41 | IF(PACKAGE_TGZ) | ||
| 42 | SET(CPACK_GENERATOR "TGZ") | ||
| 43 | SET(ext "tar.gz") | ||
| 44 | ENDIF(PACKAGE_TGZ) | ||
| 45 | SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) | ||
| 46 | set(CPACK_PACKAGE_FILE_NAME addon) | ||
| 47 | IF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||
| 48 | SET(CPACK_STRIP_FILES TRUE) | ||
| 49 | ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||
| 50 | set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) | ||
| 51 | set(CPACK_COMPONENTS_IGNORE_GROUPS 1) | ||
| 52 | list(APPEND CPACK_COMPONENTS_ALL ${target}-${${prefix}_VERSION}) | ||
| 53 | # Pack files together to create an archive | ||
| 54 | INSTALL(DIRECTORY ${target} DESTINATION ./ COMPONENT ${target}-${${prefix}_VERSION}) | ||
| 55 | IF(WIN32) | ||
| 56 | # get the installation location for the addon's target | ||
| 57 | get_property(dll_location TARGET ${target} PROPERTY LOCATION) | ||
| 58 | # in case of a VC++ project the installation location contains a $(Configuration) VS variable | ||
| 59 | # we replace it with ${CMAKE_BUILD_TYPE} (which doesn't cover the case when the build configuration | ||
| 60 | # is changed within Visual Studio) | ||
| 61 | string(REPLACE "$(Configuration)" "${CMAKE_BUILD_TYPE}" dll_location "${dll_location}") | ||
| 62 | |||
| 63 | # install the generated DLL file | ||
| 64 | INSTALL(PROGRAMS ${dll_location} DESTINATION ${target} | ||
| 65 | COMPONENT ${target}-${${prefix}_VERSION}) | ||
| 66 | |||
| 67 | IF(CMAKE_BUILD_TYPE MATCHES Debug) | ||
| 68 | # for debug builds also install the PDB file | ||
| 69 | get_filename_component(dll_directory ${dll_location} DIRECTORY) | ||
| 70 | INSTALL(FILES ${dll_directory}/${target}.pdb DESTINATION ${target} | ||
| 71 | COMPONENT ${target}-${${prefix}_VERSION}) | ||
| 72 | ENDIF() | ||
| 73 | ELSE(WIN32) | ||
| 74 | INSTALL(TARGETS ${target} DESTINATION ${target} | ||
| 75 | COMPONENT ${target}-${${prefix}_VERSION}) | ||
| 76 | ENDIF(WIN32) | ||
| 77 | add_cpack_workaround(${target} ${${prefix}_VERSION} ${ext}) | ||
| 78 | ELSE(PACKAGE_ZIP OR PACKAGE_TGZ) | ||
| 79 | INSTALL(TARGETS ${target} DESTINATION lib/kodi/addons/${target}) | ||
| 80 | INSTALL(DIRECTORY ${target} DESTINATION share/kodi/addons) | ||
| 81 | ENDIF(PACKAGE_ZIP OR PACKAGE_TGZ) | ||
| 82 | endmacro() | ||
| 83 | |||
| 84 | # finds a path to a given file (recursive) | ||
| 85 | function (kodi_find_path var_name filename search_path strip_file) | ||
| 86 | file(GLOB_RECURSE PATH_TO_FILE ${search_path} ${filename}) | ||
| 87 | if(strip_file) | ||
| 88 | string(REPLACE ${filename} "" PATH_TO_FILE ${PATH_TO_FILE}) | ||
| 89 | endif(strip_file) | ||
| 90 | set (${var_name} ${PATH_TO_FILE} PARENT_SCOPE) | ||
| 91 | endfunction() | ||
| 92 | |||
| 93 | # Cmake build options | ||
| 94 | include(addoptions) | ||
| 95 | include(TestCXXAcceptsFlag) | ||
| 96 | OPTION(PACKAGE_ZIP "Package Zip file?" OFF) | ||
| 97 | OPTION(PACKAGE_TGZ "Package TGZ file?" OFF) | ||
| 98 | OPTION(BUILD_SHARED_LIBS "Build shared libs?" ON) | ||
| 99 | |||
| 100 | # LTO support? | ||
| 101 | CHECK_CXX_ACCEPTS_FLAG("-flto" HAVE_LTO) | ||
| 102 | IF(HAVE_LTO) | ||
| 103 | OPTION(USE_LTO "use link time optimization" OFF) | ||
| 104 | IF(USE_LTO) | ||
| 105 | add_options(ALL_LANGUAGES ALL_BUILDS "-flto") | ||
| 106 | ENDIF(USE_LTO) | ||
| 107 | ENDIF(HAVE_LTO) | ||
| 108 | |||
| 109 | # set this to try linking dependencies as static as possible | ||
| 110 | IF(ADDONS_PREFER_STATIC_LIBS) | ||
| 111 | SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) | ||
| 112 | ENDIF(ADDONS_PREFER_STATIC_LIBS) | ||
| 113 | |||
diff --git a/project/cmake/scripts/common/addoptions.cmake b/project/cmake/scripts/common/addoptions.cmake new file mode 100644 index 0000000..0ebb823 --- /dev/null +++ b/project/cmake/scripts/common/addoptions.cmake | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | # - Add options without repeating them on the command line | ||
| 2 | # | ||
| 3 | # Synopsis: | ||
| 4 | # | ||
| 5 | # add_options (lang build opts) | ||
| 6 | # | ||
| 7 | # where: | ||
| 8 | # | ||
| 9 | # lang Name of the language whose compiler should receive the | ||
| 10 | # options, e.g. CXX. If a comma-separated list is received | ||
| 11 | # then the option is added for all those languages. Use the | ||
| 12 | # special value ALL_LANGUAGES for these languages: CXX, C | ||
| 13 | # and Fortran | ||
| 14 | # | ||
| 15 | # build Kind of build to which this options should apply, | ||
| 16 | # such as DEBUG and RELEASE. This can also be a comma- | ||
| 17 | # separated list. Use the special value ALL_BUILDS to apply | ||
| 18 | # to all builds. | ||
| 19 | # | ||
| 20 | # opts List of options to add. Each should be quoted. | ||
| 21 | # | ||
| 22 | # Example: | ||
| 23 | # | ||
| 24 | # add_options (CXX RELEASE "-O3" "-DNDEBUG" "-Wall") | ||
| 25 | |||
| 26 | function (add_options langs builds) | ||
| 27 | # special handling of empty language specification | ||
| 28 | if ("${langs}" STREQUAL "ALL_LANGUAGES") | ||
| 29 | set (langs CXX C Fortran) | ||
| 30 | endif ("${langs}" STREQUAL "ALL_LANGUAGES") | ||
| 31 | foreach (lang IN LISTS langs) | ||
| 32 | # prepend underscore if necessary | ||
| 33 | foreach (build IN LISTS builds) | ||
| 34 | if (NOT ("${build}" STREQUAL "ALL_BUILDS")) | ||
| 35 | set (_bld "_${build}") | ||
| 36 | string (TOUPPER "${_bld}" _bld) | ||
| 37 | else (NOT ("${build}" STREQUAL "ALL_BUILDS")) | ||
| 38 | set (_bld "") | ||
| 39 | endif (NOT ("${build}" STREQUAL "ALL_BUILDS")) | ||
| 40 | foreach (_opt IN LISTS ARGN) | ||
| 41 | set (_var "CMAKE_${lang}_FLAGS${_bld}") | ||
| 42 | #message (STATUS "Adding \"${_opt}\" to \${${_var}}") | ||
| 43 | # remove it first | ||
| 44 | string (REPLACE "${_opt}" "" _without "${${_var}}") | ||
| 45 | string (STRIP "${_without}" _without) | ||
| 46 | # we need to strip this one as well, so they are comparable | ||
| 47 | string (STRIP "${${_var}}" _stripped) | ||
| 48 | # if it wasn't there, then add it at the end | ||
| 49 | if ("${_without}" STREQUAL "${_stripped}") | ||
| 50 | # don't add any extra spaces if no options yet are set | ||
| 51 | if (NOT ${_stripped} STREQUAL "") | ||
| 52 | set (${_var} "${_stripped} ${_opt}") | ||
| 53 | else (NOT ${_stripped} STREQUAL "") | ||
| 54 | set (${_var} "${_opt}") | ||
| 55 | endif (NOT ${_stripped} STREQUAL "") | ||
| 56 | set (${_var} "${${_var}}" PARENT_SCOPE) | ||
| 57 | endif ("${_without}" STREQUAL "${_stripped}") | ||
| 58 | endforeach (_opt) | ||
| 59 | endforeach (build) | ||
| 60 | endforeach (lang) | ||
| 61 | endfunction (add_options lang build) | ||
| 62 | |||
| 63 | # set varname to flag unless user has specified something that matches regex | ||
| 64 | function (set_default_option varname flag regex) | ||
| 65 | if (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}" | ||
| 66 | AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}" | ||
| 67 | AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}") | ||
| 68 | set (${varname} ${flag} PARENT_SCOPE) | ||
| 69 | else (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}" | ||
| 70 | AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}" | ||
| 71 | AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}") | ||
| 72 | set (${varname} PARENT_SCOPE) | ||
| 73 | endif (NOT "$ENV{CXXFLAGS}" MATCHES "${regex}" | ||
| 74 | AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${regex}" | ||
| 75 | AND NOT "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" MATCHES "${regex}") | ||
| 76 | endfunction (set_default_option) | ||
| 77 | |||
| 78 | # note: this must be called before project() | ||
| 79 | macro (no_default_options) | ||
| 80 | # prevent the platform probe to set options | ||
| 81 | set (CMAKE_NOT_USING_CONFIG_FLAGS TRUE) | ||
| 82 | endmacro (no_default_options) | ||
diff --git a/project/cmake/scripts/common/check_target_platform.cmake b/project/cmake/scripts/common/check_target_platform.cmake new file mode 100644 index 0000000..fc8b403 --- /dev/null +++ b/project/cmake/scripts/common/check_target_platform.cmake | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | # handle target platforms | ||
| 2 | function(check_target_platform dir target_platform build) | ||
| 3 | # param[in] dir path/directory of the addon/dependency | ||
| 4 | # param[in] target_platform target platform of the build | ||
| 5 | # param[out] build Result whether the addon/dependency should be built for the specified target platform | ||
| 6 | |||
| 7 | set(${build} FALSE) | ||
| 8 | # check if the given directory exists and contains a platforms.txt | ||
| 9 | if(EXISTS ${dir} AND EXISTS ${dir}/platforms.txt) | ||
| 10 | # get all the specified platforms | ||
| 11 | file(STRINGS ${dir}/platforms.txt platforms) | ||
| 12 | separate_arguments(platforms) | ||
| 13 | |||
| 14 | # check if the addon/dependency should be built for the current platform | ||
| 15 | foreach(platform ${platforms}) | ||
| 16 | if(${platform} STREQUAL "all" OR ${platform} STREQUAL ${target_platform}) | ||
| 17 | set(${build} TRUE) | ||
| 18 | else() | ||
| 19 | # check if the platform is defined as "!<platform>" | ||
| 20 | string(SUBSTRING ${platform} 0 1 platform_first) | ||
| 21 | if(${platform_first} STREQUAL "!") | ||
| 22 | # extract the platform | ||
| 23 | string(LENGTH ${platform} platform_length) | ||
| 24 | MATH(EXPR platform_length "${platform_length} - 1") | ||
| 25 | string(SUBSTRING ${platform} 1 ${platform_length} platform) | ||
| 26 | |||
| 27 | # check if the current platform does not match the extracted platform | ||
| 28 | if (NOT ${platform} STREQUAL ${target_platform}) | ||
| 29 | set(${build} TRUE) | ||
| 30 | endif() | ||
| 31 | endif() | ||
| 32 | endif() | ||
| 33 | endforeach() | ||
| 34 | else() | ||
| 35 | set(${build} TRUE) | ||
| 36 | endif() | ||
| 37 | |||
| 38 | # make the ${build} variable available to the calling script | ||
| 39 | set(${build} "${${build}}" PARENT_SCOPE) | ||
| 40 | endfunction() | ||
| 41 | |||
| 42 | function(check_install_permissions install_dir have_perms) | ||
| 43 | # param[in] install_dir directory to check for write permissions | ||
| 44 | # param[out] have_perms wether we have permissions to install to install_dir | ||
| 45 | |||
| 46 | set(${have_perms} TRUE) | ||
| 47 | execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}/lib/kodi | ||
| 48 | COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}/share/kodi | ||
| 49 | COMMAND ${CMAKE_COMMAND} -E touch ${install_dir}/lib/kodi/.cmake-inst-test ${install_dir}/share/kodi/.cmake-inst-test | ||
| 50 | RESULT_VARIABLE permtest) | ||
| 51 | |||
| 52 | if(${permtest} GREATER 0) | ||
| 53 | message(STATUS "check_install_permissions: ${permtest}") | ||
| 54 | set(${have_perms} FALSE) | ||
| 55 | endif() | ||
| 56 | set(${have_perms} "${${have_perms}}" PARENT_SCOPE) | ||
| 57 | |||
| 58 | if(EXISTS ${install_dir}/lib/kodi/.cmake-inst-test OR EXISTS ${install_dir}/share/kodi/.cmake-inst-test) | ||
| 59 | file(REMOVE ${install_dir}/lib/kodi/.cmake-inst-test ${install_dir}/share/kodi/.cmake-inst-test) | ||
| 60 | endif() | ||
| 61 | endfunction() | ||
diff --git a/project/cmake/scripts/common/handle-depends.cmake b/project/cmake/scripts/common/handle-depends.cmake new file mode 100644 index 0000000..b3bf3cd --- /dev/null +++ b/project/cmake/scripts/common/handle-depends.cmake | |||
| @@ -0,0 +1,191 @@ | |||
| 1 | include(${APP_ROOT}/project/cmake/scripts/common/check_target_platform.cmake) | ||
| 2 | |||
| 3 | # handle addon depends | ||
| 4 | function(add_addon_depends addon searchpath) | ||
| 5 | # input: string addon string searchpath | ||
| 6 | |||
| 7 | set(OUTPUT_DIR ${DEPENDS_PATH}) | ||
| 8 | file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt) | ||
| 9 | file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt) | ||
| 10 | list(APPEND cmake_input_files ${cmake_input_files2}) | ||
| 11 | |||
| 12 | foreach(file ${cmake_input_files}) | ||
| 13 | if(NOT (file MATCHES CMakeLists.txt OR | ||
| 14 | file MATCHES install.txt OR | ||
| 15 | file MATCHES noinstall.txt OR | ||
| 16 | file MATCHES flags.txt OR | ||
| 17 | file MATCHES deps.txt OR | ||
| 18 | file MATCHES platforms.txt)) | ||
| 19 | message(STATUS "Processing ${file}") | ||
| 20 | file(STRINGS ${file} def) | ||
| 21 | separate_arguments(def) | ||
| 22 | list(LENGTH def deflength) | ||
| 23 | get_filename_component(dir ${file} PATH) | ||
| 24 | |||
| 25 | # get the id of the dependency | ||
| 26 | if(NOT "${def}" STREQUAL "") | ||
| 27 | # read the id from the file | ||
| 28 | list(GET def 0 id) | ||
| 29 | else() | ||
| 30 | # read the id from the filename | ||
| 31 | get_filename_component(id ${file} NAME_WE) | ||
| 32 | endif() | ||
| 33 | |||
| 34 | # check if the dependency has a platforms.txt | ||
| 35 | set(platform_found FALSE) | ||
| 36 | check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found) | ||
| 37 | |||
| 38 | if(${platform_found} AND NOT TARGET ${id}) | ||
| 39 | # determine the download URL of the dependency | ||
| 40 | set(url "") | ||
| 41 | if(deflength GREATER 1) | ||
| 42 | list(GET def 1 url) | ||
| 43 | message(STATUS "${id} url: ${url}") | ||
| 44 | endif() | ||
| 45 | |||
| 46 | # check if there are any library specific flags that need to be passed on | ||
| 47 | if(EXISTS ${dir}/flags.txt) | ||
| 48 | file(STRINGS ${dir}/flags.txt extraflags) | ||
| 49 | separate_arguments(extraflags) | ||
| 50 | message(STATUS "${id} extraflags: ${extraflags}") | ||
| 51 | endif() | ||
| 52 | |||
| 53 | set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} | ||
| 54 | -DOUTPUT_DIR=${OUTPUT_DIR} | ||
| 55 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | ||
| 56 | -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE} | ||
| 57 | -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX} | ||
| 58 | -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} | ||
| 59 | -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME} | ||
| 60 | -DENABLE_STATIC=1 | ||
| 61 | -DBUILD_SHARED_LIBS=0) | ||
| 62 | # if there are no make rules override files available take care of manually passing on ARCH_DEFINES | ||
| 63 | if(NOT CMAKE_USER_MAKE_RULES_OVERRIDE AND NOT CMAKE_USER_MAKE_RULES_OVERRIDE_CXX) | ||
| 64 | # make sure we create strings, not lists | ||
| 65 | set(TMP_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_DEFINES}") | ||
| 66 | set(TMP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_DEFINES}") | ||
| 67 | list(APPEND BUILD_ARGS -DCMAKE_C_FLAGS=${TMP_C_FLAGS} | ||
| 68 | -DCMAKE_CXX_FLAGS=${TMP_CXX_FLAGS}) | ||
| 69 | endif() | ||
| 70 | |||
| 71 | if(CMAKE_TOOLCHAIN_FILE) | ||
| 72 | list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) | ||
| 73 | MESSAGE("toolchain specified") | ||
| 74 | MESSAGE(${BUILD_ARGS}) | ||
| 75 | endif() | ||
| 76 | |||
| 77 | # if there's a CMakeLists.txt use it to prepare the build | ||
| 78 | set(PATCH_FILE ${BUILD_DIR}/${id}/tmp/patch.cmake) | ||
| 79 | if(EXISTS ${dir}/CMakeLists.txt) | ||
| 80 | file(APPEND ${PATCH_FILE} | ||
| 81 | "file(COPY ${dir}/CMakeLists.txt | ||
| 82 | DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") | ||
| 83 | endif() | ||
| 84 | |||
| 85 | # check if we have patches to apply | ||
| 86 | file(GLOB patches ${dir}/*.patch) | ||
| 87 | list(SORT patches) | ||
| 88 | foreach(patch ${patches}) | ||
| 89 | file(APPEND ${PATCH_FILE} | ||
| 90 | "execute_process(COMMAND patch -p1 -i ${patch})\n") | ||
| 91 | endforeach() | ||
| 92 | |||
| 93 | |||
| 94 | # if there's an install.txt use it to properly install the built files | ||
| 95 | set(INSTALL_COMMAND "") | ||
| 96 | if(EXISTS ${dir}/install.txt) | ||
| 97 | set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND} | ||
| 98 | -DINPUTDIR=${BUILD_DIR}/${id}/src/${id}-build/ | ||
| 99 | -DINPUTFILE=${dir}/install.txt | ||
| 100 | -DDESTDIR=${OUTPUT_DIR} | ||
| 101 | -DENABLE_STATIC=1 | ||
| 102 | "${extraflags}" | ||
| 103 | -P ${PROJECT_SOURCE_DIR}/install.cmake) | ||
| 104 | elseif(EXISTS ${dir}/noinstall.txt) | ||
| 105 | set(INSTALL_COMMAND INSTALL_COMMAND "") | ||
| 106 | endif() | ||
| 107 | |||
| 108 | # check if there's a deps.txt containing dependencies on other libraries | ||
| 109 | if(EXISTS ${dir}/deps.txt) | ||
| 110 | file(STRINGS ${dir}/deps.txt deps) | ||
| 111 | message(STATUS "${id} depends: ${deps}") | ||
| 112 | else() | ||
| 113 | set(deps) | ||
| 114 | endif() | ||
| 115 | |||
| 116 | if(CROSS_AUTOCONF AND AUTOCONF_FILES) | ||
| 117 | foreach(afile ${AUTOCONF_FILES}) | ||
| 118 | file(APPEND ${PATCH_FILE} | ||
| 119 | "message(STATUS \"AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}\")\n | ||
| 120 | file(COPY ${afile} DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") | ||
| 121 | endforeach() | ||
| 122 | endif() | ||
| 123 | |||
| 124 | # if the patch file exists we need to set the PATCH_COMMAND | ||
| 125 | set(PATCH_COMMAND "") | ||
| 126 | if (EXISTS ${PATCH_FILE}) | ||
| 127 | set(PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_FILE}) | ||
| 128 | endif() | ||
| 129 | |||
| 130 | # prepare the setup of the call to externalproject_add() | ||
| 131 | set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id} | ||
| 132 | CMAKE_ARGS ${extraflags} ${BUILD_ARGS} | ||
| 133 | PATCH_COMMAND ${PATCH_COMMAND} | ||
| 134 | "${INSTALL_COMMAND}") | ||
| 135 | |||
| 136 | # if there's an url defined we need to pass that to externalproject_add() | ||
| 137 | if(DEFINED url AND NOT "${url}" STREQUAL "") | ||
| 138 | # check if there's a third parameter in the file | ||
| 139 | if(deflength GREATER 2) | ||
| 140 | # the third parameter is considered as a revision of a git repository | ||
| 141 | list(GET def 2 revision) | ||
| 142 | |||
| 143 | externalproject_add(${id} | ||
| 144 | GIT_REPOSITORY ${url} | ||
| 145 | GIT_TAG ${revision} | ||
| 146 | "${EXTERNALPROJECT_SETUP}") | ||
| 147 | else() | ||
| 148 | set(CONFIGURE_COMMAND "") | ||
| 149 | if(NOT WIN32) | ||
| 150 | # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH | ||
| 151 | set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig | ||
| 152 | ${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags} ${BUILD_ARGS} | ||
| 153 | ${BUILD_DIR}/${id}/src/${id} | ||
| 154 | -DPACKAGE_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig | ||
| 155 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | ||
| 156 | -DOUTPUT_DIR=${OUTPUT_DIR} | ||
| 157 | -DCMAKE_PREFIX_PATH=${OUTPUT_DIR} | ||
| 158 | -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} | ||
| 159 | -DCMAKE_EXE_LINKER_FLAGS=-L${OUTPUT_DIR}/lib | ||
| 160 | -DCMAKE_INCLUDE_PATH=${OUTPUT_DIR}/include) | ||
| 161 | endif() | ||
| 162 | |||
| 163 | externalproject_add(${id} | ||
| 164 | URL ${url} | ||
| 165 | DOWNLOAD_DIR ${BUILD_DIR}/download | ||
| 166 | CONFIGURE_COMMAND ${CONFIGURE_COMMAND} | ||
| 167 | "${EXTERNALPROJECT_SETUP}") | ||
| 168 | endif() | ||
| 169 | else() | ||
| 170 | externalproject_add(${id} | ||
| 171 | SOURCE_DIR ${dir} | ||
| 172 | "${EXTERNALPROJECT_SETUP}") | ||
| 173 | endif() | ||
| 174 | |||
| 175 | if(deps) | ||
| 176 | add_dependencies(${id} ${deps}) | ||
| 177 | endif() | ||
| 178 | endif() | ||
| 179 | |||
| 180 | # if the dependency is available for the target platform add it to the list of the addon's dependencies | ||
| 181 | # (even if the target already exists as it still has to be built before the addon) | ||
| 182 | if(${platform_found}) | ||
| 183 | list(APPEND ${addon}_DEPS ${id}) | ||
| 184 | endif() | ||
| 185 | endif() | ||
| 186 | endforeach() | ||
| 187 | |||
| 188 | # make the ${addon}_DEPS variable available to the calling script | ||
| 189 | set(${addon}_DEPS "${${addon}_DEPS}" PARENT_SCOPE) | ||
| 190 | endfunction() | ||
| 191 | |||
diff --git a/project/cmake/scripts/common/prepare-env.cmake b/project/cmake/scripts/common/prepare-env.cmake new file mode 100644 index 0000000..7df421c --- /dev/null +++ b/project/cmake/scripts/common/prepare-env.cmake | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | # parse version.txt to get the version info | ||
| 2 | if(EXISTS "${APP_ROOT}/version.txt") | ||
| 3 | file(STRINGS "${APP_ROOT}/version.txt" versions) | ||
| 4 | foreach (version ${versions}) | ||
| 5 | if(version MATCHES "^VERSION_.*") | ||
| 6 | string(REGEX MATCH "^[^ ]+" version_name ${version}) | ||
| 7 | string(REPLACE "${version_name} " "" version_value ${version}) | ||
| 8 | set(APP_${version_name} "${version_value}") | ||
| 9 | else() | ||
| 10 | string(REGEX MATCH "^[^ ]+" name ${version}) | ||
| 11 | string(REPLACE "${name} " "" value ${version}) | ||
| 12 | set(${name} "${value}") | ||
| 13 | endif() | ||
| 14 | endforeach() | ||
| 15 | endif() | ||
| 16 | |||
| 17 | # bail if we can't parse versions | ||
| 18 | if(NOT DEFINED APP_VERSION_MAJOR OR NOT DEFINED APP_VERSION_MINOR) | ||
| 19 | message(FATAL_ERROR "Could not determine app version! make sure that ${APP_ROOT}/version.txt exists") | ||
| 20 | endif() | ||
| 21 | |||
| 22 | ### copy all the addon binding header files to include/kodi | ||
| 23 | # make sure include/kodi exists and is empty | ||
| 24 | set(KODI_LIB_DIR ${DEPENDS_PATH}/lib/kodi) | ||
| 25 | if(NOT EXISTS "${KODI_LIB_DIR}/") | ||
| 26 | file(MAKE_DIRECTORY ${KODI_LIB_DIR}) | ||
| 27 | endif() | ||
| 28 | |||
| 29 | set(KODI_INCLUDE_DIR ${DEPENDS_PATH}/include/kodi) | ||
| 30 | if(NOT EXISTS "${KODI_INCLUDE_DIR}/") | ||
| 31 | file(MAKE_DIRECTORY ${KODI_INCLUDE_DIR}) | ||
| 32 | endif() | ||
| 33 | |||
| 34 | # we still need XBMC_INCLUDE_DIR and XBMC_LIB_DIR for backwards compatibility to xbmc | ||
| 35 | set(XBMC_LIB_DIR ${DEPENDS_PATH}/lib/xbmc) | ||
| 36 | if(NOT EXISTS "${XBMC_LIB_DIR}/") | ||
| 37 | file(MAKE_DIRECTORY ${XBMC_LIB_DIR}) | ||
| 38 | endif() | ||
| 39 | set(XBMC_INCLUDE_DIR ${DEPENDS_PATH}/include/xbmc) | ||
| 40 | if(NOT EXISTS "${XBMC_INCLUDE_DIR}/") | ||
| 41 | file(MAKE_DIRECTORY ${XBMC_INCLUDE_DIR}) | ||
| 42 | endif() | ||
| 43 | |||
| 44 | # make sure C++11 is always set | ||
| 45 | if(NOT WIN32) | ||
| 46 | string(REGEX MATCH "-std=(gnu|c)\\+\\+11" cxx11flag "${CMAKE_CXX_FLAGS}") | ||
| 47 | if(NOT cxx11flag) | ||
| 48 | set(CXX11_SWITCH "-std=c++11") | ||
| 49 | endif() | ||
| 50 | endif() | ||
| 51 | |||
| 52 | # kodi-config.cmake.in (further down) expects a "prefix" variable | ||
| 53 | get_filename_component(prefix "${DEPENDS_PATH}" ABSOLUTE) | ||
| 54 | |||
| 55 | # generate the proper kodi-config.cmake file | ||
| 56 | configure_file(${APP_ROOT}/project/cmake/kodi-config.cmake.in ${KODI_LIB_DIR}/kodi-config.cmake @ONLY) | ||
| 57 | # copy cmake helpers to lib/kodi | ||
| 58 | file(COPY ${APP_ROOT}/project/cmake/scripts/common/addon-helpers.cmake ${APP_ROOT}/project/cmake/scripts/common/addoptions.cmake DESTINATION ${KODI_LIB_DIR}) | ||
| 59 | |||
| 60 | # generate xbmc-config.cmake for backwards compatibility to xbmc | ||
| 61 | configure_file(${APP_ROOT}/project/cmake/xbmc-config.cmake.in ${XBMC_LIB_DIR}/xbmc-config.cmake @ONLY) | ||
| 62 | |||
| 63 | ### copy all the addon binding header files to include/kodi | ||
| 64 | # parse addon-bindings.mk to get the list of header files to copy | ||
| 65 | file(STRINGS ${APP_ROOT}/xbmc/addons/addon-bindings.mk bindings) | ||
| 66 | string(REPLACE "\n" ";" bindings "${bindings}") | ||
| 67 | foreach(binding ${bindings}) | ||
| 68 | string(REPLACE " =" ";" binding "${binding}") | ||
| 69 | string(REPLACE "+=" ";" binding "${binding}") | ||
| 70 | list(GET binding 1 header) | ||
| 71 | # copy the header file to include/kodi | ||
| 72 | file(COPY ${APP_ROOT}/${header} DESTINATION ${KODI_INCLUDE_DIR}) | ||
| 73 | |||
| 74 | # auto-generate header files for backwards compatibility to xbmc with deprecation warning | ||
| 75 | # but only do it if the file doesn't already exist | ||
| 76 | get_filename_component(headerfile ${header} NAME) | ||
| 77 | if (NOT EXISTS "${XBMC_INCLUDE_DIR}/${headerfile}") | ||
| 78 | file(WRITE ${XBMC_INCLUDE_DIR}/${headerfile} | ||
| 79 | "#pragma once | ||
| 80 | #define DEPRECATION_WARNING \"Including xbmc/${headerfile} has been deprecated, please use kodi/${headerfile}\" | ||
| 81 | #ifdef _MSC_VER | ||
| 82 | #pragma message(\"WARNING: \" DEPRECATION_WARNING) | ||
| 83 | #else | ||
| 84 | #warning DEPRECATION_WARNING | ||
| 85 | #endif | ||
| 86 | #include \"kodi/${headerfile}\"") | ||
| 87 | endif() | ||
| 88 | endforeach() | ||
diff --git a/project/cmake/scripts/windows/c-flag-overrides.cmake b/project/cmake/scripts/windows/c-flag-overrides.cmake new file mode 100644 index 0000000..ab19701 --- /dev/null +++ b/project/cmake/scripts/windows/c-flag-overrides.cmake | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | if(MSVC) | ||
| 2 | set(CMAKE_C_FLAGS "/MP /DWIN32 /D_WINDOWS /W3 /Zi /arch:SSE2") | ||
| 3 | set(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /MDd /Ob0 /Od /RTC1 /D_HAS_ITERATOR_DEBUGGING=0 /D_SECURE_SCL=0") | ||
| 4 | set(CMAKE_C_FLAGS_RELEASE "/MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG") | ||
| 5 | endif(MSVC) \ No newline at end of file | ||
diff --git a/project/cmake/scripts/windows/cxx-flag-overrides.cmake b/project/cmake/scripts/windows/cxx-flag-overrides.cmake new file mode 100644 index 0000000..ad3a090 --- /dev/null +++ b/project/cmake/scripts/windows/cxx-flag-overrides.cmake | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | if(MSVC) | ||
| 2 | set(CMAKE_CXX_FLAGS "/MP /DWIN32 /D_WINDOWS /W3 /GR /Zi /EHsc /arch:SSE2") | ||
| 3 | set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob0 /Od /RTC1 /D_HAS_ITERATOR_DEBUGGING=0 /D_SECURE_SCL=0") | ||
| 4 | set(CMAKE_CXX_FLAGS_RELEASE "/MD /Ox /Ob2 /Oi /Ot /Oy /GL /DNDEBUG") | ||
| 5 | endif(MSVC) \ No newline at end of file | ||
