From f63480b5c2d4f79d62217bc4eaf8cb5fab376085 Mon Sep 17 00:00:00 2001 From: luochen570 <1160510664@qq.com> Date: Fri, 29 May 2026 23:41:51 +0800 Subject: [PATCH] ci: cross build Windows release on Linux --- .../workflows/build-windows-cross-linux.yml | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 .gitea/workflows/build-windows-cross-linux.yml diff --git a/.gitea/workflows/build-windows-cross-linux.yml b/.gitea/workflows/build-windows-cross-linux.yml new file mode 100644 index 0000000..3052cc3 --- /dev/null +++ b/.gitea/workflows/build-windows-cross-linux.yml @@ -0,0 +1,116 @@ +name: Cross Build Windows Release on Linux + +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + cross-build-windows: + # Gitea act_runner 常见 Linux 标签;该工作流在 Linux Runner 中交叉编译 Windows x86_64 包。 + runs-on: ubuntu-latest + container: + image: fedora:41 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install cross build dependencies + run: | + set -euo pipefail + dnf install -y \ + git \ + cmake \ + ninja-build \ + p7zip \ + p7zip-plugins \ + mingw64-gcc-c++ \ + mingw64-qt6-qtbase \ + mingw64-qt6-qtbase-devel \ + mingw64-opencv \ + mingw64-opencv-devel + + - name: Configure + run: | + set -euo pipefail + cmake -S . -B build-windows-cross -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-mingw64.cmake + + - name: Build + run: | + set -euo pipefail + cmake --build build-windows-cross --parallel "$(nproc)" + + - name: Package + run: | + set -euo pipefail + APP_NAME="chengnan" + PACKAGE_NAME="chengnan-windows-x86_64-cross" + PACKAGE_DIR="dist-windows-cross/${PACKAGE_NAME}" + EXE="build-windows-cross/${APP_NAME}.exe" + + test -f "$EXE" + rm -rf dist-windows-cross + mkdir -p "$PACKAGE_DIR" + cp "$EXE" "$PACKAGE_DIR/" + + # 收集 MinGW 运行时、Qt、OpenCV 依赖 DLL。 + for round in 1 2 3; do + while IFS= read -r binary; do + while IFS= read -r dll; do + [ -f "$dll" ] || continue + cp -n "$dll" "$PACKAGE_DIR/" || true + done < <(x86_64-w64-mingw32-objdump -p "$binary" \ + | awk '/DLL Name:/ {print $3}' \ + | while read -r name; do \ + find /usr/x86_64-w64-mingw32/sys-root/mingw/bin -iname "$name" -print -quit; \ + done) + done < <(find "$PACKAGE_DIR" -maxdepth 1 -type f \( -name '*.exe' -o -name '*.dll' \) | sort) + done + + # Qt 平台插件是 Windows Qt GUI 程序启动所必需的。 + QT_PLUGIN_ROOT="/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt6/plugins" + if [ -d "$QT_PLUGIN_ROOT/platforms" ]; then + mkdir -p "$PACKAGE_DIR/platforms" + cp -n "$QT_PLUGIN_ROOT/platforms"/*.dll "$PACKAGE_DIR/platforms/" + fi + + cat > "$PACKAGE_DIR/README.txt" <<'EOF' + chengnan Windows x86_64 交叉编译发布包 + + 运行方式: + 1. 解压整个目录。 + 2. 双击 chengnan.exe 运行。 + + 说明: + - 本目录由 Linux Runner 使用 MinGW-w64 交叉编译生成。 + - 请不要只复制 chengnan.exe,需保留同目录 DLL 和 platforms 子目录。 + EOF + + (cd dist-windows-cross && 7z a -tzip "${PACKAGE_NAME}.zip" "${PACKAGE_NAME}" >/dev/null) + (cd dist-windows-cross && sha256sum "${PACKAGE_NAME}.zip" > "${PACKAGE_NAME}.zip.sha256") + + - name: Verify package + run: | + set -euo pipefail + test -s dist-windows-cross/chengnan-windows-x86_64-cross.zip + sha256sum -c dist-windows-cross/chengnan-windows-x86_64-cross.zip.sha256 + 7z l dist-windows-cross/chengnan-windows-x86_64-cross.zip | grep 'chengnan.exe' + 7z l dist-windows-cross/chengnan-windows-x86_64-cross.zip | grep 'platforms/' + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: chengnan-windows-x86_64-cross + path: | + dist-windows-cross/chengnan-windows-x86_64-cross.zip + dist-windows-cross/chengnan-windows-x86_64-cross.zip.sha256 + if-no-files-found: error