2023-12-08 00:13:39 +08:00
#
# the 1k fetch functions
# require predefine variable:
# _1kfetch_cache_dir
# _1kfetch_manifest
#
2024-04-05 11:07:47 +08:00
cmake_minimum_required ( VERSION 3.23 )
2023-12-08 00:13:39 +08:00
### 1kdist url
2024-03-30 01:08:55 +08:00
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 )
2024-03-23 02:06:40 +08:00
2023-12-20 02:34:45 +08:00
function ( _1kfetch_init )
2024-03-30 01:08:55 +08:00
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 ( )
2024-04-07 23:32:28 +08:00
execute_process ( COMMAND ${ PWSH_PROG } ${ CMAKE_CURRENT_FUNCTION_LIST_DIR } /resolv-uri.ps1
2023-12-20 02:34:45 +08:00
- n a m e " 1 k d i s t "
2024-03-24 05:11:41 +08:00
- m a n i f e s t $ { _ 1 k f e t c h _ m a n i f e s t }
2023-12-20 02:34:45 +08:00
O U T P U T _ V A R I A B L E _ 1 k d i s t _ u r l
)
2024-04-03 20:25:25 +08:00
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, the _1kfetch_dist will not work" )
endif ( )
2023-12-20 02:34:45 +08:00
endfunction ( )
2023-12-08 00:13:39 +08:00
# fetch prebuilt from 1kdist
# param package_name
function ( _1kfetch_dist package_name )
2024-03-24 05:11:41 +08:00
set ( _prebuilt_root ${ CMAKE_CURRENT_LIST_DIR } /_x )
2024-04-09 02:42:25 +08:00
if ( _1KFETCH_DIST_UPGRADE AND IS_DIRECTORY ${ _prebuilt_root } )
file ( REMOVE_RECURSE ${ _prebuilt_root } )
endif ( )
2023-12-08 00:13:39 +08:00
if ( NOT IS_DIRECTORY ${ _prebuilt_root } )
2024-04-02 22:31:34 +08:00
set ( package_store "${_1kfetch_cache_dir}/1kdist/${_1kdist_ver}/${package_name}.zip" )
2023-12-08 00:13:39 +08:00
if ( NOT EXISTS ${ package_store } )
2023-12-21 23:59:24 +08:00
set ( package_url "${_1kdist_base_url}/${package_name}.zip" )
message ( AUTHOR_WARNING "Downloading ${package_url}" )
2023-12-08 00:13:39 +08:00
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 )
2024-02-06 00:32:19 +08:00
file ( REMOVE ${ package_store } )
2023-12-08 00:13:39 +08:00
message ( FATAL_ERROR "Download ${package_url} fail, ${status_string}, logs: ${_logs}" )
endif ( )
endif ( )
file ( ARCHIVE_EXTRACT INPUT ${ package_store } DESTINATION ${ CMAKE_CURRENT_LIST_DIR } / )
2024-02-06 00:32:19 +08:00
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 ( )
2023-12-08 00:13:39 +08:00
endif ( )
# set platform specific path, PLATFORM_NAME provided by user: win32,winrt,mac,ios,android,tvos,watchos,linux
2024-04-03 01:48:30 +08:00
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 ( )
2023-12-08 00:13:39 +08:00
endif ( )
set ( ${ package_name } _INC_DIR ${ _prebuilt_root } /include PARENT_SCOPE )
set ( ${ package_name } _LIB_DIR ${ _prebuilt_lib_dir } PARENT_SCOPE )
endfunction ( )
2024-03-24 05:11:41 +08:00
function ( _1kfetch uri )
2024-04-02 22:31:34 +08:00
set ( oneValueArgs NAME REV )
2024-03-23 02:06:40 +08:00
cmake_parse_arguments ( opt "" "${oneValueArgs}" "" ${ ARGN } )
2024-03-27 22:57:32 +08:00
_1kparse_name ( ${ uri } "${opt_NAME}" )
2024-04-02 22:31:34 +08:00
# rev: the explicit rev to checkout, i.e. git release tag name
set ( _pkg_rev "" )
if ( opt_REV )
set ( _pkg_rev ${ opt_REV } )
endif ( )
2024-03-27 22:57:32 +08:00
2024-03-24 05:11:41 +08:00
set ( _pkg_store "${_1kfetch_cache_dir}/${_pkg_name}" )
2024-03-30 01:08:55 +08:00
execute_process ( COMMAND ${ PWSH_PROG } ${ CMAKE_CURRENT_FUNCTION_LIST_DIR } /fetch.ps1
2024-03-24 05:11:41 +08:00
- u r i " $ { u r i } "
2024-02-16 08:57:13 +08:00
- p r e f i x " $ { _ 1 k f e t c h _ c a c h e _ d i r } "
2024-03-24 05:11:41 +08:00
- m a n i f e s t " $ { _ 1 k f e t c h _ m a n i f e s t } "
- n a m e " $ { _ p k g _ n a m e } "
2024-04-02 22:31:34 +08:00
- r e v " $ { _ p k g _ r e v } "
2023-12-21 23:59:24 +08:00
R E S U L T _ V A R I A B L E _ e r r o r c o d e
)
if ( _errorcode )
2024-03-24 05:11:41 +08:00
message ( FATAL_ERROR "fetch content ${uri} failed" )
endif ( )
set ( ${ _pkg_name } _SOURCE_DIR ${ _pkg_store } PARENT_SCOPE )
set ( source_dir ${ _pkg_store } PARENT_SCOPE )
endfunction ( )
2024-03-30 01:08:55 +08:00
# developing, not available yet
function ( _1kfetch_fast uri )
_1kperf_start ( "_1kfetch: ${uri}" )
2024-04-02 22:31:34 +08:00
set ( oneValueArgs NAME REV )
2024-03-30 01:08:55 +08:00
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 ( )
2024-03-26 00:08:53 +08:00
# simple cmake pkg management:
# for example: _1kadd_pkg("gh:yasio/yasio#4.2.1")
function ( _1kadd_pkg uri )
2024-03-24 05:11:41 +08:00
set ( optValueArgs EXCLUDE_FROM_ALL )
2024-03-27 22:57:32 +08:00
set ( oneValueArgs BINARY_DIR NAME )
2024-03-26 00:08:53 +08:00
set ( multiValueArgs OPTIONS )
cmake_parse_arguments ( opt "${optValueArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ ARGN } )
2024-03-27 22:57:32 +08:00
_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 ( )
2023-12-21 23:59:24 +08:00
endif ( )
2023-12-08 00:13:39 +08:00
endfunction ( )
2023-12-20 02:34:45 +08:00
function ( _1klink src dest )
file ( TO_NATIVE_PATH "${src}" _srcDir )
file ( TO_NATIVE_PATH "${dest}" _dstDir )
2024-03-30 01:08:55 +08:00
execute_process ( COMMAND ${ PWSH_PROG } ${ CMAKE_CURRENT_FUNCTION_LIST_DIR } /fsync.ps1 -s "${_srcDir}" -d "${_dstDir}" -l 1 )
2023-12-08 00:13:39 +08:00
endfunction ( )
2023-12-20 02:34:45 +08:00
2024-03-26 00:08:53 +08:00
function ( _1kparse_option OPTION )
2024-03-24 05:11:41 +08:00
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
" $ { O P T I O N _ K E Y } "
P A R E N T _ S C O P E
)
set ( OPTION_VALUE
" $ { O P T I O N _ V A L U E } "
P A R E N T _ S C O P E
)
endfunction ( )
2024-03-27 22:57:32 +08:00
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 ( )
2024-03-30 01:08:55 +08:00
if ( PWSH_PROG )
2024-03-24 05:11:41 +08:00
_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 ( )