1+ function (download_external_project project_name )
2+ include (CMakeParseArguments)
3+
4+ set (_dep_flags
5+ NO_UPDATE)
6+ set (_dep_one_variables
7+ URL
8+ TAG
9+ BACKEND
10+ THIRD_PARTY_DIR
11+ PATCH
12+ )
13+
14+ set (_dep_multi_variables)
15+
16+ cmake_parse_arguments (_dep_args
17+ "${_dep_flags} "
18+ "${_dep_one_variables} "
19+ "${_dep_multi_variables} "
20+ ${ARGN}
21+ )
22+
23+ if (NOT _dep_args_URL)
24+ message (FATAL_ERROR "You have to provide a URL for the project ${project_name} " )
25+ endif ()
26+
27+ if (_dep_args_BACKEND)
28+ set (_ep_backend "${_dep_args_BACKEND} _REPOSITORY \" ${_dep_args_URL} \" " )
29+ else ()
30+ set (_ep_backend "URL \" ${_dep_args_URL} \" " )
31+ if (CMAKE_VERSION VERSION_GREATER 3.23)
32+ list (APPEND _ep_backend "DOWNLOAD_EXTRACT_TIMESTAMP TRUE" )
33+ endif ()
34+ endif ()
35+
36+ if (_dep_args_TAG)
37+ set (_ep_tag "${_dep_args_BACKEND} _TAG ${_dep_args_TAG} " )
38+ endif ()
39+
40+
41+ if (NOT _dep_args_THIRD_PARTY_DIR)
42+ set (_dep_args_THIRD_PARTY_DIR deps)
43+ endif ()
44+
45+ if (_dep_args_PATCH)
46+ find_program (PATCH_EXECUTABLE patch REQUIRED)
47+ set (_patch_cmd "PATCH_COMMAND ${PATCH_EXECUTABLE} -p1 < \" ${PROJECT_SOURCE_DIR} /${_dep_args_THIRD_PARTY_DIR} /${_dep_args_PATCH} \" " )
48+ endif ()
49+
50+ set (_src_dir ${PROJECT_SOURCE_DIR} /${_dep_args_THIRD_PARTY_DIR} /${project_name} )
51+ if (EXISTS ${_src_dir} /.DOWNLOAD_SUCCESS AND _dep_args_NO_UPDATE)
52+ return ()
53+ endif ()
54+
55+ set (_working_dir ${PROJECT_BINARY_DIR} /${_dep_args_THIRD_PARTY_DIR} /${project_name} -download)
56+ set (_cmake_lists ${_working_dir} /CMakeLists.txt)
57+ file (WRITE ${_cmake_lists} "cmake_minimum_required(VERSION 3.1)\n " )
58+ file (APPEND ${_cmake_lists} "project(${project_name} -download NONE)\n " )
59+ file (APPEND ${_cmake_lists} "include(ExternalProject)\n " )
60+ file (APPEND ${_cmake_lists} "ExternalProject_Add(${project_name} \n " )
61+ file (APPEND ${_cmake_lists} " SOURCE_DIR ${_src_dir} \n " )
62+ file (APPEND ${_cmake_lists} " BINARY_DIR ${_working_dir} \n " )
63+ foreach (line ${_ep_backend} )
64+ file (APPEND ${_cmake_lists} " ${line} \n " )
65+ endforeach ()
66+ file (APPEND ${_cmake_lists} " ${_ep_tag} \n " )
67+ file (APPEND ${_cmake_lists} " CONFIGURE_COMMAND \"\"\n " )
68+ file (APPEND ${_cmake_lists} " BUILD_COMMAND \"\"\n " )
69+ file (APPEND ${_cmake_lists} " INSTALL_COMMAND \"\"\n " )
70+ file (APPEND ${_cmake_lists} " TEST_COMMAND \"\"\n " )
71+ file (APPEND ${_cmake_lists} " ${_patch_cmd} \n " )
72+ file (APPEND ${_cmake_lists} "LOG_BUILD 1)" )
73+
74+ message (STATUS "Downloading ${project_name} ${_dep_args_GIT_TAG} " )
75+ execute_process (COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR} " .
76+ RESULT_VARIABLE _result
77+ WORKING_DIRECTORY ${_working_dir}
78+ OUTPUT_FILE ${_working_dir} /download-out.log
79+ ERROR_FILE ${_working_dir} /download-error.log )
80+
81+ if (_result)
82+ message (SEND_ERROR "Something went wrong (${_result} ) during the download"
83+ " process of ${project_name} check the file"
84+ " ${_working_dir} /download-error.log for more details:" )
85+ file (STRINGS "${_working_dir} /download-error.log" _error_strings)
86+ string (REPLACE ";" "\n " _error_msg "${_error_strings} " )
87+ message (FATAL_ERROR "${_error_msg} " )
88+ endif ()
89+
90+ execute_process (COMMAND "${CMAKE_COMMAND} " --build .
91+ RESULT_VARIABLE _result
92+ WORKING_DIRECTORY ${_working_dir}
93+ OUTPUT_FILE ${_working_dir} /build -out.log
94+ ERROR_FILE ${_working_dir} /build -error.log )
95+
96+ if (_result)
97+ message ("Something went wrong (${_result} ) during the download"
98+ " process of ${project_name} check the file"
99+ " ${_working_dir} /build-error.log for more details" )
100+ file (STRINGS "${_working_dir} /build-error.log" _error_strings)
101+ string (REPLACE ";" "\n " _error_msg "${_error_strings} " )
102+ message (FATAL_ERROR "${_error_msg} " )
103+ endif ()
104+
105+ file (WRITE ${_src_dir} /.DOWNLOAD_SUCCESS "" )
106+ endfunction ()
107+
108+ # ------------------------------------------------------------------------------
109+ function (mark_as_advanced_prefix prefix )
110+ get_property (_list DIRECTORY PROPERTY VARIABLES )
111+ foreach (_var ${_list} )
112+ if ("${_var} " MATCHES "^${prefix} " )
113+ mark_as_advanced (${_var} )
114+ endif ()
115+ endforeach ()
116+ endfunction ()
117+
118+ # ------------------------------------------------------------------------------
119+ function (add_external_package package)
120+ include (CMakeParseArguments)
121+
122+ set (_aep_flags
123+ IGNORE_SYSTEM
124+ )
125+ set (_aep_one_variables
126+ VERSION
127+ THIRD_PARTY_DIR
128+ )
129+ set (_aep_multi_variables)
130+
131+ cmake_parse_arguments (_aep_args
132+ "${_aep_flags} "
133+ "${_aep_one_variables} "
134+ "${_aep_multi_variables} "
135+ ${ARGN}
136+ )
137+
138+ if (_aep_args_VERSION)
139+ set (_${package} _version ${_aep_args_VERSION} )
140+ endif ()
141+
142+ if (NOT _aep_args_THIRD_PARTY_DIR)
143+ set (_aep_args_THIRD_PARTY_DIR deps)
144+ endif ()
145+
146+ set (_cmake_includes ${PROJECT_SOURCE_DIR} /${_aep_args_THIRD_PARTY_DIR} )
147+ set (_${package} _external_dir ${PROJECT_BINARY_DIR} /${_aep_args_THIRD_PARTY_DIR} )
148+
149+
150+ if (NOT EXISTS ${_cmake_includes} /${package} .cmake)
151+ set (_required REQUIRED)
152+ endif ()
153+
154+ string (TOUPPER "${package} " u_package)
155+ if (NOT DEFINED ${PROJECT_NAME} _USE_EXTERNAL_${u_package} )
156+ set (${PROJECT_NAME} _USE_EXTERNAL_${u_package} FALSE CACHE INTERNAL "" )
157+ endif ()
158+
159+ if (NOT _aep_args_IGNORE_SYSTEM AND NOT ${PROJECT_NAME} _USE_EXTERNAL_${u_package} )
160+ find_package (${package} ${_${package} _version} ${_required} ${_aep_UNPARSED_ARGUMENTS} QUIET )
161+ if (${package} _FOUND AND NOT ${package} _FOUND_EXTERNAL)
162+ message (STATUS "Found system ${package} " )
163+ string (TOUPPER ${package} u_package)
164+ mark_as_advanced_prefix(${package} )
165+ mark_as_advanced_prefix(${u_package} )
166+ return ()
167+ endif ()
168+ endif ()
169+
170+ if (EXISTS ${_cmake_includes} /${package} .cmake)
171+ message (STATUS "Using own ${package} " )
172+ include (${_cmake_includes} /${package} .cmake)
173+ set (${PROJECT_NAME} _USE_EXTERNAL_${u_package} TRUE CACHE INTERNAL "" )
174+ endif ()
175+ string (TOUPPER ${package} u_package)
176+ mark_as_advanced_prefix(${package} )
177+ mark_as_advanced_prefix(${u_package} )
178+ endfunction ()
179+
180+ function (quote_arguments var)
181+ set (_quoted "" )
182+ foreach (_arg ${ARGN} )
183+ if (_quoted)
184+ set (_quoted "${_quoted} , \" ${_arg} \" " )
185+ else ()
186+ set (_quoted "\" ${_arg} \" " )
187+ endif ()
188+ endforeach ()
189+
190+ if (${var} )
191+ set (${var} "${${var} }, ${_quoted} " PARENT_SCOPE)
192+ else ()
193+ set (${var} "${_quoted} " PARENT_SCOPE)
194+ endif ()
195+ endfunction ()
196+
197+ # Download and update submodules with latest remote version
198+ function (download_submodule_project project_name )
199+ find_package (Git QUIET )
200+ if (NOT GIT_FOUND OR NOT EXISTS "${PROJECT_SOURCE_DIR} /.git" OR NOT EXISTS "${PROJECT_SOURCE_DIR} /deps/${project_name} /.git" )
201+ return ()
202+ endif ()
203+ message (STATUS "Update submodule ${project_name} to the latest commit" )
204+
205+ execute_process (
206+ COMMAND ${GIT_EXECUTABLE} --version
207+ OUTPUT_VARIABLE GIT_VERSION_STRING
208+ )
209+ string (REGEX MATCH "([0-9]+)\\ .([0-9]+)\\ .([0-9]+)" GIT_VERSION_STRING ${GIT_VERSION_STRING} )
210+ set (GIT_VERSION_MAJOR ${CMAKE_MATCH_1} )
211+ set (GIT_VERSION_MINOR ${CMAKE_MATCH_2} )
212+ set (GIT_VERSION_PATCH ${CMAKE_MATCH_3} )
213+
214+ if (NOT (GIT_VERSION_MAJOR GREATER 1 OR (GIT_VERSION_MAJOR EQUAL 1 AND GIT_VERSION_MINOR GREATER 8)))
215+ message (FATAL_ERROR "Git version 1.8 or greater is required." )
216+ endif ()
217+
218+ if (NOT EXISTS ${PROJECT_SOURCE_DIR} /deps/${project_name} /.git)
219+ execute_process (COMMAND ${GIT_EXECUTABLE} submodule init -- deps/${project_name}
220+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} )
221+ endif ()
222+
223+ execute_process (COMMAND ${GIT_EXECUTABLE} submodule sync -- deps/${project_name}
224+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} )
225+ execute_process (COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive --remote -- deps/${project_name}
226+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
227+ RESULT_VARIABLE GIT_SUBMOD_RESULT)
228+ if (NOT GIT_SUBMOD_RESULT EQUAL "0" )
229+ message (FATAL_ERROR "git submodule update --init --recursive --remote failed with ${GIT_SUBMOD_RESULT} , please checkout submodules" )
230+ endif ()
231+ endfunction ()
0 commit comments