mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-11-07 06:39:10 +08:00
[build] cache Xmake toolchains and reuse mobile dependencies
This commit is contained in:
@@ -5,6 +5,9 @@ inputs:
|
||||
minimum-version:
|
||||
description: Minimum supported Xmake version (major.minor.patch).
|
||||
required: true
|
||||
cache-key:
|
||||
description: Host environment identity, including the image when running in a container.
|
||||
default: host
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
@@ -16,11 +19,19 @@ runs:
|
||||
XMAKE_MIN_VERSION: ${{ inputs.minimum-version }}
|
||||
run: bash "$GITHUB_ACTION_PATH/check-version.sh"
|
||||
|
||||
- name: Identify Xmake cache environment
|
||||
if: steps.check.outputs.needs-upgrade == 'true'
|
||||
id: cache-environment
|
||||
shell: bash
|
||||
run: printf 'image=%s-%s\n' "${ImageOS:-unknown}" "${ImageVersion:-unknown}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Install or upgrade Xmake
|
||||
if: steps.check.outputs.needs-upgrade == 'true'
|
||||
uses: xmake-io/github-action-setup-xmake@v1
|
||||
with:
|
||||
xmake-version: ${{ inputs.minimum-version }}
|
||||
actions-cache-folder: ${{ runner.temp }}/crossdesk-xmake-toolchain
|
||||
actions-cache-key: crossdesk-toolchain-v1-${{ runner.os }}-${{ runner.arch }}-${{ steps.cache-environment.outputs.image }}-${{ inputs.cache-key }}
|
||||
|
||||
- name: Verify Xmake meets the minimum version
|
||||
shell: bash
|
||||
|
||||
@@ -70,6 +70,7 @@ jobs:
|
||||
java-version: "17"
|
||||
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.13"
|
||||
@@ -90,7 +91,9 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends "${crossdesk_missing_packages[@]}"
|
||||
fi
|
||||
python3 -m pip install setuptools wheel
|
||||
if ! python3 -c 'import setuptools, wheel, pip' >/dev/null 2>&1; then
|
||||
python3 -m pip install setuptools wheel
|
||||
fi
|
||||
|
||||
# Use an isolated SDK directory so the cache contains only this toolchain,
|
||||
# rather than every SDK/NDK version preinstalled on the runner.
|
||||
@@ -134,13 +137,40 @@ jobs:
|
||||
actions-cache-folder: .xmake-toolchain-cache
|
||||
actions-cache-key: ${{ runner.os }}-${{ runner.arch }}-ubuntu24.04-android-xmake${{ env.XMAKE_MIN_VERSION }}
|
||||
|
||||
# Repository selection follows desktop Xmake behavior. Keep installed
|
||||
# packages isolated; never reuse another platform's build/config.
|
||||
- name: Cache native dependencies
|
||||
uses: actions/cache@v5
|
||||
- name: Set native dependency cache key
|
||||
id: native-cache-key
|
||||
env:
|
||||
CACHE_ENVIRONMENT: ${{ runner.os }}-${{ runner.arch }}-android-arm64-native-v2-ndk28.2.13676358-api26-xmake${{ env.XMAKE_MIN_VERSION }}-python${{ steps.python.outputs.python-version }}
|
||||
RECIPE_HASH: ${{ hashFiles('apps/android/scripts/build_native.py', 'deps/submodules/minirtc/thirdparty/**') }}
|
||||
DEPENDENCY_HASH: ${{ hashFiles('apps/android/native/xmake.lua', 'deps/submodules/minirtc/xmake.lua') }}
|
||||
run: |
|
||||
prefix="${CACHE_ENVIRONMENT}-image${ImageVersion:?Missing GitHub runner image version}-${RECIPE_HASH}-"
|
||||
printf 'prefix=%s\nkey=%s%s\n' "$prefix" "$prefix" "$DEPENDENCY_HASH" >> "$GITHUB_OUTPUT"
|
||||
# Historical source_tag checkouts keep exact-only dependency reuse.
|
||||
if grep -q -- '--configure-only' apps/android/scripts/build_native.py && \
|
||||
grep -q 'package.librarydeps.strict_compatibility' apps/android/scripts/build_native.py; then
|
||||
echo 'incremental=true' >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
# Cache installed packages separately from native targets and Xmake state.
|
||||
- name: Restore native dependencies
|
||||
id: native-cache
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: apps/android/.native/packages
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-android-arm64-native-v1-${{ hashFiles('apps/android/scripts/build_native.py', 'apps/android/native/xmake.lua', 'deps/submodules/minirtc/xmake.lua', 'deps/submodules/minirtc/thirdparty/**') }}
|
||||
key: ${{ steps.native-cache-key.outputs.key }}
|
||||
restore-keys: ${{ steps.native-cache-key.outputs.incremental == 'true' && steps.native-cache-key.outputs.prefix || '' }}
|
||||
|
||||
- name: Prepare native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental == 'true'
|
||||
run: python3 -B apps/android/scripts/build_native.py --configure-only
|
||||
|
||||
- name: Save native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental == 'true' && steps.native-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: apps/android/.native/packages
|
||||
key: ${{ steps.native-cache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v6
|
||||
@@ -185,6 +215,13 @@ jobs:
|
||||
-PcrossdeskVersionCode="${ANDROID_VERSION_CODE}" \
|
||||
:app:assembleDebug :app:assembleRelease
|
||||
|
||||
- name: Save legacy native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental != 'true' && steps.native-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: apps/android/.native/packages
|
||||
key: ${{ steps.native-cache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Verify APKs
|
||||
working-directory: apps/android
|
||||
run: |
|
||||
|
||||
@@ -155,30 +155,55 @@ jobs:
|
||||
- name: Initialize submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Cache xmake dependencies
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: apps/ios/.xmake/packages
|
||||
key: "${{ runner.os }}-xmake${{ env.XMAKE_MIN_VERSION }}-deps-ios-arm64-source-v2-xcode26.6-min16-${{ hashFiles('apps/ios/scripts/build_minirtc_ios.sh', 'xmake.lua', 'deps/submodules/minirtc/xmake.lua', 'deps/submodules/minirtc/thirdparty/**') }}-${{ github.run_id }}"
|
||||
restore-keys: |
|
||||
${{ runner.os }}-xmake${{ env.XMAKE_MIN_VERSION }}-deps-ios-arm64-source-v2-xcode26.6-min16-${{ hashFiles('apps/ios/scripts/build_minirtc_ios.sh', 'xmake.lua', 'deps/submodules/minirtc/xmake.lua', 'deps/submodules/minirtc/thirdparty/**') }}-
|
||||
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.13"
|
||||
cache: pip
|
||||
cache-dependency-path: .github/workflows/build-ios.yml
|
||||
|
||||
- name: Install Python build tools
|
||||
shell: bash
|
||||
run: |
|
||||
# Xmake only accepts the host Python when all three modules exist;
|
||||
# otherwise it falls back to compiling another Python from source.
|
||||
python3 -m pip install --upgrade pip setuptools wheel
|
||||
if ! python3 -c 'import setuptools, wheel, pip' >/dev/null 2>&1; then
|
||||
python3 -m pip install setuptools wheel
|
||||
fi
|
||||
|
||||
- name: Set native dependency cache key
|
||||
id: native-cache-key
|
||||
shell: bash
|
||||
env:
|
||||
CACHE_ENVIRONMENT: ${{ runner.os }}-${{ runner.arch }}-ios-arm64-source-v3-xcode26.6-min16-xmake${{ env.XMAKE_MIN_VERSION }}-python${{ steps.python.outputs.python-version }}
|
||||
RECIPE_HASH: ${{ hashFiles('apps/ios/scripts/build_minirtc_ios.sh', 'deps/submodules/minirtc/thirdparty/**') }}
|
||||
DEPENDENCY_HASH: ${{ hashFiles('xmake.lua', 'deps/submodules/minirtc/xmake.lua') }}
|
||||
run: |
|
||||
image="${ImageVersion:?Missing GitHub runner image version}"
|
||||
prefix="${CACHE_ENVIRONMENT}-image${image}-${RECIPE_HASH}-"
|
||||
printf 'image=%s\nprefix=%s\nkey=%s%s\n' "$image" "$prefix" "$prefix" "$DEPENDENCY_HASH" >> "$GITHUB_OUTPUT"
|
||||
# Historical source_tag checkouts keep exact-only dependency reuse.
|
||||
if grep -q -- '--configure-only' apps/ios/scripts/build_minirtc_ios.sh && \
|
||||
grep -q 'package.librarydeps.strict_compatibility' apps/ios/scripts/build_minirtc_ios.sh; then
|
||||
echo 'incremental=true' >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Install xmake
|
||||
uses: xmake-io/github-action-setup-xmake@v1
|
||||
with:
|
||||
xmake-version: "${{ env.XMAKE_MIN_VERSION }}"
|
||||
actions-cache-folder: ${{ runner.temp }}/crossdesk-ios-xmake-toolchain
|
||||
actions-cache-key: ios-toolchain-v1-${{ runner.os }}-${{ runner.arch }}-image${{ steps.native-cache-key.outputs.image }}-xcode26.6
|
||||
|
||||
# Keep recipe/patch and toolchain changes outside the fallback boundary.
|
||||
- name: Restore native dependencies
|
||||
id: native-cache
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: apps/ios/.xmake/packages
|
||||
key: ${{ steps.native-cache-key.outputs.key }}
|
||||
restore-keys: ${{ steps.native-cache-key.outputs.incremental == 'true' && steps.native-cache-key.outputs.prefix || '' }}
|
||||
|
||||
- name: Verify minimum xmake version
|
||||
shell: bash
|
||||
@@ -187,6 +212,24 @@ jobs:
|
||||
python3 -B apps/ios/scripts/verify_native_build.py \
|
||||
--xmake-version "${RUNNER_TEMP}/xmake-version.txt"
|
||||
|
||||
- name: Prepare native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental == 'true'
|
||||
timeout-minutes: 60
|
||||
shell: bash
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
PLATFORM_NAME: iphoneos
|
||||
CURRENT_ARCH: arm64
|
||||
CROSSDESK_NATIVE_VERBOSE: "1"
|
||||
run: apps/ios/scripts/build_minirtc_ios.sh --configure-only
|
||||
|
||||
- name: Save native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental == 'true' && steps.native-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: apps/ios/.xmake/packages
|
||||
key: ${{ steps.native-cache.outputs.cache-primary-key }}
|
||||
|
||||
# Xcode buffers Run Script output until the phase finishes. Build the
|
||||
# native archives here so dependency downloads and compiler commands are
|
||||
# streamed to Actions; the Xcode phase then reuses the same build products.
|
||||
@@ -216,6 +259,13 @@ jobs:
|
||||
apps/ios/scripts/build_minirtc_ios.sh 2>&1 | \
|
||||
tee "${RUNNER_TEMP}/ios-native-build.log"
|
||||
|
||||
- name: Save legacy native dependencies
|
||||
if: steps.native-cache-key.outputs.incremental != 'true' && steps.native-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: apps/ios/.xmake/packages
|
||||
key: ${{ steps.native-cache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Build CrossDesk Mobile
|
||||
timeout-minutes: 30
|
||||
shell: bash
|
||||
|
||||
@@ -132,6 +132,7 @@ jobs:
|
||||
uses: ./.github/actions/ensure-xmake
|
||||
with:
|
||||
minimum-version: ${{ env.XMAKE_MIN_VERSION }}
|
||||
cache-key: ${{ matrix.image }}
|
||||
|
||||
- name: Verify Linux build image
|
||||
shell: bash
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the native controller in isolation from desktop and iOS caches."""
|
||||
import argparse
|
||||
import fcntl
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -26,7 +27,7 @@ def find_xmake():
|
||||
return xmake
|
||||
|
||||
|
||||
def main():
|
||||
def main(configure_only=False):
|
||||
sdk = Path(os.environ.get('ANDROID_HOME') or os.environ.get('ANDROID_SDK_ROOT')
|
||||
or Path.home() / 'Library/Android/sdk')
|
||||
ndk = sdk / 'ndk/28.2.13676358'
|
||||
@@ -45,13 +46,20 @@ def main():
|
||||
# and updates. Only installed Android packages/build products are isolated.
|
||||
subprocess.run([xmake, 'f', '-P', str(work), '-y', '-p', 'android', '-a', 'arm64-v8a',
|
||||
'-m', 'release', '--ndk=' + str(ndk), '--ndk_sdkver=26',
|
||||
'--runtimes=c++_static', '--policies=package.precompiled:n',
|
||||
'--runtimes=c++_static',
|
||||
'--policies=package.precompiled:n,package.librarydeps.strict_compatibility',
|
||||
'-o', str(CACHE / 'build')], cwd=work, env=env, check=True)
|
||||
if configure_only:
|
||||
return
|
||||
subprocess.run([xmake, '-P', str(work), '-y', 'crossdesk_android'], cwd=work, env=env, check=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--configure-only', action='store_true',
|
||||
help='Install native dependencies before compiling application targets.')
|
||||
args = parser.parse_args()
|
||||
CACHE.mkdir(parents=True, exist_ok=True)
|
||||
with (CACHE / 'build.lock').open('w') as lock:
|
||||
fcntl.flock(lock, fcntl.LOCK_EX)
|
||||
main()
|
||||
main(configure_only=args.configure_only)
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CONFIGURE_ONLY=false
|
||||
if [[ $# -eq 1 && "$1" == "--configure-only" ]]; then
|
||||
CONFIGURE_ONLY=true
|
||||
elif [[ $# -ne 0 ]]; then
|
||||
print -u2 "Usage: $0 [--configure-only]"
|
||||
exit 64
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="${0:A:h}"
|
||||
IOS_DIR="${SCRIPT_DIR:h}"
|
||||
REPO_DIR="${IOS_DIR:h:h}"
|
||||
@@ -169,7 +177,7 @@ configure_xmake() {
|
||||
print "Configuring iOS native project: ${project_dir}"
|
||||
run_xmake f -P "${project_dir}" "${clean_flags[@]}" "${XMAKE_LOG_FLAGS[@]}" -o "${build_dir}" \
|
||||
-p iphoneos -a arm64 --appledev="${APPLE_DEVICE}" -m "${MODE}" --target_minver=16.0 \
|
||||
--policies=package.precompiled:n -y "$@"
|
||||
--policies=package.precompiled:n,package.librarydeps.strict_compatibility -y "$@"
|
||||
mkdir -p "${build_dir}"
|
||||
print -r -- "${CONFIG_SIGNATURE}" > "${stamp}"
|
||||
}
|
||||
@@ -182,6 +190,24 @@ configure_xmake() {
|
||||
configure_xmake "${MINIRTC_DIR}" "${MINIRTC_BUILD_DIR}" \
|
||||
--as="${XMAKE_TOOLCHAIN_BIN}/clang" --USE_CUDA=false \
|
||||
--MINIRTC_ENABLE_AOM="${MINIRTC_ENABLE_AOM}"
|
||||
)
|
||||
|
||||
# Build the platform-independent wire archive from the root project's target.
|
||||
# The copied manifest only isolates Xmake's generated configuration; there is
|
||||
# no second project definition to maintain.
|
||||
(
|
||||
cd "${WIRE_WORK_DIR}"
|
||||
configure_xmake "${WIRE_WORK_DIR}" "${WIRE_BUILD_DIR}" \
|
||||
--CROSSDESK_BUILD_DESKTOP=false --CROSSDESK_BUILD_CLI=false
|
||||
)
|
||||
|
||||
# CI can persist the installed packages before compiling either archive.
|
||||
if [[ "${CONFIGURE_ONLY}" == true ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
(
|
||||
cd "${MINIRTC_DIR}"
|
||||
print "Building MiniRTC for ${SDK_NAME} (${MODE})"
|
||||
run_xmake b -P "${MINIRTC_DIR}" "${XMAKE_LOG_FLAGS[@]}" minirtc
|
||||
)
|
||||
@@ -191,13 +217,8 @@ if [[ ! -f "${MINIRTC_LIBRARY}" ]]; then
|
||||
exit 66
|
||||
fi
|
||||
|
||||
# Build the platform-independent wire archive from the root project's target.
|
||||
# The copied manifest only isolates Xmake's generated configuration; there is
|
||||
# no second project definition to maintain.
|
||||
(
|
||||
cd "${WIRE_WORK_DIR}"
|
||||
configure_xmake "${WIRE_WORK_DIR}" "${WIRE_BUILD_DIR}" \
|
||||
--CROSSDESK_BUILD_DESKTOP=false --CROSSDESK_BUILD_CLI=false
|
||||
print "Building CrossDesk wire for ${SDK_NAME} (${MODE})"
|
||||
run_xmake b -P "${WIRE_WORK_DIR}" "${XMAKE_LOG_FLAGS[@]}" crossdesk_wire
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user