summaryrefslogtreecommitdiffstats
path: root/cmake/scripts/common/HandleDepends.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/scripts/common/HandleDepends.cmake')
-rw-r--r--cmake/scripts/common/HandleDepends.cmake252
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 @@
1include(${CORE_SOURCE_DIR}/cmake/scripts/common/CheckTargetPlatform.cmake)
2
3# handle addon depends
4function(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)
251endfunction()
252