forked from axmolengine/axmol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfetch.cmake
257 lines (221 loc) · 9.5 KB
/
fetch.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#
# the 1k fetch functions
# require predefine variable:
# _1kfetch_cache_dir
# _1kfetch_manifest
#
cmake_minimum_required(VERSION 3.23)
### 1kdist url
find_program(PWSH_PROG NAMES pwsh powershell NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
find_program(GIT_PROG NAMES git NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
function(_1kfetch_init)
if(NOT _1kfetch_cache_dir)
file(REAL_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../cache" _1kfetch_cache_dir)
set(_1kfetch_cache_dir "${_1kfetch_cache_dir}" CACHE STRING "" FORCE)
endif()
if(NOT _1kfetch_manifest)
file(REAL_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../manifest.json" _1kfetch_manifest)
set(_1kfetch_manifest "${_1kfetch_manifest}" CACHE STRING "" FORCE)
endif()
if(NOT EXISTS ${PWSH_PROG}) # try again
unset(PWSH_PROG CACHE)
find_program(PWSH_PROG NAMES pwsh powershell NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
endif()
execute_process(COMMAND ${PWSH_PROG} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/resolv-url.ps1
-name "1kdist"
-manifest ${_1kfetch_manifest}
OUTPUT_VARIABLE _1kdist_url
RESULT_VARIABLE _1kdist_error
)
if(_1kdist_url)
string(REPLACE "#" ";" _1kdist_url ${_1kdist_url})
list(GET _1kdist_url 0 _1kdist_base_url)
list(GET _1kdist_url 1 _1kdist_ver)
set(_1kdist_base_url "${_1kdist_base_url}/${_1kdist_ver}" PARENT_SCOPE)
set(_1kdist_ver ${_1kdist_ver} PARENT_SCOPE)
else()
message(WARNING "Resolve 1kdist uri fail, ${_1kdist_error}, the _1kfetch_dist will not work")
endif()
endfunction()
# fetch prebuilt from 1kdist
# param package_name
function(_1kfetch_dist package_name)
set(_prebuilt_root ${CMAKE_CURRENT_LIST_DIR}/_x)
if(_1KFETCH_UPGRADE AND IS_DIRECTORY ${_prebuilt_root})
file(REMOVE_RECURSE ${_prebuilt_root})
endif()
if(NOT IS_DIRECTORY ${_prebuilt_root})
set (package_store "${_1kfetch_cache_dir}/1kdist/${_1kdist_ver}/${package_name}.zip")
if (NOT EXISTS ${package_store})
set (package_url "${_1kdist_base_url}/${package_name}.zip")
message(AUTHOR_WARNING "Downloading ${package_url}")
file(DOWNLOAD ${package_url} ${package_store} STATUS _status LOG _logs SHOW_PROGRESS)
list(GET _status 0 status_code)
list(GET _status 1 status_string)
if(NOT status_code EQUAL 0)
file(REMOVE ${package_store})
message(FATAL_ERROR "Download ${package_url} fail, ${status_string}, logs: ${_logs}")
endif()
endif()
file(ARCHIVE_EXTRACT INPUT ${package_store} DESTINATION ${CMAKE_CURRENT_LIST_DIR}/)
if (IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/${package_name})
file(RENAME ${CMAKE_CURRENT_LIST_DIR}/${package_name} ${_prebuilt_root})
else() # download may fail
file(REMOVE ${package_store})
message(FATAL_ERROR "The package ${package_store} is malformed, please try again!")
endif()
endif()
# set platform specific path, PLATFORM_NAME provided by user: win32,winrt,mac,ios,android,tvos,watchos,linux
if(APPLE) # since 1kiss_dist v80+, xcframework don't require platform spec sub folder
set(_prebuilt_lib_dir "${_prebuilt_root}/lib")
else()
set(_prebuilt_lib_dir "${_prebuilt_root}/lib/${PLATFORM_NAME}")
if(ANDROID OR WIN32)
set(_prebuilt_lib_dir "${_prebuilt_lib_dir}/${ARCH_ALIAS}")
endif()
endif()
set(${package_name}_INC_DIR ${_prebuilt_root}/include PARENT_SCOPE)
set(${package_name}_LIB_DIR ${_prebuilt_lib_dir} PARENT_SCOPE)
endfunction()
function(_1kfetch uri)
set(oneValueArgs NAME REV)
cmake_parse_arguments(opt "" "${oneValueArgs}" "" ${ARGN})
_1kparse_name(${uri} "${opt_NAME}")
set(_pkg_store "${_1kfetch_cache_dir}/${_pkg_name}")
get_property(_fetched GLOBAL PROPERTY "${_pkg_name}_fetched")
if (NOT _fetched)
set(_fetch_args
-uri "${uri}"
-prefix "${_1kfetch_cache_dir}"
-manifest "${_1kfetch_manifest}"
-name "${_pkg_name}"
)
# rev: the explicit rev to checkout, i.e. git release tag name
if(opt_REV)
list(APPEND _fetch_args -rev ${opt_REV})
endif()
if(_1KFETCH_UPGRADE)
list(APPEND _fetch_args -pull_branch)
endif()
execute_process(COMMAND ${PWSH_PROG} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/fetch.ps1
${_fetch_args}
RESULT_VARIABLE _errorcode
)
if (_errorcode)
message(FATAL_ERROR "fetch content ${uri} failed")
endif()
set_property(GLOBAL PROPERTY "${_pkg_name}_fetched" TRUE)
endif()
set(${_pkg_name}_SOURCE_DIR ${_pkg_store} PARENT_SCOPE)
set(source_dir ${_pkg_store} PARENT_SCOPE)
endfunction()
# developing, not available yet
function(_1kfetch_fast uri)
_1kperf_start("_1kfetch: ${uri}")
set(oneValueArgs NAME REV)
cmake_parse_arguments(opt "" "${oneValueArgs}" "" ${ARGN})
_1kparse_name(${uri} "${opt_NAME}")
set(_pkg_store "${_1kfetch_cache_dir}/${_pkg_name}")
set(_sentry_file "${_pkg_store}/_1kiss")
if(NOT _manifest_conf)
file(READ "${_1kfetch_manifest}" _manifest_conf)
endif()
string(JSON _url GET "${_manifest_conf}" "mirrors" "github" "${_pkg_name}")
string(JSON _version GET "${_manifest_conf}" "versions" "${_pkg_name}")
string(PREPEND _url "https://github.com/")
if(NOT EXISTS "${_sentry_file}")
execute_process(COMMAND ${GIT_PROG} clone --progress ${_url} "${_pkg_store}" RESULT_VARIABLE _errorcode)
file(WRITE "${_sentry_file}" "ver: ${_version}")
endif()
if(EXISTS "${_sentry_file}")
execute_process(COMMAND ${GIT_PROG} -C ${_pkg_store} checkout ${_version} RESULT_VARIABLE _errorcode)
if(_errorcode)
execute_process(COMMAND ${GIT_PROG} -C ${_pkg_store} checkout v${_version} RESULT_VARIABLE _errorcode)
endif()
else()
message(FATAL_ERROR "fetch repo ${uri} fail, try again")
endif()
set(${_pkg_name}_SOURCE_DIR ${_pkg_store} PARENT_SCOPE)
set(source_dir ${_pkg_store} PARENT_SCOPE)
_1kperf_end("_1kfetch")
endfunction()
# simple cmake pkg management:
# for example: _1kadd_pkg("gh:yasio/yasio#4.2.1")
function(_1kadd_pkg uri)
set(optValueArgs EXCLUDE_FROM_ALL)
set(oneValueArgs BINARY_DIR NAME)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(opt "${optValueArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
_1kparse_name(${uri} "${opt_NAME}")
if(NOT TARGET ${_pkg_name})
_1kfetch(${uri} ${ARGN} NAME ${_pkg_name})
foreach(OPTION ${opt_OPTIONS})
_1kparse_option("${OPTION}")
set(${OPTION_KEY} "${OPTION_VALUE}" CACHE BOOL "" FORCE)
endforeach()
if(opt_BINARY_DIR)
set(binary_dir "${opt_BINARY_DIR}/${_pkg_name}")
else()
set(binary_dir "${CMAKE_BINARY_DIR}/1kiss/${_pkg_name}")
endif()
if (opt_EXCLUDE_FROM_ALL)
add_subdirectory(${source_dir} ${binary_dir} EXCLUDE_FROM_ALL)
else()
add_subdirectory(${source_dir} ${binary_dir})
endif()
endif()
endfunction()
function(_1klink src dest)
file(TO_NATIVE_PATH "${src}" _srcDir)
file(TO_NATIVE_PATH "${dest}" _dstDir)
execute_process(COMMAND ${PWSH_PROG} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/fsync.ps1 -s "${_srcDir}" -d "${_dstDir}" -l 1)
endfunction()
function(_1kparse_option OPTION)
string(REGEX MATCH "^[^ ]+" OPTION_KEY "${OPTION}")
string(LENGTH "${OPTION}" OPTION_LENGTH)
string(LENGTH "${OPTION_KEY}" OPTION_KEY_LENGTH)
if(OPTION_KEY_LENGTH STREQUAL OPTION_LENGTH)
# no value for key provided, assume user wants to set option to "ON"
set(OPTION_VALUE "ON")
else()
math(EXPR OPTION_KEY_LENGTH "${OPTION_KEY_LENGTH}+1")
string(SUBSTRING "${OPTION}" "${OPTION_KEY_LENGTH}" "-1" OPTION_VALUE)
endif()
set(OPTION_KEY
"${OPTION_KEY}"
PARENT_SCOPE
)
set(OPTION_VALUE
"${OPTION_VALUE}"
PARENT_SCOPE
)
endfunction()
macro(_1kparse_name uri opt_NAME)
if(opt_NAME)
set(_pkg_name ${opt_NAME})
else()
set(_trimmed_uri "")
# parse pkg name for pkg_store due to we can't get from execute_process properly
string(REGEX REPLACE "#.*" "" _trimmed_uri "${uri}")
get_filename_component(_pkg_name ${_trimmed_uri} NAME_WE)
set(_pkg_name ${_pkg_name})
endif()
endmacro()
macro(_1kperf_start tag)
string(TIMESTAMP _current_sec "%s" UTC)
string(TIMESTAMP _current_usec "%f" UTC)
math(EXPR _fetch_start_msec "${_current_sec} * 1000 + ${_current_usec} / 1000" OUTPUT_FORMAT DECIMAL)
message(STATUS "[${_fetch_start_msec}ms][1kperf] start of ${tag} ..." )
endmacro()
macro(_1kperf_end tag)
string(TIMESTAMP _current_sec "%s" UTC)
string(TIMESTAMP _current_usec "%f" UTC)
math(EXPR _fetch_end_msec "${_current_sec} * 1000 + ${_current_usec} / 1000" OUTPUT_FORMAT DECIMAL)
math(EXPR _fetch_cost_msec "${_fetch_end_msec} - ${_fetch_start_msec}")
message(STATUS "[${_fetch_end_msec}ms][1kperf] end of ${tag}, cost: ${_fetch_cost_msec}ms" )
endmacro()
if(PWSH_PROG)
_1kfetch_init()
else()
message(WARNING "fetch.cmake: PowerShell is missing, the fetch functions not work, please install from https://github.com/PowerShell/PowerShell/releases")
endif()