考虑到官方预编译的 Windows 版 qBittorrent 有些时候不能满足自己稳定运行的要求,因此我决定尝试 GitLab CI 自动构建。
Contents
准备 Windows 容器
运行 Windows 容器只需要 WSL 或者 WSL2 支持,但 GitLab Runner 仅支持 Windows Server 平台,因此需要准备一台 Windows Server 宿主机。Windows Server 可以是裸机或者通过虚拟化 Intel VT-x/AMD-v 做到 Nested Virtualization。我使用的是 Windows Server 2019 (version 1809)。
可以在 PowerShell 运行如下命令:
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1" -o install-docker-ce.ps1 .\install-docker-ce.ps1
这会为系统启用 WSL/WSL2 功能,并安装 Docker Engine。
注册 GitLab Runner
为 GitLab Runner 创建一个文件夹例如:C:\\GitLab-Runner
将二进制文件下载到文件夹中。运行如下指令注册 runner:
.\gitlab-runner.exe register
填写相关信息:
- 输入 GitLab 的网址,自建或者官网。
- 输入用以注册 runner 的 token
- 输入你对 runner 的描述,或者保留默认值,通常它会选择你的系统 hostname
- 输入 runner 关联的 tag。
- 输入其他维护信息
顺利的话你就可以在 GitLab runner 状态页面找到这台 runner。
准备 Windows 镜像
你只能运行与宿主系统相同版本的 Windows Server Core 镜像。因此如果运行的是 Windows Server 2019 就应该拉取 mcr.microsoft.com/windows/servercore:1809
。其他镜像可以在 Docker Hub 查到。此外相关的 dotnet 镜像等也可以被用来运行 CI 环境。由于 qBittorrent 编译以来的 Visual Studio 2019 CE 依赖 dotnet 环境,因此直接拉取 mcr.microsoft.com/dotnet/framework/runtime:4.8-20220913-windowsservercore-ltsc2019
可以方便后续操作。
除了准备基础镜像,我还需要收集编译依赖的组件。根据 qBittorrent 的 Wiki 我需要为这个系统安装
- Visual Studio 2019 Community Edition
- CMake, ninja, git
- libboost
- openssl
- qt5
- Libtorrent
其中 VS2019CE
, cmake
, ninja
, git
可以通过 chocolatey
安装。剩下的 libboost
, openssl
, qt5
, 可以使用 vcpkg
编译安装。而 Libtorrent
则通过手动编译完成安装。由于大部分的编译依赖并不需要经常更新,因此我决定先将一部分常用的依赖安装并制作成镜像,编译 qBittorrent 时直接使用这个环境。
我使用了如下配置(Dockerfile)创建 Docker 镜像
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8-20220913-windowsservercore-ltsc2019 SHELL [ "powershell", "-Command" ] # install chocolatey RUN echo \"**** installing chocolatey ****\" RUN Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) # install buildtools RUN echo \"**** installing build-essential ****\" RUN choco install visualstudio2019community -y --params \"--add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.VC.CoreIde --add Microsoft.VisualStudio.Component.VC.CoreBuildTools --add Microsoft.VisualStudio.Component.TextTemplating --add Microsoft.VisualStudio.Component.VC.Redist.14.Latest --add Microsoft.VisualStudio.Component.VC.ATL --add Microsoft.VisualStudio.Component.VC.ATLMFC --add Microsoft.VisualStudio.Component.VC.14.29.16.10.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041\" RUN choco install git -y RUN choco install cmake -y --installargs 'ADD_CMAKE_TO_PATH=System' RUN choco install ninja -y # active build environment RUN $env:Path = [Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine); RUN Import-Module \"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll\"; Enter-VsDevShell -VsInstallPath \"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\" -DevCmdArguments \"-host_arch=amd64 -arch=amd64\" # prepare vcpkg RUN echo \"**** installing vcpkg ****\" WORKDIR "C:\\" RUN git clone https://github.com/microsoft/vcpkg WORKDIR "C:\\vcpkg" RUN .\bootstrap-vcpkg.bat -disableMetrics RUN .\vcpkg integrate install RUN .\vcpkg install \ boost-circular-buffer:x64-windows-static \ boost-stacktrace:x64-windows-static \ openssl:x64-windows-static \ qt5-base:x64-windows-static \ qt5-svg:x64-windows-static \ qt5-tools:x64-windows-static \ qt5-translations:x64-windows-static \ qt5-winextras:x64-windows-static \ --clean-after-build # Storage layer consumed downstream FROM scratch # set version label ARG BUILD_DATE ARG VERSION LABEL build_version="efs.zone version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="EFS"
使用上述配置的镜像体积高达 43.6GB 因此并不适合上传到 Docker Hub,但我可以通过上传到本地的 docker registry 完成对镜像的管理。可以通过上一篇日志所叙述的方式搭建本地的 docker registry。
配置 GitLab CI
使用上一个步骤生成的镜像就可以编译 qBittorrent。编译 qBittorrent 需要如下步骤。
- 通过 vcpkg 安装然后删除 Libtorrent 以完成 Libtorrent 的编译依赖
- 编译 Libtorrent
- 编译 qBittorrent
- 提取打包所需二进制及其他必要文件
- 安装 NSIS 打包环境
- 打包并上传 artifacts
以下配置为实现方法(.gitlab-ci.yml):
.shared_windows_runners: tags: - build-windows image: local.registry/efs/qt5-cmake-vs2019:latest stages: - build-binary - packaging build: extends: - .shared_windows_runners stage: build-binary timeout: 8h script: # prepare base environment - Import-Module "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"; Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community" -DevCmdArguments "-host_arch=amd64 -arch=amd64" # install build environment - cd "C:\vcpkg" - .\vcpkg integrate install - .\vcpkg install libtorrent:x64-windows-static - .\vcpkg remove libtorrent:x64-windows-static # build binary # Libtorrent-Rasterbar - cd "$CI_PROJECT_DIR" - git clone ` --branch RC_1_2_EFS ` --depth 1 ` --recurse-submodules ` https://gitlab-ci-token:${CI_JOB_TOKEN}@selfhost.gitlab.com/efs/libtorrent.git - cd ".\libtorrent" - cmake ` -B build ` -G "Ninja" ` -DCMAKE_BUILD_TYPE=Release ` -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ` -DCMAKE_INSTALL_PREFIX="$CI_PROJECT_DIR/buildd" ` -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ` -DVCPKG_TARGET_TRIPLET="x64-windows-static" ` -DBUILD_SHARED_LIBS=OFF ` -Ddeprecated-functions=OFF ` -Dstatic_runtime=ON - cmake --build build - cmake --install build # qBittorrent - cd "$CI_PROJECT_DIR" - git clone ` https://gitlab-ci-token:${CI_JOB_TOKEN}@selfhost.gitlab.com/efs/qbittorrent.git - cd ".\qBittorrent" - cmake ` -B build ` -G "Ninja" ` -DCMAKE_BUILD_TYPE=Release ` -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ` -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ` -DLibtorrentRasterbar_DIR="$CI_PROJECT_DIR/buildd/lib/cmake/LibtorrentRasterbar" ` -DMSVC_RUNTIME_DYNAMIC=OFF ` -DVCPKG_TARGET_TRIPLET=x64-windows-static ` -DVERBOSE_CONFIGURE=ON ` --graphviz=build/target_graph.dot - cmake --build build # prepare uploads - cd $CI_PROJECT_DIR - If(!(test-path -PathType container upload)){New-Item -ItemType Directory -Path upload} - Copy-Item "$CI_PROJECT_DIR/qBittorrent/build/qbittorrent.exe" "upload" - Copy-Item "$CI_PROJECT_DIR/qBittorrent/build/qbittorrent.pdb" "upload" - Copy-Item "$CI_PROJECT_DIR/qBittorrent/dist/windows/qt.conf" "upload" # cmake additionals - If(!(test-path -PathType container upload/cmake)){New-Item -ItemType Directory -Path upload/cmake} - Copy-Item "$CI_PROJECT_DIR/qBittorrent/build/compile_commands.json" "upload/cmake" - Copy-Item "$CI_PROJECT_DIR/qBittorrent/build/target_graph.dot" "upload/cmake" - If(!(test-path -PathType container upload/cmake/libtorrent)){New-Item -ItemType Directory -Path upload/cmake/libtorrent} - Copy-Item "$CI_PROJECT_DIR/libtorrent/build/compile_commands.json" "upload/cmake/libtorrent" # qt-translations - Copy-Item "C:/vcpkg/installed/x64-windows-static/share/qt5/translations" "$CI_PROJECT_DIR/translations/" -Recurse cache: key: build-cache paths: - upload/ - translations/ packaging: extends: - .shared_windows_runners stage: packaging timeout: 8h script: # prepare base environment - Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) - choco install git -y - choco install nsis -y - choco install 7zip -y - $env:Path = [Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine); - cd "$CI_PROJECT_DIR" - git clone ` https://gitlab-ci-token:${CI_JOB_TOKEN}@selfhost.gitlab.com/efs/qbittorrent.git - cd ".\qBittorrent\dist\windows\nsis plugins" - 7z x -o".\FindProcDLL" .\FindProcDLL_mod_by_hnedka.7z - Copy-Item ".\FindProcDLL\Unicode\FindProcDLL.dll" "C:\Program Files (x86)\NSIS\Plugins\x86-unicode" - 7z x -o".\nsisFirewall" .\nsisFirewall.zip - Copy-Item ".\nsisFirewall\bin\nsisFirewallW.dll" "C:\Program Files (x86)\NSIS\Plugins\x86-unicode" - 7z x -o".\UAC" .\UAC.zip - Copy-Item ".\UAC\Plugins\x86-unicode\UAC.dll" "C:\Program Files (x86)\NSIS\Plugins\x86-unicode" # prepare binary - Copy-Item "$CI_PROJECT_DIR\upload\qbittorrent.exe" "$CI_PROJECT_DIR\qBittorrent\dist\windows" - Copy-Item "$CI_PROJECT_DIR\upload\qbittorrent.pdb" "$CI_PROJECT_DIR\qBittorrent\dist\windows" - Copy-Item "$CI_PROJECT_DIR\upload\qt.conf" "$CI_PROJECT_DIR\qBittorrent\dist\windows" -Force - Copy-Item "$CI_PROJECT_DIR\qBittorrent\COPYING" "$CI_PROJECT_DIR\qBittorrent\dist\windows\license.txt" - Copy-Item "$CI_PROJECT_DIR\translations\" "$CI_PROJECT_DIR\qBittorrent\dist\windows\translations\" -Recurse # run package - cd "$CI_PROJECT_DIR\qBittorrent\dist\windows" - Start-Process -NoNewWindow -FilePath "C:\Program Files (x86)\NSIS\makensis.exe" -ArgumentList "qbittorrent.nsi" -Wait - Copy-Item "$CI_PROJECT_DIR\qBittorrent\dist\windows\qbittorrent*setup.exe" "$CI_PROJECT_DIR\upload" cache: key: build-cache paths: - upload/ - translations/ artifacts: paths: - upload/qbittorrent*setup.exe name: qBittorrent-installer_Windows-x64_libtorrent-1.2.x expire_in: 2 hr
其中以 https://gitlab-ci-token:${CI_JOB_TOKEN}@selfhost.gitlab.com/efs/qbittorrent.git
形式存在的 git url 可以在开启 Limit CI_JOB_TOKEN access
并赋予相应 Repo 权限后自动完成鉴权以达到拉取其他 Repo 完成编译的效果。
参考文档
https://docs.gitlab.com/runner/install/windows.html
https://docs.gitlab.com/runner/register/
https://docs.gitlab.com/runner/executors/docker.html#supported-windows-versions
3条评论. Leave new
您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。
github ci 对比 gitlab ci 有啥太大差别不
除了语法用法有区别,基本功能一致。GitHub 有很多调用如
actions/upload-artifact@v2
是基于 TS 的。GitLab 这类的操作是 runner 直接内置提供的。