diff options
Diffstat (limited to 'cmake/scripts/common/HandleDepends.cmake')
| -rw-r--r-- | cmake/scripts/common/HandleDepends.cmake | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/cmake/scripts/common/HandleDepends.cmake b/cmake/scripts/common/HandleDepends.cmake new file mode 100644 index 0000000..85d2cf4 --- /dev/null +++ b/cmake/scripts/common/HandleDepends.cmake | |||
| @@ -0,0 +1,252 @@ | |||
| 1 | include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake) | ||
| 2 | |||
| 3 | # handle addon depends | ||
| 4 | function(add_addon_depends addon searchpath) | ||
| 5 | # input: string addon string searchpath | ||
| 6 | |||
| 7 | set(OUTPUT_DIR ${ADDON_DEPENDS_PATH}) | ||
| 8 | # look for platform-specific dependencies | ||
| 9 | file(GLOB_RECURSE cmake_input_files ${searchpath}/${CORE_SYSTEM_NAME}/*.txt) | ||
| 10 | file(GLOB_RECURSE cmake_input_files2 ${searchpath}/common/*.txt) | ||
| 11 | list(APPEND cmake_input_files ${cmake_input_files2}) | ||
| 12 | |||
| 13 | foreach(file ${cmake_input_files}) | ||
| 14 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${file}) | ||
| 15 | if(NOT (file MATCHES CMakeLists.txt OR | ||
| 16 | file MATCHES install.txt OR | ||
| 17 | file MATCHES noinstall.txt OR | ||
| 18 | file MATCHES flags.txt OR | ||
| 19 | file MATCHES deps.txt OR | ||
| 20 | file MATCHES "[a-z]+-deps[.]txt" OR | ||
| 21 | file MATCHES platforms.txt)) | ||
| 22 | message(STATUS "Processing ${file}") | ||
| 23 | file(STRINGS ${file} def) | ||
| 24 | string(REPLACE " " ";" def ${def}) | ||
| 25 | list(LENGTH def deflength) | ||
| 26 | get_filename_component(dir ${file} DIRECTORY) | ||
| 27 | |||
| 28 | # get the id of the dependency | ||
| 29 | if(NOT "${def}" STREQUAL "") | ||
| 30 | # read the id from the file | ||
| 31 | list(GET def 0 id) | ||
| 32 | else() | ||
| 33 | # read the id from the filename | ||
| 34 | get_filename_component(id ${file} NAME_WE) | ||
| 35 | endif() | ||
| 36 | |||
| 37 | # check if the dependency has a platforms.txt | ||
| 38 | set(platform_found FALSE) | ||
| 39 | check_target_platform(${dir} ${CORE_SYSTEM_NAME} platform_found) | ||
| 40 | |||
| 41 | if(${platform_found} AND NOT TARGET ${id}) | ||
| 42 | # determine the download URL of the dependency | ||
| 43 | set(url "") | ||
| 44 | if(deflength GREATER 1) | ||
| 45 | list(GET def 1 url) | ||
| 46 | message(STATUS "${id} url: ${url}") | ||
| 47 | endif() | ||
| 48 | |||
| 49 | # check if there are any library specific flags that need to be passed on | ||
| 50 | if(EXISTS ${dir}/flags.txt) | ||
| 51 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/flags.txt) | ||
| 52 | file(STRINGS ${dir}/flags.txt extraflags) | ||
| 53 | |||
| 54 | # replace some custom placeholders | ||
| 55 | string(REPLACE "@MINGW_TOOLCHAIN_FILE@" "${OUTPUT_DIR}/Toolchain_mingw32.cmake" extraflags "${extraflags}") | ||
| 56 | string(REPLACE " " ";" extraflags ${extraflags}) | ||
| 57 | |||
| 58 | message(STATUS "${id} extraflags: ${extraflags}") | ||
| 59 | endif() | ||
| 60 | |||
| 61 | set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} | ||
| 62 | -DOUTPUT_DIR=${OUTPUT_DIR} | ||
| 63 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | ||
| 64 | -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE} | ||
| 65 | -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX} | ||
| 66 | -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} | ||
| 67 | -DCORE_SYSTEM_NAME=${CORE_SYSTEM_NAME} | ||
| 68 | -DENABLE_STATIC=1 | ||
| 69 | -DBUILD_SHARED_LIBS=0) | ||
| 70 | # if there are no make rules override files available take care of manually passing on ARCH_DEFINES | ||
| 71 | if(NOT CMAKE_USER_MAKE_RULES_OVERRIDE AND NOT CMAKE_USER_MAKE_RULES_OVERRIDE_CXX) | ||
| 72 | # make sure we create strings, not lists | ||
| 73 | set(TMP_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_DEFINES}") | ||
| 74 | set(TMP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_DEFINES}") | ||
| 75 | list(APPEND BUILD_ARGS -DCMAKE_C_FLAGS=${TMP_C_FLAGS} | ||
| 76 | -DCMAKE_CXX_FLAGS=${TMP_CXX_FLAGS}) | ||
| 77 | endif() | ||
| 78 | |||
| 79 | if(CMAKE_TOOLCHAIN_FILE) | ||
| 80 | list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) | ||
| 81 | message("toolchain specified") | ||
| 82 | message(${BUILD_ARGS}) | ||
| 83 | endif() | ||
| 84 | |||
| 85 | # prepare patchfile. ensure we have a clean file after reconfiguring | ||
| 86 | set(PATCH_FILE ${BUILD_DIR}/${id}/tmp/patch.cmake) | ||
| 87 | file(REMOVE ${PATCH_FILE}) | ||
| 88 | |||
| 89 | # if there's a CMakeLists.txt use it to prepare the build | ||
| 90 | if(EXISTS ${dir}/CMakeLists.txt) | ||
| 91 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/CMakeLists.txt) | ||
| 92 | file(APPEND ${PATCH_FILE} | ||
| 93 | "file(COPY ${dir}/CMakeLists.txt | ||
| 94 | DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") | ||
| 95 | endif() | ||
| 96 | |||
| 97 | # check if we have patches to apply | ||
| 98 | file(GLOB patches ${dir}/*.patch) | ||
| 99 | list(SORT patches) | ||
| 100 | foreach(patch ${patches}) | ||
| 101 | if(NOT PATCH_PROGRAM OR "${PATCH_PROGRAM}" STREQUAL "") | ||
| 102 | if(NOT PATCH_EXECUTABLE) | ||
| 103 | # find the path to the patch executable | ||
| 104 | find_program(PATCH_EXECUTABLE NAMES patch) | ||
| 105 | |||
| 106 | if(NOT PATCH_EXECUTABLE) | ||
| 107 | message(FATAL_ERROR "Missing patch command (we looked in ${CMAKE_PREFIX_PATH})") | ||
| 108 | endif() | ||
| 109 | endif() | ||
| 110 | |||
| 111 | set(PATCH_PROGRAM ${PATCH_EXECUTABLE}) | ||
| 112 | |||
| 113 | # On Windows "patch.exe" can only handle CR-LF line-endings. | ||
| 114 | # Our patches have LF-only line endings - except when they | ||
| 115 | # have been checked out as part of a dependency hosted on Git | ||
| 116 | # and core.autocrlf=true. | ||
| 117 | if(WIN32) | ||
| 118 | file(READ ${patch} patch_content_hex HEX) | ||
| 119 | # Force handle LF-only line endings | ||
| 120 | if(NOT patch_content_hex MATCHES "0d0a") | ||
| 121 | set(PATCH_PROGRAM "\"${PATCH_PROGRAM}\" --binary") | ||
| 122 | endif() | ||
| 123 | endif() | ||
| 124 | endif() | ||
| 125 | |||
| 126 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${patch}) | ||
| 127 | file(APPEND ${PATCH_FILE} | ||
| 128 | "execute_process(COMMAND ${PATCH_PROGRAM} -p1 -i \"${patch}\")\n") | ||
| 129 | endforeach() | ||
| 130 | |||
| 131 | |||
| 132 | # if there's an install.txt use it to properly install the built files | ||
| 133 | set(INSTALL_COMMAND "") | ||
| 134 | if(EXISTS ${dir}/install.txt) | ||
| 135 | set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND} | ||
| 136 | -DINPUTDIR=${BUILD_DIR}/${id}/src/${id}-build/ | ||
| 137 | -DINPUTFILE=${dir}/install.txt | ||
| 138 | -DDESTDIR=${OUTPUT_DIR} | ||
| 139 | -DENABLE_STATIC=1 | ||
| 140 | "${extraflags}" | ||
| 141 | -P ${PROJECT_SOURCE_DIR}/install.cmake) | ||
| 142 | elseif(EXISTS ${dir}/noinstall.txt) | ||
| 143 | set(INSTALL_COMMAND INSTALL_COMMAND "") | ||
| 144 | endif() | ||
| 145 | |||
| 146 | # check if there's a platform-specific or generic deps.txt containing dependencies on other libraries | ||
| 147 | if(EXISTS ${dir}/${CORE_SYSTEM_NAME}-deps.txt) | ||
| 148 | file(STRINGS ${dir}/${CORE_SYSTEM_NAME}-deps.txt deps) | ||
| 149 | message(STATUS "${id} depends: ${deps}") | ||
| 150 | elseif(EXISTS ${dir}/deps.txt) | ||
| 151 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/deps.txt) | ||
| 152 | file(STRINGS ${dir}/deps.txt deps) | ||
| 153 | message(STATUS "${id} depends: ${deps}") | ||
| 154 | else() | ||
| 155 | set(deps) | ||
| 156 | endif() | ||
| 157 | |||
| 158 | if(CROSS_AUTOCONF AND AUTOCONF_FILES) | ||
| 159 | foreach(afile ${AUTOCONF_FILES}) | ||
| 160 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${afile}) | ||
| 161 | file(APPEND ${PATCH_FILE} | ||
| 162 | "message(STATUS \"AUTOCONF: copying ${afile} to ${BUILD_DIR}/${id}/src/${id}\")\n | ||
| 163 | file(COPY ${afile} DESTINATION ${BUILD_DIR}/${id}/src/${id})\n") | ||
| 164 | endforeach() | ||
| 165 | endif() | ||
| 166 | |||
| 167 | # if the patch file exists we need to set the PATCH_COMMAND | ||
| 168 | set(PATCH_COMMAND "") | ||
| 169 | if(EXISTS ${PATCH_FILE}) | ||
| 170 | set(PATCH_COMMAND ${CMAKE_COMMAND} -P ${PATCH_FILE}) | ||
| 171 | endif() | ||
| 172 | |||
| 173 | # prepare the setup of the call to externalproject_add() | ||
| 174 | set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id} | ||
| 175 | CMAKE_ARGS ${extraflags} ${BUILD_ARGS} | ||
| 176 | PATCH_COMMAND ${PATCH_COMMAND} | ||
| 177 | "${INSTALL_COMMAND}") | ||
| 178 | |||
| 179 | if(CMAKE_VERSION VERSION_GREATER 3.5.9) | ||
| 180 | list(APPEND EXTERNALPROJECT_SETUP GIT_SHALLOW 1) | ||
| 181 | endif() | ||
| 182 | |||
| 183 | # if there's an url defined we need to pass that to externalproject_add() | ||
| 184 | if(DEFINED url AND NOT "${url}" STREQUAL "") | ||
| 185 | # check if there's a third parameter in the file | ||
| 186 | if(deflength GREATER 2) | ||
| 187 | # the third parameter is considered as a revision of a git repository | ||
| 188 | list(GET def 2 revision) | ||
| 189 | |||
| 190 | externalproject_add(${id} | ||
| 191 | GIT_REPOSITORY ${url} | ||
| 192 | GIT_TAG ${revision} | ||
| 193 | "${EXTERNALPROJECT_SETUP}") | ||
| 194 | |||
| 195 | # For patchfiles to work, disable (users globally set) autocrlf=true | ||
| 196 | if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER 3.7) | ||
| 197 | message(AUTHOR_WARNING "Make use of GIT_CONFIG") | ||
| 198 | endif() | ||
| 199 | if(WIN32 AND patches) | ||
| 200 | externalproject_add_step(${id} gitconfig | ||
| 201 | COMMAND git config core.autocrlf false | ||
| 202 | COMMAND git rm -rf --cached . | ||
| 203 | COMMAND git reset --hard HEAD | ||
| 204 | COMMENT "Performing gitconfig step: Disabling autocrlf to enable patching for '${id}'" | ||
| 205 | DEPENDERS patch | ||
| 206 | WORKING_DIRECTORY <SOURCE_DIR>) | ||
| 207 | endif() | ||
| 208 | else() | ||
| 209 | set(CONFIGURE_COMMAND "") | ||
| 210 | if(NOT WIN32) | ||
| 211 | # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH | ||
| 212 | set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig | ||
| 213 | ${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags} ${BUILD_ARGS} | ||
| 214 | ${BUILD_DIR}/${id}/src/${id} | ||
| 215 | -DPACKAGE_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig | ||
| 216 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | ||
| 217 | -DOUTPUT_DIR=${OUTPUT_DIR} | ||
| 218 | -DCMAKE_PREFIX_PATH=${OUTPUT_DIR} | ||
| 219 | -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR} | ||
| 220 | -DCMAKE_EXE_LINKER_FLAGS=-L${OUTPUT_DIR}/lib | ||
| 221 | -DCMAKE_INCLUDE_PATH=${OUTPUT_DIR}/include) | ||
| 222 | endif() | ||
| 223 | |||
| 224 | externalproject_add(${id} | ||
| 225 | URL ${url} | ||
| 226 | DOWNLOAD_DIR ${BUILD_DIR}/download | ||
| 227 | CONFIGURE_COMMAND ${CONFIGURE_COMMAND} | ||
| 228 | "${EXTERNALPROJECT_SETUP}") | ||
| 229 | endif() | ||
| 230 | else() | ||
| 231 | externalproject_add(${id} | ||
| 232 | SOURCE_DIR ${dir} | ||
| 233 | "${EXTERNALPROJECT_SETUP}") | ||
| 234 | endif() | ||
| 235 | |||
| 236 | if(deps) | ||
| 237 | add_dependencies(${id} ${deps}) | ||
| 238 | endif() | ||
| 239 | endif() | ||
| 240 | |||
| 241 | # if the dependency is available for the target platform add it to the list of the addon's dependencies | ||
| 242 | # (even if the target already exists as it still has to be built before the addon) | ||
| 243 | if(${platform_found}) | ||
| 244 | list(APPEND ${addon}_DEPS ${id}) | ||
| 245 | endif() | ||
| 246 | endif() | ||
| 247 | endforeach() | ||
| 248 | |||
| 249 | # make the ${addon}_DEPS variable available to the calling script | ||
| 250 | set(${addon}_DEPS "${${addon}_DEPS}" PARENT_SCOPE) | ||
| 251 | endfunction() | ||
| 252 | |||
