chore: keep build tooling in workflow only
Some checks failed
Build Windows Release / build-windows (push) Has been cancelled
Some checks failed
Build Windows Release / build-windows (push) Has been cancelled
This commit is contained in:
@@ -14,30 +14,94 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: msys2 {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Configure MSVC environment
|
- name: Setup MSYS2 build environment
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: msys2/setup-msys2@v2
|
||||||
with:
|
with:
|
||||||
arch: x64
|
msystem: UCRT64
|
||||||
|
update: true
|
||||||
|
install: >-
|
||||||
|
git
|
||||||
|
zip
|
||||||
|
p7zip
|
||||||
|
mingw-w64-ucrt-x86_64-toolchain
|
||||||
|
mingw-w64-ucrt-x86_64-cmake
|
||||||
|
mingw-w64-ucrt-x86_64-ninja
|
||||||
|
mingw-w64-ucrt-x86_64-qt6-base
|
||||||
|
mingw-w64-ucrt-x86_64-opencv
|
||||||
|
|
||||||
- name: Build and package Windows app
|
- name: Configure
|
||||||
shell: pwsh
|
|
||||||
run: |
|
run: |
|
||||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
cmake -S . -B build-windows -G Ninja \
|
||||||
.\scripts\package-windows-release.ps1 -Toolchain msvc
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_PREFIX_PATH=/ucrt64
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake --build build-windows --parallel "$(nproc)"
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
APP_NAME="chengnan"
|
||||||
|
PACKAGE_NAME="chengnan-windows-x86_64"
|
||||||
|
PACKAGE_DIR="dist-windows/${PACKAGE_NAME}"
|
||||||
|
EXE="build-windows/${APP_NAME}.exe"
|
||||||
|
|
||||||
|
test -f "$EXE"
|
||||||
|
rm -rf dist-windows
|
||||||
|
mkdir -p "$PACKAGE_DIR"
|
||||||
|
cp "$EXE" "$PACKAGE_DIR/"
|
||||||
|
|
||||||
|
# 部署 Qt 运行时和插件。
|
||||||
|
if command -v windeployqt >/dev/null 2>&1; then
|
||||||
|
windeployqt --release --no-translations "$PACKAGE_DIR/${APP_NAME}.exe"
|
||||||
|
elif command -v windeployqt6 >/dev/null 2>&1; then
|
||||||
|
windeployqt6 --release --no-translations "$PACKAGE_DIR/${APP_NAME}.exe"
|
||||||
|
else
|
||||||
|
echo "windeployqt not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 收集 MinGW/MSYS2/OpenCV 运行时 DLL。ldd 会列出 exe/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 < <(ldd "$binary" \
|
||||||
|
| awk '/=> \/ucrt64\/bin\// {print $3} /^\/ucrt64\/bin\// {print $1}' \
|
||||||
|
| sort -u)
|
||||||
|
done < <(find "$PACKAGE_DIR" -maxdepth 2 -type f \( -name '*.exe' -o -name '*.dll' \) | sort)
|
||||||
|
done
|
||||||
|
|
||||||
|
cat > "$PACKAGE_DIR/README.txt" <<'EOF'
|
||||||
|
chengnan Windows x86_64 发布包
|
||||||
|
|
||||||
|
运行方式:
|
||||||
|
1. 解压整个目录。
|
||||||
|
2. 双击 chengnan.exe 运行。
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 本目录已包含 Qt、OpenCV 和 MinGW 运行时 DLL。
|
||||||
|
- 请不要只复制 chengnan.exe,需保留同目录 DLL 和 Qt plugins 子目录。
|
||||||
|
EOF
|
||||||
|
|
||||||
|
(cd dist-windows && 7z a -tzip "${PACKAGE_NAME}.zip" "${PACKAGE_NAME}" >/dev/null)
|
||||||
|
(cd dist-windows && sha256sum "${PACKAGE_NAME}.zip" > "${PACKAGE_NAME}.zip.sha256")
|
||||||
|
|
||||||
- name: Verify package
|
- name: Verify package
|
||||||
shell: pwsh
|
|
||||||
run: |
|
run: |
|
||||||
if (!(Test-Path .\dist-windows\chengnan-windows-x86_64.zip)) { throw "missing zip" }
|
test -s dist-windows/chengnan-windows-x86_64.zip
|
||||||
if (!(Test-Path .\dist-windows\chengnan-windows-x86_64.zip.sha256)) { throw "missing sha256" }
|
sha256sum -c dist-windows/chengnan-windows-x86_64.zip.sha256
|
||||||
$zip = Get-Item .\dist-windows\chengnan-windows-x86_64.zip
|
7z l dist-windows/chengnan-windows-x86_64.zip | grep 'chengnan.exe'
|
||||||
if ($zip.Length -le 0) { throw "empty zip" }
|
|
||||||
$hashLine = Get-Content .\dist-windows\chengnan-windows-x86_64.zip.sha256
|
|
||||||
if ($hashLine -notmatch '^[0-9a-f]{64}\s+chengnan-windows-x86_64\.zip$') { throw "invalid sha256 file" }
|
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
|||||||
63
.gitignore
vendored
63
.gitignore
vendored
@@ -1,37 +1,19 @@
|
|||||||
# 构建输出
|
# 构建输出与发布产物
|
||||||
/build*/
|
/build*/
|
||||||
/dist*/
|
/dist*/
|
||||||
|
/out*/
|
||||||
|
/release*/
|
||||||
|
/debug*/
|
||||||
|
|
||||||
# 项目内二进制依赖与下载缓存
|
# 编译工具、SDK、第三方依赖缓存
|
||||||
/tools/linux-build-env/
|
# 本仓库只保存源码;CMake/Ninja/Qt/OpenCV/MSYS2/vcpkg 等均由工作流临时安装。
|
||||||
/tools/micromamba/
|
/tools/
|
||||||
/tools/cmake-linux
|
/third_party/
|
||||||
/tools/ninja-linux
|
|
||||||
/tools/compiler-linux
|
|
||||||
/tools/python-bin
|
|
||||||
/tools/python-venv
|
|
||||||
/third_party/qt-linux
|
|
||||||
/third_party/opencv-linux
|
|
||||||
/downloads/
|
/downloads/
|
||||||
|
/.cache/
|
||||||
|
/vcpkg_installed/
|
||||||
|
|
||||||
# 历史 Windows 二进制依赖,体积很大,不纳入 Git
|
# CMake / Ninja / 编译数据库
|
||||||
/third_party/opencv-windows
|
|
||||||
/third_party/opencv-windows*/
|
|
||||||
/third_party/qt-windows
|
|
||||||
/third_party/qt-windows-msvc
|
|
||||||
/third_party/qt-windows*/
|
|
||||||
/third_party/qt-tools/
|
|
||||||
/tools/cmake-windows/
|
|
||||||
/tools/cmake-current-windows
|
|
||||||
|
|
||||||
# 日志和临时文件
|
|
||||||
*.log
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# CMake / Ninja
|
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
@@ -40,6 +22,29 @@ install_manifest.txt
|
|||||||
build.ninja
|
build.ninja
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
|
# Windows / Qt / C++ 本地产物
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.lib
|
||||||
|
*.pdb
|
||||||
|
*.ilk
|
||||||
|
*.obj
|
||||||
|
*.exp
|
||||||
|
*.manifest
|
||||||
|
*.qrc.depends
|
||||||
|
moc_*.cpp
|
||||||
|
qrc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
*_autogen/
|
||||||
|
|
||||||
|
# 日志和临时文件
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
|||||||
546
README.md
546
README.md
@@ -1,22 +1,28 @@
|
|||||||
# chengnan
|
# chengnan
|
||||||
|
|
||||||
## 项目名称
|
chengnan 是一个面向 Windows 的图片查看器 / 简单图像处理应用,使用 **Qt Widgets + OpenCV + CMake + C++17** 开发。
|
||||||
|
|
||||||
chengnan:基于 Qt 与 OpenCV 的图像显示与处理系统
|
## 项目定位
|
||||||
|
|
||||||
## 当前实现状态
|
- 目标平台:Windows x64
|
||||||
|
- 应用类型:桌面图片查看器
|
||||||
|
- 构建方式:只在 Gitea Actions 工作流中构建和打包
|
||||||
|
- 仓库内容:只保留源码、CMake 配置、文档和工作流
|
||||||
|
- 仓库不包含:CMake/Ninja/Qt/OpenCV/MSYS2/vcpkg 等编译工具、SDK、第三方二进制依赖、本地构建产物
|
||||||
|
|
||||||
本项目已初始化为一个 Qt Widgets + OpenCV + CMake 的 C++ 图像处理应用。当前发布目标为:**Windows x64 桌面应用**,使用 MSVC、Qt Windows 运行时、OpenCV Windows 预编译 DLL 构建并打包;Linux 构建仅作为代码验证用途。
|
## 功能
|
||||||
|
|
||||||
已实现功能:
|
当前已实现:
|
||||||
|
|
||||||
- 打开图片
|
- 打开图片
|
||||||
- 保存图片
|
- 保存图片、另存图片
|
||||||
- 另存图片
|
- 使用 Qt QWidget 体系显示图片,不使用 `cv::imshow`
|
||||||
- 使用 QWidget 体系显示图像,不使用 `cv::imshow`
|
- 左右对比显示原图和处理后图片
|
||||||
- 左右对比显示处理前 / 处理后图像
|
- 图片视图支持:
|
||||||
- 图像视图支持鼠标滚轮缩放、双击适配窗口、拖拽平移视图
|
- 鼠标滚轮缩放
|
||||||
- 图像处理功能:
|
- 双击适配窗口
|
||||||
|
- 拖拽平移视图
|
||||||
|
- 基础图像处理:
|
||||||
- 放大 / 缩小
|
- 放大 / 缩小
|
||||||
- 平移
|
- 平移
|
||||||
- 指定角度旋转
|
- 指定角度旋转
|
||||||
@@ -24,490 +30,86 @@ chengnan:基于 Qt 与 OpenCV 的图像显示与处理系统
|
|||||||
- 基于 HSV 均值的简单规则分类
|
- 基于 HSV 均值的简单规则分类
|
||||||
- 使用 `QThread` + 信号槽执行 OpenCV 处理任务,避免阻塞 UI
|
- 使用 `QThread` + 信号槽执行 OpenCV 处理任务,避免阻塞 UI
|
||||||
|
|
||||||
## Windows 发布与隔离依赖原则
|
## 技术栈
|
||||||
|
|
||||||
本项目发布目标为 Windows x64 桌面应用,要求如下:
|
- C++17
|
||||||
|
- Qt Widgets / Qt Concurrent
|
||||||
|
- OpenCV
|
||||||
|
- CMake
|
||||||
|
- Gitea Actions
|
||||||
|
|
||||||
- 在 Windows x64 + Visual Studio MSVC 环境中构建发布包
|
## 目录结构
|
||||||
- 使用 `cl.exe`、Windows `cmake.exe`、Windows `ninja.exe`、`windeployqt.exe` 构建和部署
|
|
||||||
- Qt、OpenCV、CMake、Ninja 等依赖优先使用项目目录内二进制包或 CI 缓存中的可信二进制包
|
|
||||||
- 不把 Qt/OpenCV 安装到系统目录,不修改系统全局环境变量
|
|
||||||
- 发布包必须包含 `chengnan.exe`、Qt 运行时、Qt plugins、OpenCV DLL 和校验文件
|
|
||||||
- Linux 构建脚本仅用于代码验证,不作为最终发布制品来源
|
|
||||||
|
|
||||||
推荐 Windows 依赖目录约定:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
chengnan/
|
chengnan/
|
||||||
├── tools/
|
├── .gitea/workflows/
|
||||||
│ ├── cmake-current-windows/ # Windows 版 CMake
|
│ └── build-windows-release.yml # Windows 构建与发布工作流
|
||||||
│ └── python-bin/ # 可选:项目内 Python 二进制
|
├── app/
|
||||||
├── third_party/
|
│ ├── include/ # 头文件
|
||||||
│ ├── qt-windows-msvc/ # Windows 版 Qt MSVC
|
│ └── src/ # 源文件
|
||||||
│ ├── opencv-windows/ # Windows 版 OpenCV 预编译包
|
|
||||||
│ └── qt-tools/ # Ninja 等 Qt 工具
|
|
||||||
├── build-windows/ # Windows 构建输出目录
|
|
||||||
└── dist-windows/ # Windows 发布包输出目录
|
|
||||||
```
|
|
||||||
|
|
||||||
> 注意:Windows 发布包依赖 Qt 与 OpenCV Windows 预编译二进制。CI Runner 必须能访问这些依赖,或仓库/缓存中已经准备好对应目录。
|
|
||||||
|
|
||||||
## 编译工具链与版本声明
|
|
||||||
|
|
||||||
本项目发布目标为 Windows x64,推荐工具链如下:
|
|
||||||
|
|
||||||
| 工具 / 依赖 | 项目内路径 | 说明 |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| Visual Studio Build Tools / MSVC | Runner 系统环境 | 提供 `cl.exe`,需通过 x64 Native Tools 或 `msvc-dev-cmd` 初始化 |
|
|
||||||
| CMake | `tools/cmake-current-windows/bin/cmake.exe` | CMake 最低要求 3.21 |
|
|
||||||
| Ninja | `third_party/qt-tools/Tools/Ninja/ninja.exe` | CMake 使用 `-G Ninja` 生成构建系统 |
|
|
||||||
| Qt | `third_party/qt-windows-msvc` | 使用 Qt Widgets / Qt Concurrent,部署时调用 `windeployqt.exe` |
|
|
||||||
| OpenCV | `third_party/opencv-windows/x64/vc16` | 使用 `core`、`imgproc`、`imgcodecs` 组件,发布时复制 DLL |
|
|
||||||
| C++ 标准 | `CMakeLists.txt` | `CMAKE_CXX_STANDARD 17` |
|
|
||||||
|
|
||||||
Linux 二进制工具链仍可用于代码验证,但不作为发布包来源。
|
|
||||||
|
|
||||||
## 如何构建
|
|
||||||
|
|
||||||
### Windows 发布构建
|
|
||||||
|
|
||||||
本项目目标是 Windows 桌面应用。推荐在 Windows x64 + Visual Studio MSVC 环境中构建,仓库内 Windows 依赖约定如下:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-windows-msvc/
|
|
||||||
third_party/opencv-windows/x64/vc16/
|
|
||||||
third_party/qt-tools/Tools/Ninja/ninja.exe
|
|
||||||
tools/cmake-current-windows/bin/cmake.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
在 Windows Runner 或 “x64 Native Tools Command Prompt for VS” 中执行:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
powershell -ExecutionPolicy Bypass -File .\scripts\package-windows-release.ps1 -Toolchain msvc
|
|
||||||
```
|
|
||||||
|
|
||||||
生成的发布包:
|
|
||||||
|
|
||||||
```text
|
|
||||||
dist-windows/chengnan-windows-x86_64.zip
|
|
||||||
dist-windows/chengnan-windows-x86_64.zip.sha256
|
|
||||||
```
|
|
||||||
|
|
||||||
发布包内包含 `chengnan.exe`、Qt 运行时、Qt plugins 和 OpenCV DLL。解压后双击 `chengnan.exe` 运行。
|
|
||||||
|
|
||||||
### Linux 本地验证构建
|
|
||||||
|
|
||||||
Linux 构建仅用于本地验证 Qt/OpenCV 代码,不作为最终 Windows 发布包。
|
|
||||||
|
|
||||||
在 Linux 中进入项目目录执行:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /root/chengnan
|
|
||||||
./scripts/build-linux-binary.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会自动完成:
|
|
||||||
|
|
||||||
1. 检查项目内 Linux 二进制构建环境是否存在
|
|
||||||
2. 如不存在,则下载项目内 `micromamba` 二进制工具
|
|
||||||
3. 在 `tools/linux-build-env/` 内安装 CMake、Ninja、Clang、Qt、OpenCV 等二进制依赖
|
|
||||||
4. 使用项目内 Clang / CMake / Ninja 配置并构建项目
|
|
||||||
5. 输出 Linux 可执行文件:
|
|
||||||
|
|
||||||
```text
|
|
||||||
build-linux/chengnan
|
|
||||||
```
|
|
||||||
|
|
||||||
### 分步构建
|
|
||||||
|
|
||||||
如果希望先准备依赖,再单独构建:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /root/chengnan
|
|
||||||
./scripts/setup-linux-binary-deps.sh
|
|
||||||
./scripts/build-linux-binary.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 手动等价构建命令
|
|
||||||
|
|
||||||
以下命令等价于脚本中的核心构建逻辑,适合调试 CMake 参数:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /root/chengnan
|
|
||||||
|
|
||||||
export PATH="$PWD/tools/linux-build-env/bin:$PATH"
|
|
||||||
export CMAKE_PREFIX_PATH="$PWD/tools/linux-build-env"
|
|
||||||
export PKG_CONFIG_PATH="$PWD/tools/linux-build-env/lib/pkgconfig:$PWD/tools/linux-build-env/share/pkgconfig:${PKG_CONFIG_PATH:-}"
|
|
||||||
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:${LD_LIBRARY_PATH:-}"
|
|
||||||
export CC="$PWD/tools/linux-build-env/bin/clang"
|
|
||||||
export CXX="$PWD/tools/linux-build-env/bin/clang++"
|
|
||||||
|
|
||||||
cmake -S . -B build-linux \
|
|
||||||
-G Ninja \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
|
|
||||||
-DCMAKE_C_COMPILER="$CC" \
|
|
||||||
-DCMAKE_CXX_COMPILER="$CXX" \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="$PWD/dist-linux"
|
|
||||||
|
|
||||||
cmake --build build-linux --parallel "$(nproc)"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 运行程序
|
|
||||||
|
|
||||||
构建完成后运行:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /root/chengnan
|
|
||||||
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:${LD_LIBRARY_PATH:-}"
|
|
||||||
./build-linux/chengnan
|
|
||||||
```
|
|
||||||
|
|
||||||
如果在无桌面环境或 SSH 终端中运行,Qt 图形界面可能无法显示,需要在有 X11 / Wayland 图形会话的 Linux 桌面环境中运行。
|
|
||||||
|
|
||||||
## 已清理的历史依赖
|
|
||||||
|
|
||||||
之前为了尝试构建曾产生过源码编译或非目标平台相关内容,目前已删除:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/opencv-src
|
|
||||||
third_party/opencv-build
|
|
||||||
third_party/opencv
|
|
||||||
third_party/qt-sdk
|
|
||||||
third_party/qt
|
|
||||||
third_party/opengl-stub
|
|
||||||
tools/uv
|
|
||||||
tools/pyenv
|
|
||||||
tools/cmake
|
|
||||||
tools/cmake.tar.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
这些内容被删除的原因:
|
|
||||||
|
|
||||||
- `opencv-src` / `opencv-build` / `opencv` 属于源码编译安装路径,不符合“只使用二进制安装”的要求
|
|
||||||
- `qt-sdk` / `qt` 是 Linux 本地尝试阶段的旧 Qt 目录,需要按新的 Linux 二进制依赖规范重新放置
|
|
||||||
- `opengl-stub` 是临时构建验证用内容,不属于正式项目依赖
|
|
||||||
- `tools/uv` / `tools/pyenv` 是 uv 相关环境,不符合“Python 使用虚拟环境,不使用 uv 安装”的要求
|
|
||||||
- `tools/cmake` 是旧 Linux CMake 工具目录,后续应按 `tools/cmake-linux/` 重新放置二进制工具
|
|
||||||
|
|
||||||
## 当前项目内已有的二进制依赖记录
|
|
||||||
|
|
||||||
当前目录中准备或约定了 Windows 方案所需的二进制依赖和脚本:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-windows-msvc-sdk/
|
|
||||||
third_party/qt-windows-msvc
|
|
||||||
third_party/opencv-windows-extract/
|
|
||||||
third_party/opencv-windows
|
|
||||||
third_party/qt-tools/
|
|
||||||
tools/cmake-windows/
|
|
||||||
tools/cmake-current-windows
|
|
||||||
tools/python-bin/
|
|
||||||
scripts/build-windows.ps1
|
|
||||||
scripts/setup-python-venv-windows.ps1
|
|
||||||
DEPENDENCIES.md
|
|
||||||
```
|
|
||||||
|
|
||||||
已验证这些文件曾存在:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-windows-msvc/bin/qmake.exe
|
|
||||||
third_party/qt-windows-msvc/bin/windeployqt.exe
|
|
||||||
third_party/opencv-windows/x64/vc16/lib/OpenCVConfig.cmake
|
|
||||||
third_party/opencv-windows/x64/vc16/lib/opencv_world4100.lib
|
|
||||||
third_party/opencv-windows/x64/vc16/bin/opencv_world4100.dll
|
|
||||||
third_party/qt-tools/Tools/Ninja/ninja.exe
|
|
||||||
tools/cmake-current-windows/bin/cmake.exe
|
|
||||||
tools/python-bin/python.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
这些 Windows 二进制内容是发布包构建所需依赖;Linux 验证构建不会引用它们。
|
|
||||||
|
|
||||||
## Linux 验证构建说明
|
|
||||||
|
|
||||||
如需在 Linux 上做代码验证,可使用项目内 Linux 二进制依赖:
|
|
||||||
|
|
||||||
- Linux 版 CMake 二进制包
|
|
||||||
- Linux 版 Ninja 二进制包
|
|
||||||
- Linux 版二进制 C++ 编译器工具链,例如 LLVM/Clang 预编译包
|
|
||||||
- Linux 版 Qt 二进制包
|
|
||||||
- Linux 版 OpenCV 二进制包
|
|
||||||
- 项目内 Python 二进制包和虚拟环境
|
|
||||||
|
|
||||||
构建脚本建议命名为:
|
|
||||||
|
|
||||||
```text
|
|
||||||
scripts/setup-python-venv-linux.sh
|
|
||||||
scripts/build-linux-binary.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
示例构建命令应类似:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./scripts/build-linux-binary.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
该脚本应只使用项目内路径,例如:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export PATH="$PWD/tools/cmake-linux/bin:$PWD/tools/ninja-linux:$PWD/tools/compiler-linux/bin:$PATH"
|
|
||||||
export CMAKE_PREFIX_PATH="$PWD/third_party/qt-linux;$PWD/third_party/opencv-linux"
|
|
||||||
```
|
|
||||||
|
|
||||||
但脚本不得写入系统环境,也不得调用系统 GCC/G++ 作为项目编译器。
|
|
||||||
|
|
||||||
## 项目目标
|
|
||||||
|
|
||||||
使用 Qt 设计图形化界面,结合 OpenCV 实现图像的读取、显示、保存、基础几何处理,以及分类或目标提取功能。程序需要支持处理前后图像对比显示,并在图像处理流程中尽量使用 Qt 线程,避免阻塞界面。
|
|
||||||
|
|
||||||
## 技术要求
|
|
||||||
|
|
||||||
### 1. 开发框架
|
|
||||||
|
|
||||||
- GUI 框架:Qt(建议 Qt 6.x,使用 Qt Widgets)
|
|
||||||
- 图像处理库:OpenCV
|
|
||||||
- 构建系统:CMake
|
|
||||||
- 编程语言:C++17 或更高版本
|
|
||||||
- 图像显示:必须使用 Qt 的 QWidget / QLabel / QGraphicsView 等控件显示图像
|
|
||||||
- 禁止使用:`cv::imshow`、`cv::waitKey` 等 OpenCV 窗口显示方式
|
|
||||||
|
|
||||||
### 2. 界面功能要求
|
|
||||||
|
|
||||||
界面由 Qt 设计实现,至少应包含以下基础功能:
|
|
||||||
|
|
||||||
- 打开图片
|
|
||||||
- 保存图片
|
|
||||||
- 另存图片
|
|
||||||
- 显示原始图片
|
|
||||||
- 显示处理后的图片
|
|
||||||
- 支持处理前、处理后图像的对比观看
|
|
||||||
- 显示当前操作状态或处理结果提示
|
|
||||||
|
|
||||||
建议界面布局:
|
|
||||||
|
|
||||||
- 左侧显示原始图片
|
|
||||||
- 右侧显示处理后图片
|
|
||||||
- 顶部或侧边栏放置操作按钮
|
|
||||||
- 底部状态栏显示当前文件路径、处理状态、图片尺寸等信息
|
|
||||||
|
|
||||||
### 3. 图像基础处理要求
|
|
||||||
|
|
||||||
图片处理应包含以下简单操作:
|
|
||||||
|
|
||||||
- 缩放
|
|
||||||
- 放大
|
|
||||||
- 缩小
|
|
||||||
- 按比例缩放
|
|
||||||
- 平移
|
|
||||||
- 向上、下、左、右移动图像显示区域或图像内容
|
|
||||||
- 旋转
|
|
||||||
- 顺时针旋转
|
|
||||||
- 逆时针旋转
|
|
||||||
- 指定角度旋转
|
|
||||||
|
|
||||||
可选增强功能:
|
|
||||||
|
|
||||||
- 灰度化
|
|
||||||
- 二值化
|
|
||||||
- 亮度 / 对比度调节
|
|
||||||
- 滤波 / 模糊
|
|
||||||
- 边缘检测
|
|
||||||
- 撤销 / 重做
|
|
||||||
|
|
||||||
### 4. 分类或目标提取功能要求
|
|
||||||
|
|
||||||
程序应至少实现以下两项功能之一,两者皆有最佳:
|
|
||||||
|
|
||||||
#### 方案 A:图像分类
|
|
||||||
|
|
||||||
可实现简单图像分类,例如:
|
|
||||||
|
|
||||||
- 根据颜色占比进行分类
|
|
||||||
- 根据亮度、纹理、边缘数量进行规则分类
|
|
||||||
- 使用 OpenCV DNN 加载轻量模型进行分类
|
|
||||||
|
|
||||||
分类结果应显示在界面中,例如:
|
|
||||||
|
|
||||||
- 图片类型
|
|
||||||
- 置信度或规则判断依据
|
|
||||||
- 分类耗时
|
|
||||||
|
|
||||||
#### 方案 B:目标提取
|
|
||||||
|
|
||||||
可实现目标提取,例如:
|
|
||||||
|
|
||||||
- 阈值分割
|
|
||||||
- 颜色区域提取
|
|
||||||
- 轮廓检测
|
|
||||||
- 边缘检测
|
|
||||||
- 前景目标提取
|
|
||||||
|
|
||||||
目标提取结果应显示在处理后图像窗口中,并可叠加以下信息:
|
|
||||||
|
|
||||||
- 目标轮廓
|
|
||||||
- 外接矩形
|
|
||||||
- 目标数量
|
|
||||||
- 面积、中心点等简单特征
|
|
||||||
|
|
||||||
建议优先实现目标提取,再扩展简单分类功能。
|
|
||||||
|
|
||||||
### 5. 显示要求
|
|
||||||
|
|
||||||
- 必须具有图像显示功能
|
|
||||||
- 必须显示处理前、处理后的图像对比
|
|
||||||
- 显示控件必须基于 QWidget 体系
|
|
||||||
- 不允许使用 OpenCV 的 `cv::imshow` 显示图片
|
|
||||||
- OpenCV 的 `cv::Mat` 与 Qt 的 `QImage` / `QPixmap` 之间应封装转换函数
|
|
||||||
|
|
||||||
### 6. 线程要求
|
|
||||||
|
|
||||||
考虑图像处理使用 Qt 线程,避免大图像处理时卡住主界面。
|
|
||||||
|
|
||||||
建议设计:
|
|
||||||
|
|
||||||
- 主线程:负责 UI 显示、按钮响应、用户交互
|
|
||||||
- 工作线程:负责 OpenCV 图像处理、分类、目标提取
|
|
||||||
- 线程通信:使用 Qt 信号与槽
|
|
||||||
- 禁止在工作线程中直接操作 QWidget 控件
|
|
||||||
|
|
||||||
建议类设计:
|
|
||||||
|
|
||||||
- `MainWindow`:主窗口,负责 UI 和用户操作
|
|
||||||
- `ImageProcessor`:图像处理逻辑类
|
|
||||||
- `ImageWorker`:运行在 QThread 中的图像处理工作对象
|
|
||||||
- `ImageConverter`:负责 `cv::Mat` 与 `QImage` 转换
|
|
||||||
|
|
||||||
### 7. 环境与依赖安装要求
|
|
||||||
|
|
||||||
所有安装的依赖不得污染本地系统环境,必须采用项目文件夹内二进制安装或指定路径解压的方式。
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
- Windows 发布包在 Windows x64 + MSVC 环境中构建
|
|
||||||
- Linux 构建仅用于本地代码验证
|
|
||||||
- 不使用源码编译安装 Qt / OpenCV 等依赖
|
|
||||||
- 不建议直接全局安装 Qt 或 OpenCV
|
|
||||||
- 不建议污染系统 `/usr`、`/usr/local` 等全局路径
|
|
||||||
- 建议将依赖安装到项目目录下,例如:
|
|
||||||
- `chengnan/third_party/qt-linux/`
|
|
||||||
- `chengnan/third_party/opencv-linux/`
|
|
||||||
- `chengnan/tools/cmake-linux/`
|
|
||||||
- `chengnan/tools/ninja-linux/`
|
|
||||||
- `chengnan/tools/compiler-linux/`
|
|
||||||
- `chengnan/tools/python-venv/`
|
|
||||||
- CMake 通过 `CMAKE_PREFIX_PATH` 指向项目内依赖路径
|
|
||||||
- 构建目录使用 `chengnan/build-linux/`
|
|
||||||
- 可使用脚本统一配置环境变量,但只能影响当前进程,不修改系统环境变量
|
|
||||||
|
|
||||||
示例目录:
|
|
||||||
|
|
||||||
```text
|
|
||||||
chengnan/
|
|
||||||
├── README.md
|
|
||||||
├── CMakeLists.txt
|
├── CMakeLists.txt
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
├── app/
|
└── README.md
|
||||||
│ ├── include/
|
|
||||||
│ │ ├── MainWindow.h
|
|
||||||
│ │ ├── ImageView.h
|
|
||||||
│ │ ├── ImageProcessor.h
|
|
||||||
│ │ ├── ImageWorker.h
|
|
||||||
│ │ └── ImageConverter.h
|
|
||||||
│ └── src/
|
|
||||||
│ ├── main.cpp
|
|
||||||
│ ├── MainWindow.cpp
|
|
||||||
│ ├── ImageView.cpp
|
|
||||||
│ ├── ImageProcessor.cpp
|
|
||||||
│ ├── ImageWorker.cpp
|
|
||||||
│ └── ImageConverter.cpp
|
|
||||||
├── docs/
|
|
||||||
│ └── windows/ # Windows 依赖说明和构建脚本
|
|
||||||
├── scripts/
|
|
||||||
│ ├── setup-linux-binary-deps.sh
|
|
||||||
│ ├── setup-python-venv-linux.sh
|
|
||||||
│ └── build-linux-binary.sh
|
|
||||||
├── tools/
|
|
||||||
│ ├── linux-build-env/ # 项目内 Linux 二进制构建环境,Git 忽略
|
|
||||||
│ ├── cmake-linux -> linux-build-env
|
|
||||||
│ ├── ninja-linux -> linux-build-env
|
|
||||||
│ ├── compiler-linux -> linux-build-env
|
|
||||||
│ ├── python-bin -> linux-build-env
|
|
||||||
│ └── python-venv -> linux-build-env
|
|
||||||
├── third_party/
|
|
||||||
│ ├── qt-linux -> ../tools/linux-build-env
|
|
||||||
│ └── opencv-linux -> ../tools/linux-build-env
|
|
||||||
└── build-linux/ # Linux 构建输出目录,Git 忽略
|
|
||||||
```
|
```
|
||||||
|
|
||||||
示例 CMake 配置方式应写入脚本中统一执行,不能依赖系统工具链:
|
## 构建与发布
|
||||||
|
|
||||||
```bash
|
本项目不在仓库中保存编译工具或第三方二进制依赖。所有构建工作都在 `.gitea/workflows/build-windows-release.yml` 中完成。
|
||||||
./scripts/setup-linux-binary-deps.sh
|
|
||||||
./scripts/build-linux-binary.sh
|
工作流会在 Windows Runner 中临时完成以下步骤:
|
||||||
|
|
||||||
|
1. 拉取源码
|
||||||
|
2. 安装 Windows 构建环境和依赖
|
||||||
|
3. 配置 CMake
|
||||||
|
4. 编译 Release 版本
|
||||||
|
5. 部署 Qt / OpenCV / MinGW 运行时依赖
|
||||||
|
6. 打包 Windows 发布包
|
||||||
|
7. 生成 SHA256 校验文件
|
||||||
|
8. 上传构建产物
|
||||||
|
|
||||||
|
触发方式:
|
||||||
|
|
||||||
|
- push 到 `main`
|
||||||
|
- 创建 `v*` 标签
|
||||||
|
- Pull Request 到 `main`
|
||||||
|
- 手动触发 `workflow_dispatch`
|
||||||
|
|
||||||
|
构建产物:
|
||||||
|
|
||||||
|
```text
|
||||||
|
chengnan-windows-x86_64.zip
|
||||||
|
chengnan-windows-x86_64.zip.sha256
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本会在项目目录内使用 Linux 二进制包创建隔离环境,并只在当前进程内设置环境变量。核心等价配置如下:
|
发布包解压后,双击 `chengnan.exe` 运行。请保留同目录 DLL 和 Qt 插件目录,不要只复制单个 exe。
|
||||||
|
|
||||||
```bash
|
## 本地开发说明
|
||||||
export PATH="$PWD/tools/linux-build-env/bin:$PATH"
|
|
||||||
export CMAKE_PREFIX_PATH="$PWD/tools/linux-build-env"
|
|
||||||
export PKG_CONFIG_PATH="$PWD/tools/linux-build-env/lib/pkgconfig:$PWD/tools/linux-build-env/share/pkgconfig:$PKG_CONFIG_PATH"
|
|
||||||
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:$LD_LIBRARY_PATH"
|
|
||||||
export CC="$PWD/tools/linux-build-env/bin/clang"
|
|
||||||
export CXX="$PWD/tools/linux-build-env/bin/clang++"
|
|
||||||
|
|
||||||
cmake -S . -B build-linux \
|
仓库不提供本地依赖安装脚本,也不保存编译工具。若需要本地开发,请自行在 Windows 上安装:
|
||||||
-G Ninja \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
|
|
||||||
-DCMAKE_C_COMPILER="$CC" \
|
|
||||||
-DCMAKE_CXX_COMPILER="$CXX"
|
|
||||||
|
|
||||||
cmake --build build-linux -j$(nproc)
|
- CMake
|
||||||
```
|
- Ninja
|
||||||
|
- Qt 6
|
||||||
|
- OpenCV
|
||||||
|
- C++ 编译器(MSVC 或 MinGW)
|
||||||
|
|
||||||
如需临时设置运行环境,建议写入脚本,不写入系统全局配置:
|
然后按常规 CMake 项目方式配置和构建。正式发布以 Gitea Actions 产物为准。
|
||||||
|
|
||||||
```bash
|
## 依赖管理原则
|
||||||
export PATH="$PWD/third_party/qt-linux/bin:$PWD/tools/cmake-linux/bin:$PWD/tools/ninja-linux:$PWD/tools/compiler-linux/bin:$PATH"
|
|
||||||
export LD_LIBRARY_PATH="$PWD/third_party/qt-linux/lib:$PWD/third_party/opencv-linux/lib:$LD_LIBRARY_PATH"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 推荐实现步骤
|
- 不提交编译器、CMake、Ninja、Qt、OpenCV、MSYS2、vcpkg 等工具或 SDK
|
||||||
|
- 不提交 `build-*`、`dist-*`、`.exe`、`.dll` 等构建产物
|
||||||
1. 创建 Qt Widgets + CMake 项目结构
|
- 第三方依赖只在工作流运行期间临时安装
|
||||||
2. 实现主窗口和基本按钮:打开、保存、另存
|
- 发布包只作为工作流 artifact 产出,不进入源码仓库
|
||||||
3. 实现图片显示控件,完成原图和处理图对比显示
|
|
||||||
4. 封装 `cv::Mat` 与 `QImage` 的转换工具
|
|
||||||
5. 实现缩放、平移、旋转等基础处理
|
|
||||||
6. 将图像处理逻辑迁移到 `QThread` 工作线程
|
|
||||||
7. 实现目标提取功能,例如阈值分割 + 轮廓检测
|
|
||||||
8. 可选实现简单分类功能
|
|
||||||
9. 完成保存处理结果图片
|
|
||||||
10. 编写 Linux 本地二进制工具链构建脚本,确保 Qt、OpenCV、CMake、Ninja、编译器等工具均放在项目目录内
|
|
||||||
11. 测试大图处理时界面是否保持响应
|
|
||||||
12. 完善 README、运行说明和截图
|
|
||||||
|
|
||||||
## 验收标准
|
## 验收标准
|
||||||
|
|
||||||
- 可以打开常见图片格式,例如 PNG、JPG、BMP
|
- 可以打开常见图片格式,例如 PNG、JPG、BMP
|
||||||
- 可以保存当前处理后的图片
|
- 可以保存当前处理后的图片
|
||||||
- 可以另存为指定路径
|
- 可以另存为指定路径
|
||||||
- 可以在同一界面中对比显示处理前和处理后图像
|
- 可以在同一界面中对比显示处理前和处理后图片
|
||||||
- 支持缩放、平移、旋转操作
|
- 支持缩放、平移、旋转操作
|
||||||
- 至少实现分类或目标提取功能之一
|
- 至少实现目标提取或分类功能之一
|
||||||
- 图像显示使用 QWidget 体系,不使用 `cv::imshow`
|
- 图片显示使用 QWidget 体系,不使用 OpenCV 窗口显示函数
|
||||||
- 图像处理任务不会明显阻塞 UI
|
- 图像处理任务不会明显阻塞 UI
|
||||||
- 依赖安装和构建必须限制在项目目录内,不污染系统环境
|
- Windows 发布包可直接解压运行
|
||||||
- Windows 发布包可通过 Windows x64 + MSVC 构建生成
|
|
||||||
- 所有工具和依赖使用二进制包或解压式安装,不使用源码编译安装
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
- QWidget 只能在主线程中创建和更新
|
|
||||||
- 工作线程只处理数据,不直接改 UI
|
|
||||||
- 大图处理时应避免频繁深拷贝,可合理使用 `cv::Mat::clone()` 控制生命周期
|
|
||||||
- `QImage` 与 `cv::Mat` 共享内存时要注意对象生命周期
|
|
||||||
- 保存图片时应保存处理后的图像,而不是原图
|
|
||||||
- 若使用 OpenCV DNN 模型,模型文件应放入项目目录,例如 `models/`
|
|
||||||
- 所有脚本应避免执行破坏性系统操作
|
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
# chengnan 本地二进制依赖说明
|
|
||||||
|
|
||||||
本项目原则:**构建项目所用依赖使用二进制包放在项目目录内,不在本机编译安装依赖,不使用系统 GCC 等编译工具链参与本项目构建。**
|
|
||||||
|
|
||||||
## 已删除的非目标依赖
|
|
||||||
|
|
||||||
已删除之前为 Linux 本地尝试构建而产生的内容:
|
|
||||||
|
|
||||||
- `third_party/opencv-src/`:OpenCV 源码
|
|
||||||
- `third_party/opencv-build/`:OpenCV 编译目录
|
|
||||||
- `third_party/opencv/`:由源码编译安装出的 Linux OpenCV
|
|
||||||
- `third_party/qt-sdk/`:Linux Qt 包
|
|
||||||
- `third_party/qt`:Linux Qt 软链接
|
|
||||||
- `third_party/opengl-stub/`:Linux 构建验证用 stub
|
|
||||||
- `tools/uv/`:uv 工具
|
|
||||||
- `tools/pyenv/`:uv 创建的 Python 环境
|
|
||||||
- `tools/cmake/`:Linux CMake 二进制
|
|
||||||
|
|
||||||
## 当前保留的 Windows 二进制依赖
|
|
||||||
|
|
||||||
### Qt 6.7.3 MSVC 2019 64-bit
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-windows-msvc-sdk/6.7.3/msvc2019_64/
|
|
||||||
third_party/qt-windows-msvc -> qt-windows-msvc-sdk/6.7.3/msvc2019_64
|
|
||||||
```
|
|
||||||
|
|
||||||
关键文件:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-windows-msvc/bin/qmake.exe
|
|
||||||
third_party/qt-windows-msvc/bin/windeployqt.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
### OpenCV 4.10.0 Windows 官方预编译包
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/opencv-windows-extract/opencv/build/
|
|
||||||
third_party/opencv-windows -> opencv-windows-extract/opencv/build
|
|
||||||
```
|
|
||||||
|
|
||||||
关键文件:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/opencv-windows/x64/vc16/lib/OpenCVConfig.cmake
|
|
||||||
third_party/opencv-windows/x64/vc16/lib/opencv_world4100.lib
|
|
||||||
third_party/opencv-windows/x64/vc16/bin/opencv_world4100.dll
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ninja / MinGW 工具包
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-tools/
|
|
||||||
```
|
|
||||||
|
|
||||||
关键文件:
|
|
||||||
|
|
||||||
```text
|
|
||||||
third_party/qt-tools/Tools/Ninja/ninja.exe
|
|
||||||
third_party/qt-tools/Tools/mingw1120_64/bin/g++.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
> 注意:项目保留 MinGW 二进制只是备用。当前推荐 MSVC,因为 OpenCV 官方 Windows 二进制是 `vc16`,不能直接给 MinGW 链接。
|
|
||||||
|
|
||||||
### Windows CMake 二进制
|
|
||||||
|
|
||||||
```text
|
|
||||||
tools/cmake-windows/cmake-3.31.6-windows-x86_64/
|
|
||||||
tools/cmake-current-windows -> cmake-windows/cmake-3.31.6-windows-x86_64
|
|
||||||
```
|
|
||||||
|
|
||||||
关键文件:
|
|
||||||
|
|
||||||
```text
|
|
||||||
tools/cmake-current-windows/bin/cmake.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
### Windows Python 二进制与虚拟环境脚本
|
|
||||||
|
|
||||||
```text
|
|
||||||
tools/python-bin/
|
|
||||||
scripts/setup-python-venv-windows.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- `tools/python-bin/` 使用 Python 官方 Windows embeddable zip 二进制包解压得到
|
|
||||||
- 不使用 uv
|
|
||||||
- 如果需要 Python 包,请在 Windows 上运行:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\setup-python-venv-windows.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
该脚本会优先尝试创建:
|
|
||||||
|
|
||||||
```text
|
|
||||||
tools/python-venv/
|
|
||||||
```
|
|
||||||
|
|
||||||
如果 embeddable Python 不支持 `venv`,则会在 `tools/python-bin/` 内安装 pip/aqtinstall,仍然限制在项目目录内。
|
|
||||||
|
|
||||||
## Windows 推荐构建方式
|
|
||||||
|
|
||||||
由于当前 OpenCV 是官方 MSVC `vc16` 二进制包,推荐使用 MSVC 构建。
|
|
||||||
|
|
||||||
在 Windows 上打开:
|
|
||||||
|
|
||||||
```text
|
|
||||||
x64 Native Tools Command Prompt for VS 2019/2022
|
|
||||||
```
|
|
||||||
|
|
||||||
进入项目目录后运行:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\build-windows.ps1 -Toolchain msvc -Deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会使用项目内:
|
|
||||||
|
|
||||||
- `tools/cmake-current-windows/bin/cmake.exe`
|
|
||||||
- `third_party/qt-tools/Tools/Ninja/ninja.exe`
|
|
||||||
- `third_party/qt-windows-msvc/`
|
|
||||||
- `third_party/opencv-windows/`
|
|
||||||
|
|
||||||
## 关于“不使用系统工具链”
|
|
||||||
|
|
||||||
当前已经避免使用 Linux 系统 GCC 编译本项目,也删除了通过系统 GCC 编译出来的 OpenCV。
|
|
||||||
|
|
||||||
但 MSVC 编译器 `cl.exe` 通常来自 Visual Studio Build Tools。微软没有像 Qt/OpenCV 一样提供适合随项目简单解压携带的独立 MSVC 工具链包。因此:
|
|
||||||
|
|
||||||
- 如果允许使用 Windows 已安装的 Visual Studio Build Tools:可直接构建
|
|
||||||
- 如果要求连 MSVC 编译器也必须项目内携带:建议改用 MinGW,但需要额外准备 MinGW 版 OpenCV 二进制包
|
|
||||||
|
|
||||||
## 当前 Linux 服务器限制
|
|
||||||
|
|
||||||
当前服务器是 Linux,只能整理 Windows 二进制依赖和脚本,不能直接运行 Windows 的:
|
|
||||||
|
|
||||||
- `cmake.exe`
|
|
||||||
- `ninja.exe`
|
|
||||||
- `cl.exe`
|
|
||||||
- `windeployqt.exe`
|
|
||||||
|
|
||||||
因此最终 `.exe` 需要在 Windows 上执行构建脚本生成。
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
param(
|
|
||||||
[ValidateSet("msvc", "mingw")]
|
|
||||||
[string]$Toolchain = "msvc",
|
|
||||||
[string]$BuildDir = "$PSScriptRoot\..\..\build-windows",
|
|
||||||
[switch]$Deploy
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
$ProjectRoot = Resolve-Path "$PSScriptRoot\..\.."
|
|
||||||
$BuildDir = [System.IO.Path]::GetFullPath($BuildDir)
|
|
||||||
$ThirdParty = Join-Path $ProjectRoot "third_party"
|
|
||||||
$Tools = Join-Path $ProjectRoot "tools"
|
|
||||||
|
|
||||||
$CMakeExe = Join-Path $Tools "cmake-current-windows\bin\cmake.exe"
|
|
||||||
if (!(Test-Path $CMakeExe)) {
|
|
||||||
$CMakeExe = Join-Path $Tools "cmake-windows\cmake-3.31.6-windows-x86_64\bin\cmake.exe"
|
|
||||||
}
|
|
||||||
if (!(Test-Path $CMakeExe)) {
|
|
||||||
throw "未找到项目内 Windows CMake:$CMakeExe"
|
|
||||||
}
|
|
||||||
|
|
||||||
$NinjaExe = Join-Path $ThirdParty "qt-tools\Tools\Ninja\ninja.exe"
|
|
||||||
if (!(Test-Path $NinjaExe)) {
|
|
||||||
$NinjaExe = Join-Path $ThirdParty "qt-tools\Tools\ninja\ninja.exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($Toolchain -eq "msvc") {
|
|
||||||
$QtPrefix = Join-Path $ThirdParty "qt-windows-msvc"
|
|
||||||
$OpenCvPrefix = Join-Path $ThirdParty "opencv-windows\x64\vc16\lib"
|
|
||||||
$OpenCvBin = Join-Path $ThirdParty "opencv-windows\x64\vc16\bin"
|
|
||||||
$Generator = "Ninja"
|
|
||||||
|
|
||||||
if (!(Test-Path $QtPrefix)) { throw "未找到 Qt MSVC:$QtPrefix" }
|
|
||||||
if (!(Test-Path $OpenCvPrefix)) { throw "未找到 OpenCV MSVC:$OpenCvPrefix" }
|
|
||||||
if (!(Get-Command cl.exe -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "未检测到 cl.exe。请在 x64 Native Tools Command Prompt for VS 中运行本脚本,或先运行 vcvars64.bat。"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$QtPrefix = Join-Path $ThirdParty "qt-windows"
|
|
||||||
$OpenCvPrefix = Join-Path $ThirdParty "opencv-windows\x64\vc16\lib"
|
|
||||||
$OpenCvBin = Join-Path $ThirdParty "opencv-windows\x64\vc16\bin"
|
|
||||||
$MingwBin = Join-Path $ThirdParty "qt-tools\Tools\mingw1120_64\bin"
|
|
||||||
$Generator = "Ninja"
|
|
||||||
|
|
||||||
if (!(Test-Path $QtPrefix)) { throw "未找到 Qt MinGW:$QtPrefix" }
|
|
||||||
if (!(Test-Path $MingwBin)) { throw "未找到项目内 MinGW:$MingwBin" }
|
|
||||||
Write-Warning "OpenCV 官方 Windows 预编译包是 MSVC vc16,不适配 MinGW 链接。若要 MinGW 构建,需要另备 MinGW 版 OpenCV 二进制包。"
|
|
||||||
|
|
||||||
$env:PATH = "$MingwBin;$env:PATH"
|
|
||||||
$env:CC = Join-Path $MingwBin "gcc.exe"
|
|
||||||
$env:CXX = Join-Path $MingwBin "g++.exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(Test-Path $NinjaExe)) {
|
|
||||||
throw "未找到项目内 Ninja:$NinjaExe"
|
|
||||||
}
|
|
||||||
|
|
||||||
$env:PATH = "$QtPrefix\bin;$OpenCvBin;$(Split-Path $NinjaExe);$env:PATH"
|
|
||||||
$PrefixPath = "$QtPrefix;$OpenCvPrefix"
|
|
||||||
|
|
||||||
Write-Host "ProjectRoot: $ProjectRoot"
|
|
||||||
Write-Host "Toolchain: $Toolchain"
|
|
||||||
Write-Host "QtPrefix: $QtPrefix"
|
|
||||||
Write-Host "OpenCV: $OpenCvPrefix"
|
|
||||||
Write-Host "BuildDir: $BuildDir"
|
|
||||||
Write-Host "Ninja: $NinjaExe"
|
|
||||||
|
|
||||||
& $CMakeExe -S $ProjectRoot -B $BuildDir -G $Generator `
|
|
||||||
-DCMAKE_BUILD_TYPE=Release `
|
|
||||||
-DCMAKE_MAKE_PROGRAM="$NinjaExe" `
|
|
||||||
-DCMAKE_PREFIX_PATH="$PrefixPath"
|
|
||||||
|
|
||||||
& $CMakeExe --build $BuildDir --config Release
|
|
||||||
|
|
||||||
if ($Deploy) {
|
|
||||||
$Exe = Join-Path $BuildDir "chengnan.exe"
|
|
||||||
$DeployDir = Join-Path $BuildDir "deploy"
|
|
||||||
New-Item -ItemType Directory -Force -Path $DeployDir | Out-Null
|
|
||||||
Copy-Item $Exe $DeployDir -Force
|
|
||||||
& (Join-Path $QtPrefix "bin\windeployqt.exe") --release --no-translations (Join-Path $DeployDir "chengnan.exe")
|
|
||||||
Copy-Item (Join-Path $OpenCvBin "*.dll") $DeployDir -Force
|
|
||||||
Write-Host "已部署到:$DeployDir"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "构建完成。"
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
param(
|
|
||||||
[string]$InstallRoot = "$PSScriptRoot\..\..\third_party"
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
$InstallRoot = [System.IO.Path]::GetFullPath($InstallRoot)
|
|
||||||
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
|
||||||
|
|
||||||
Write-Host "本脚本不会写入系统目录,只在项目 third_party 下准备依赖。"
|
|
||||||
Write-Host "建议方式:"
|
|
||||||
Write-Host "1. 安装 Qt Online Installer 时,将安装目录选择为:$InstallRoot\qt-sdk"
|
|
||||||
Write-Host "2. 安装组件选择 Qt 6.x / MinGW 或 MSVC 版本。"
|
|
||||||
Write-Host "3. 将实际 Qt 编译套件目录复制或软链接到:$InstallRoot\qt"
|
|
||||||
Write-Host " 例如:$InstallRoot\qt-sdk\6.7.3\mingw_64 -> $InstallRoot\qt"
|
|
||||||
Write-Host "4. 下载 OpenCV Windows 预编译包,解压到:$InstallRoot\opencv"
|
|
||||||
Write-Host "5. 然后运行:powershell -ExecutionPolicy Bypass -File scripts\build-windows.ps1"
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "如使用 vcpkg,也请将 vcpkg clone 到项目 tools/vcpkg,不要装到系统目录。"
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
param(
|
|
||||||
[string]$PythonBin = "$PSScriptRoot\..\..\tools\python-bin",
|
|
||||||
[string]$VenvDir = "$PSScriptRoot\..\..\tools\python-venv"
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
$PythonBin = [System.IO.Path]::GetFullPath($PythonBin)
|
|
||||||
$VenvDir = [System.IO.Path]::GetFullPath($VenvDir)
|
|
||||||
$PythonExe = Join-Path $PythonBin "python.exe"
|
|
||||||
|
|
||||||
if (!(Test-Path $PythonExe)) {
|
|
||||||
throw "未找到项目内 Python 二进制:$PythonExe"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Windows embeddable Python 不一定带 venv 模块。优先尝试 venv;失败则使用同目录作为隔离 Python 环境安装 pip。
|
|
||||||
try {
|
|
||||||
& $PythonExe -m venv $VenvDir
|
|
||||||
$VenvPython = Join-Path $VenvDir "Scripts\python.exe"
|
|
||||||
& $VenvPython -m pip install --upgrade pip setuptools wheel
|
|
||||||
& $VenvPython -m pip install aqtinstall
|
|
||||||
Write-Host "已创建虚拟环境:$VenvDir"
|
|
||||||
} catch {
|
|
||||||
Write-Warning "venv 创建失败,改用项目内 embeddable Python 自身作为隔离环境。"
|
|
||||||
& $PythonExe (Join-Path $PythonBin "get-pip.py")
|
|
||||||
& $PythonExe -m pip install --upgrade pip setuptools wheel
|
|
||||||
& $PythonExe -m pip install aqtinstall
|
|
||||||
Write-Host "已在项目内 Python 二进制目录安装 pip/aqtinstall:$PythonBin"
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
ENV_DIR="$ROOT_DIR/tools/linux-build-env"
|
|
||||||
BUILD_DIR="$ROOT_DIR/build-linux"
|
|
||||||
|
|
||||||
if [[ ! -x "$ENV_DIR/bin/cmake" || ! -x "$ENV_DIR/bin/ninja" || ! -x "$ENV_DIR/bin/clang++" ]]; then
|
|
||||||
echo "[build] 未发现项目内 Linux 二进制构建环境,先执行 setup-linux-binary-deps.sh"
|
|
||||||
"$ROOT_DIR/scripts/setup-linux-binary-deps.sh"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export PATH="$ENV_DIR/bin:$PATH"
|
|
||||||
export CMAKE_PREFIX_PATH="$ENV_DIR"
|
|
||||||
export PKG_CONFIG_PATH="$ENV_DIR/lib/pkgconfig:$ENV_DIR/share/pkgconfig:${PKG_CONFIG_PATH:-}"
|
|
||||||
export LD_LIBRARY_PATH="$ENV_DIR/lib:${LD_LIBRARY_PATH:-}"
|
|
||||||
export CC="$ENV_DIR/bin/clang"
|
|
||||||
export CXX="$ENV_DIR/bin/clang++"
|
|
||||||
|
|
||||||
cmake -S "$ROOT_DIR" -B "$BUILD_DIR" \
|
|
||||||
-G Ninja \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
|
|
||||||
-DCMAKE_C_COMPILER="$CC" \
|
|
||||||
-DCMAKE_CXX_COMPILER="$CXX" \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="$ROOT_DIR/dist-linux"
|
|
||||||
|
|
||||||
cmake --build "$BUILD_DIR" --parallel "$(nproc)"
|
|
||||||
|
|
||||||
echo "[build] 构建完成:$BUILD_DIR/chengnan"
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
exec "$ROOT_DIR/scripts/build-linux-binary.sh"
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
param(
|
|
||||||
[ValidateSet("msvc")]
|
|
||||||
[string]$Toolchain = "msvc",
|
|
||||||
[string]$BuildDir = "$PSScriptRoot\..\build-windows",
|
|
||||||
[string]$DistDir = "$PSScriptRoot\..\dist-windows"
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
$ProjectRoot = Resolve-Path "$PSScriptRoot\.."
|
|
||||||
$BuildDir = [System.IO.Path]::GetFullPath($BuildDir)
|
|
||||||
$DistDir = [System.IO.Path]::GetFullPath($DistDir)
|
|
||||||
$PackageName = "chengnan-windows-x86_64"
|
|
||||||
$PackageDir = Join-Path $DistDir $PackageName
|
|
||||||
$ZipPath = Join-Path $DistDir "$PackageName.zip"
|
|
||||||
$HashPath = "$ZipPath.sha256"
|
|
||||||
|
|
||||||
Write-Host "[package] ProjectRoot: $ProjectRoot"
|
|
||||||
Write-Host "[package] BuildDir: $BuildDir"
|
|
||||||
Write-Host "[package] DistDir: $DistDir"
|
|
||||||
|
|
||||||
& "$ProjectRoot\docs\windows\build-windows.ps1" -Toolchain $Toolchain -BuildDir $BuildDir -Deploy
|
|
||||||
|
|
||||||
$DeployDir = Join-Path $BuildDir "deploy"
|
|
||||||
$Exe = Join-Path $DeployDir "chengnan.exe"
|
|
||||||
if (!(Test-Path $Exe)) {
|
|
||||||
throw "未找到部署后的 Windows 可执行文件:$Exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Test-Path $PackageDir) { Remove-Item -Recurse -Force $PackageDir }
|
|
||||||
if (Test-Path $ZipPath) { Remove-Item -Force $ZipPath }
|
|
||||||
if (Test-Path $HashPath) { Remove-Item -Force $HashPath }
|
|
||||||
New-Item -ItemType Directory -Force -Path $DistDir | Out-Null
|
|
||||||
Copy-Item -Recurse -Force $DeployDir $PackageDir
|
|
||||||
|
|
||||||
$ReadmePath = Join-Path $PackageDir "README.txt"
|
|
||||||
@"
|
|
||||||
chengnan Windows x86_64 发布包
|
|
||||||
|
|
||||||
运行方式:
|
|
||||||
1. 解压整个目录。
|
|
||||||
2. 双击 chengnan.exe 运行。
|
|
||||||
|
|
||||||
说明:
|
|
||||||
- 本目录已包含 Qt 运行时和 OpenCV DLL。
|
|
||||||
- 请不要只复制 chengnan.exe,需保留同目录 DLL 和 Qt plugins 子目录。
|
|
||||||
"@ | Set-Content -Encoding UTF8 $ReadmePath
|
|
||||||
|
|
||||||
Compress-Archive -Path (Join-Path $PackageDir "*") -DestinationPath $ZipPath -Force
|
|
||||||
|
|
||||||
$Hash = Get-FileHash -Algorithm SHA256 $ZipPath
|
|
||||||
"$($Hash.Hash.ToLower()) $(Split-Path -Leaf $ZipPath)" | Set-Content -Encoding ASCII $HashPath
|
|
||||||
|
|
||||||
if (!(Test-Path $ZipPath) -or ((Get-Item $ZipPath).Length -le 0)) {
|
|
||||||
throw "发布包生成失败:$ZipPath"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "[package] 发布包:$ZipPath"
|
|
||||||
Write-Host "[package] 校验文件:$HashPath"
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
DOWNLOAD_DIR="$ROOT_DIR/downloads"
|
|
||||||
TOOLS_DIR="$ROOT_DIR/tools"
|
|
||||||
MICROMAMBA_DIR="$TOOLS_DIR/micromamba"
|
|
||||||
MICROMAMBA_BIN="$MICROMAMBA_DIR/bin/micromamba"
|
|
||||||
ENV_DIR="$TOOLS_DIR/linux-build-env"
|
|
||||||
|
|
||||||
mkdir -p "$DOWNLOAD_DIR" "$TOOLS_DIR" "$MICROMAMBA_DIR"
|
|
||||||
|
|
||||||
if [[ ! -x "$MICROMAMBA_BIN" ]]; then
|
|
||||||
echo "[setup] 下载 Linux micromamba 二进制包..."
|
|
||||||
ARCHIVE="$DOWNLOAD_DIR/micromamba-linux-64.tar.bz2"
|
|
||||||
curl -L --fail -o "$ARCHIVE" "https://micro.mamba.pm/api/micromamba/linux-64/latest"
|
|
||||||
tar -xjf "$ARCHIVE" -C "$MICROMAMBA_DIR" bin/micromamba
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -x "$ENV_DIR/bin/cmake" || ! -x "$ENV_DIR/bin/ninja" || ! -x "$ENV_DIR/bin/clang++" ]]; then
|
|
||||||
echo "[setup] 在项目目录内创建 Linux 二进制构建环境..."
|
|
||||||
"$MICROMAMBA_BIN" create -y -p "$ENV_DIR" -c conda-forge \
|
|
||||||
cmake ninja make clangxx qt-main opencv pkg-config patchelf
|
|
||||||
fi
|
|
||||||
|
|
||||||
# README 中约定的路径,使用软链接指向隔离环境,便于 CMake 查找。
|
|
||||||
ln -sfn "linux-build-env" "$TOOLS_DIR/compiler-linux"
|
|
||||||
ln -sfn "linux-build-env" "$TOOLS_DIR/cmake-linux"
|
|
||||||
ln -sfn "linux-build-env" "$TOOLS_DIR/ninja-linux"
|
|
||||||
ln -sfn "linux-build-env" "$TOOLS_DIR/python-bin"
|
|
||||||
ln -sfn "linux-build-env" "$TOOLS_DIR/python-venv"
|
|
||||||
ln -sfn "../tools/linux-build-env" "$ROOT_DIR/third_party/qt-linux"
|
|
||||||
ln -sfn "../tools/linux-build-env" "$ROOT_DIR/third_party/opencv-linux"
|
|
||||||
|
|
||||||
echo "[setup] 完成。所有 Linux 构建工具位于:$ENV_DIR"
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
exec "$ROOT_DIR/scripts/setup-linux-binary-deps.sh"
|
|
||||||
Reference in New Issue
Block a user