移除 Docker 构建路线,改为 host 直装 Qt 5.14.2 + Qt Creator 4.11.0
学生主要用 Windows,Docker 方案不再需要:删掉 tools/docker/ 及 README/HANDOFF/ CMakeLists 里的相关引用(含一处已失效的 docker_run.sh 死链接)。 install_qt_host.sh 现在同时装期号匹配的 Qt Creator 4.11.0:官方 .run 安装器 强制要求 Qt 账号登录且无 Skip 选项,改用 tools/extract_qtcreator_payload.py 直接从 .run 里定位、解出内嵌的 7z payload,绕开账号登录。提取逻辑先解到 staging 目录再原子替换到位,避免中途失败留下部分安装但被判定为"已装"; 候选 7z 复用同一临时文件,不会在磁盘上堆多份安装包大小的临时拷贝。
This commit is contained in:
+1
-1
@@ -45,7 +45,7 @@ if(BUILD_QT_PART)
|
|||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
"Refusing to build Qt examples against Qt ${Qt5Core_VERSION_STRING}: "
|
"Refusing to build Qt examples against Qt ${Qt5Core_VERSION_STRING}: "
|
||||||
"this repo requires the ISOLATED Qt 5.14.x toolchain. "
|
"this repo requires the ISOLATED Qt 5.14.x toolchain. "
|
||||||
"Run via tools/docker/docker_run.sh, or pass -DCMAKE_PREFIX_PATH=/path/to/qt/5.14.2/gcc_64.")
|
"Run tools/install_qt_host.sh, then pass -DCMAKE_PREFIX_PATH=/path/to/qt/5.14.2/gcc_64.")
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|||||||
+5
-8
@@ -52,7 +52,6 @@
|
|||||||
| 仓库骨架(顶层 CMakeLists、.gitignore、tools/、docs/) | ✅ 完成 |
|
| 仓库骨架(顶层 CMakeLists、.gitignore、tools/、docs/) | ✅ 完成 |
|
||||||
| **隔离 Qt 5.14.2 安装**(`.qt514/`,aqtinstall 装在仓库内) | ✅ 完成 |
|
| **隔离 Qt 5.14.2 安装**(`.qt514/`,aqtinstall 装在仓库内) | ✅ 完成 |
|
||||||
| 验证隔离有效:`ldd` 0 系统 Qt 引用、offscreen 运行打印 5.14.2 | ✅ 完成 |
|
| 验证隔离有效:`ldd` 0 系统 Qt 引用、offscreen 运行打印 5.14.2 | ✅ 完成 |
|
||||||
| Docker 构建/安装/运行脚本(构建容器模型) | ✅ 完成(轻量 builder 镜像已构建) |
|
|
||||||
| Part1 C/C++ 源码 + CMakeLists 生成器 | ✅ 可运行(`tools/gen_part1.py`) |
|
| Part1 C/C++ 源码 + CMakeLists 生成器 | ✅ 可运行(`tools/gen_part1.py`) |
|
||||||
| Part1 英文文件名映射表(`tools/file_name_map.py`) | ✅ 完成,113 节全覆盖 |
|
| Part1 英文文件名映射表(`tools/file_name_map.py`) | ✅ 完成,113 节全覆盖 |
|
||||||
| Part1 全部编译通过 | ⚠️ **未完成**:144 个目标,剩 4 个 FAILED |
|
| Part1 全部编译通过 | ⚠️ **未完成**:144 个目标,剩 4 个 FAILED |
|
||||||
@@ -77,8 +76,7 @@ qt-course/
|
|||||||
│ ├── gen_part1.py # Part1 生成器(含 exact_fix、block_classify、wrap_statements、emit_console)
|
│ ├── gen_part1.py # Part1 生成器(含 exact_fix、block_classify、wrap_statements、emit_console)
|
||||||
│ ├── file_name_map.py # (pageId, section_title) → 英文文件名词根(113 条,全覆盖)
|
│ ├── file_name_map.py # (pageId, section_title) → 英文文件名词根(113 条,全覆盖)
|
||||||
│ ├── run.sh / run_qt.sh # 宿主机运行 part1 / Qt 目标(LD_LIBRARY_PATH 隔离)
|
│ ├── run.sh / run_qt.sh # 宿主机运行 part1 / Qt 目标(LD_LIBRARY_PATH 隔离)
|
||||||
│ ├── install_qt_host.sh # 宿主机直装 Qt 5.14.2 到 .qt514/(venv+apt)
|
│ ├── install_qt_host.sh # 宿主机直装 Qt 5.14.2 + Qt Creator 4.11.0 到 .qt514/
|
||||||
│ ├── docker/ # Dockerfile + docker_build_image/install_qt/build.sh
|
|
||||||
│ └── wiki_data/ # 抓取的 wiki 正文+代码块(已拷入,生成器输入)
|
│ └── wiki_data/ # 抓取的 wiki 正文+代码块(已拷入,生成器输入)
|
||||||
├── docs/
|
├── docs/
|
||||||
│ ├── ERRATA.md # Part1 代码修正记录(自动生成,72 条)
|
│ ├── ERRATA.md # Part1 代码修正记录(自动生成,72 条)
|
||||||
@@ -111,12 +109,11 @@ cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON \
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
LD_LIBRARY_PATH=$PWD/.qt514/5.14.2/gcc_64/lib ./tools/run_qt.sh <target> # 或直接 ./tools/run_qt.sh
|
LD_LIBRARY_PATH=$PWD/.qt514/5.14.2/gcc_64/lib ./tools/run_qt.sh <target> # 或直接 ./tools/run_qt.sh
|
||||||
|
|
||||||
# 装/重装隔离 Qt 5.14.2(宿主机,一次性)
|
# 装/重装隔离 Qt 5.14.2(宿主机,一次性;同时装 Qt Creator 4.11.0)
|
||||||
tools/install_qt_host.sh
|
tools/install_qt_host.sh
|
||||||
# 或用容器装:tools/docker/docker_install_qt.sh(需先 tools/docker/docker_build_image.sh)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**隔离 Qt 核心事实**(已验证):靶机=gcc13+glibc2.39;容器与宿主机同栈;二进制容器编译宿主机运行;`.qt514` 是唯一真相源;`ldd` 0 系统 Qt 引用;`QT_QPA_PLATFORM=offscreen` 可无 X 运行验证。
|
**隔离 Qt 核心事实**(已验证):`.qt514` 是唯一真相源;`ldd` 0 系统 Qt 引用;`QT_QPA_PLATFORM=offscreen` 可无 X 运行验证。学生主要用 Windows,构建/运行方案不引入 Docker。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -182,7 +179,7 @@ tools/install_qt_host.sh
|
|||||||
- 语言全是 C++(`.cpp`)。
|
- 语言全是 C++(`.cpp`)。
|
||||||
- 英文文件名映射表 `file_name_map.py` 里目前**只有 Part1**;Part3 需新增 pageId 58954515–58954552 的映射(约 16–25 个 section)。
|
- 英文文件名映射表 `file_name_map.py` 里目前**只有 Part1**;Part3 需新增 pageId 58954515–58954552 的映射(约 16–25 个 section)。
|
||||||
|
|
||||||
**验证**:Docker 容器构建 → host offscreen 运行(`QT_QPA_PLATFORM=offscreen ./tools/run_qt.sh <target>`),用 `QTimer` 自动退出、捕获 stdout/退出码确认。需 X 真窗时给 DISPLAY。
|
**验证**:host 构建 → offscreen 运行(`QT_QPA_PLATFORM=offscreen ./tools/run_qt.sh <target>`),用 `QTimer` 自动退出、捕获 stdout/退出码确认。需 X 真窗时给 DISPLAY。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -207,7 +204,7 @@ tools/install_qt_host.sh
|
|||||||
1. 读本手册 + `tools/gen_part1.py` + `tools/gen_sources.py` 了解生成器。
|
1. 读本手册 + `tools/gen_part1.py` + `tools/gen_sources.py` 了解生成器。
|
||||||
2. 修 Part1 剩余 4 个 FAILED(§4):补 `<cstring>`、namespace 提升 41/42、dedupe 重载集。重建到 144/144 全绿。
|
2. 修 Part1 剩余 4 个 FAILED(§4):补 `<cstring>`、namespace 提升 41/42、dedupe 重载集。重建到 144/144 全绿。
|
||||||
3. 应用深缩写目录(§5):改 `PAGE_CONFIG` 的 dir 为 p/ch/s,全量重建确认路径。
|
3. 应用深缩写目录(§5):改 `PAGE_CONFIG` 的 dir 为 p/ch/s,全量重建确认路径。
|
||||||
4. 写 `gen_part3.py` + 扩 `file_name_map.py`;生成 Part3;Docker/host 构建;offscreen 运行验证。
|
4. 写 `gen_part3.py` + 扩 `file_name_map.py`;生成 Part3;host 构建;offscreen 运行验证。
|
||||||
5. 写 `std_probe.py` + `tools/demo_versions/`;填 `docs/VERSION_NOTES.md`。
|
5. 写 `std_probe.py` + `tools/demo_versions/`;填 `docs/VERSION_NOTES.md`。
|
||||||
6. 写 `docs/SOURCE_PAGES.md`(pageId→章节映射表)、各章 README、顶层 README。
|
6. 写 `docs/SOURCE_PAGES.md`(pageId→章节映射表)、各章 README、顶层 README。
|
||||||
7. 全量 clean build,`git add -A && git commit`(**目前 0 提交,务必最后提交一次**)。
|
7. 全量 clean build,`git add -A && git commit`(**目前 0 提交,务必最后提交一次**)。
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ qt-course/
|
|||||||
│ ├── std_probe.py 跨 -std= 编译探针(任务 1 机制)
|
│ ├── std_probe.py 跨 -std= 编译探针(任务 1 机制)
|
||||||
│ ├── demo_versions/ 版本相关论断的最小演示片段
|
│ ├── demo_versions/ 版本相关论断的最小演示片段
|
||||||
│ ├── run.sh / run_qt.sh 宿主机运行 p01 / p03 目标(Qt 走 LD_LIBRARY_PATH 隔离)
|
│ ├── run.sh / run_qt.sh 宿主机运行 p01 / p03 目标(Qt 走 LD_LIBRARY_PATH 隔离)
|
||||||
│ ├── install_qt_host.sh 宿主机直装隔离 Qt 5.14.2 到 .qt514/
|
│ ├── install_qt_host.sh 宿主机直装隔离 Qt 5.14.2 + Qt Creator 4.11.0 到 .qt514/
|
||||||
│ ├── docker/ 构建容器模型(Dockerfile + 脚本)
|
|
||||||
│ └── wiki_data/ 抓取的 wiki 正文+代码块(生成器输入,只读)
|
│ └── wiki_data/ 抓取的 wiki 正文+代码块(生成器输入,只读)
|
||||||
├── docs/
|
├── docs/
|
||||||
│ ├── ERRATA.md Part1 代码修正记录(自动生成)
|
│ ├── ERRATA.md Part1 代码修正记录(自动生成)
|
||||||
@@ -52,7 +51,6 @@ cmake --build build --target all_p01_ch04_s03 # 只构建某章
|
|||||||
```bash
|
```bash
|
||||||
# 一次性:装隔离 Qt 5.14.2(装到 .qt514/,不碰系统 Qt 5.15)
|
# 一次性:装隔离 Qt 5.14.2(装到 .qt514/,不碰系统 Qt 5.15)
|
||||||
tools/install_qt_host.sh
|
tools/install_qt_host.sh
|
||||||
# 或用容器:tools/docker/docker_build_image.sh && tools/docker/docker_install_qt.sh
|
|
||||||
|
|
||||||
cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON \
|
cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON \
|
||||||
-DCMAKE_PREFIX_PATH=$PWD/.qt514/5.14.2/gcc_64 -DCMAKE_BUILD_TYPE=Debug
|
-DCMAKE_PREFIX_PATH=$PWD/.qt514/5.14.2/gcc_64 -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
# ==============================================================================
|
|
||||||
# Build-container image for the qt-course repo.
|
|
||||||
#
|
|
||||||
# Usage model (see docker_install_qt.sh / docker_build.sh / docker_run_qt.sh):
|
|
||||||
# 1. Install isolated Qt 5.14.2 INTO THE REPO at .qt514/ (one-off, ~577MB).
|
|
||||||
# The Qt files live on the host filesystem, mounted into the container.
|
|
||||||
# 2. Build the Qt part from a container, writing into the mounted build/.
|
|
||||||
# 3. RUN the compiled Qt apps on the HOST (no container needed) using
|
|
||||||
# LD_LIBRARY_PATH=.qt514/.../lib — host & container share glibc 2.39,
|
|
||||||
# so binaries built in the container run natively on the host. Isolation
|
|
||||||
# from the system Qt 5.15 is by prefix + LD_LIBRARY_PATH, not by the
|
|
||||||
# container boundary.
|
|
||||||
#
|
|
||||||
# This image only needs the build toolchain + aqtinstall. It is small and
|
|
||||||
# stable (no multi-GB Qt layer baked in; Qt is downloaded into the mount).
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
FROM ubuntu:24.04
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
ENV TZ=Asia/Shanghai
|
|
||||||
|
|
||||||
# Build toolchain matching the host (gcc 13.3, cmake 3.28, ninja) + runtime
|
|
||||||
# libs so the container can also run GUI examples with X11 forwarding if needed.
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
build-essential g++ gcc cmake ninja-build git \
|
|
||||||
ca-certificates python3 python3-pip python3-venv \
|
|
||||||
libgl1 libegl1 libxkbcommon0 libdbus-1-3 \
|
|
||||||
libfontconfig1 libfreetype6 libxcb-cursor0 \
|
|
||||||
fontconfig xauth x11-xserver-utils \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN pip3 install --break-system-packages aqtinstall
|
|
||||||
|
|
||||||
WORKDIR /workspace
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Build-container: run ONE build pass of the repo (CMake configure + compile),
|
|
||||||
# mounting the repo so build artifacts land on the host filesystem.
|
|
||||||
#
|
|
||||||
# Usage: tools/docker/docker_build.sh [extra cmake args...]
|
|
||||||
# It builds BOTH part1 (C/C++) and part3 (Qt) unless you pass args to restrict.
|
|
||||||
# The Qt part is pointed at the isolated .qt514/ toolchain.
|
|
||||||
#
|
|
||||||
# After this, run compiled apps on the HOST with tools/run_qt.sh / tools/run.sh.
|
|
||||||
set -euo pipefail
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
||||||
IMAGE_TAG="qt-course:builder"
|
|
||||||
QT_ROOT="/workspace/.qt514/5.14.2/gcc_64"
|
|
||||||
|
|
||||||
if [ ! -x "$REPO_ROOT/.qt514/5.14.2/gcc_64/bin/qmake" ]; then
|
|
||||||
echo ">> Isolated Qt not found at .qt514/. Run tools/docker/docker_install_qt.sh first." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker run --rm \
|
|
||||||
-v "$REPO_ROOT:/workspace" \
|
|
||||||
-w /workspace \
|
|
||||||
"$IMAGE_TAG" \
|
|
||||||
bash -lc "
|
|
||||||
set -e
|
|
||||||
cmake -S . -B build -G Ninja \
|
|
||||||
-DBUILD_QT_PART=ON \
|
|
||||||
-DCMAKE_PREFIX_PATH='${QT_ROOT}' \
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug \
|
|
||||||
$*
|
|
||||||
cmake --build build --parallel
|
|
||||||
"
|
|
||||||
echo ">> Build done. Run on host: tools/run.sh <target> (Qt targets: tools/run_qt.sh <target>)"
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Build the lightweight build-container image (toolchain + aqtinstall, no Qt baked in).
|
|
||||||
# Usage: tools/docker/docker_build_image.sh
|
|
||||||
set -euo pipefail
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
||||||
IMAGE_TAG="qt-course:builder"
|
|
||||||
echo ">> Building image ${IMAGE_TAG} ..."
|
|
||||||
docker build -t "$IMAGE_TAG" -f "$REPO_ROOT/tools/docker/Dockerfile" "$REPO_ROOT/tools/docker"
|
|
||||||
echo ">> Done. Next: tools/docker/docker_install_qt.sh (downloads Qt 5.14.2 into .qt514/)"
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Install the ISOLATED Qt 5.14.2 toolchain into the repo at .qt514/ using the
|
|
||||||
# build container (keeps the host free of aqtinstall deps; Qt files land on the
|
|
||||||
# host filesystem via the mount so the host can build/run against them later).
|
|
||||||
#
|
|
||||||
# Usage: tools/docker/docker_install_qt.sh
|
|
||||||
# Idempotent: re-running refreshes/repairs the install.
|
|
||||||
set -euo pipefail
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
||||||
IMAGE_TAG="qt-course:builder"
|
|
||||||
QT_DEST="/workspace/.qt514"
|
|
||||||
QT_VERSION="5.14.2"
|
|
||||||
|
|
||||||
if ! docker image inspect "$IMAGE_TAG" >/dev/null 2>&1; then
|
|
||||||
echo ">> image ${IMAGE_TAG} not found; building it first." >&2
|
|
||||||
"$REPO_ROOT/tools/docker/docker_build_image.sh"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$REPO_ROOT/.qt514"
|
|
||||||
echo ">> Installing Qt ${QT_VERSION} gcc_64 into $REPO_ROOT/.qt514/ (via container)..."
|
|
||||||
docker run --rm \
|
|
||||||
-v "$REPO_ROOT:/workspace" \
|
|
||||||
"$IMAGE_TAG" \
|
|
||||||
aqt install-qt linux desktop "${QT_VERSION}" gcc_64 -O "${QT_DEST}"
|
|
||||||
|
|
||||||
# Verify on the host (no container needed for this read).
|
|
||||||
QT_ROOT="$REPO_ROOT/.qt514/${QT_VERSION}/gcc_64"
|
|
||||||
echo ">> Verify (host):"
|
|
||||||
"$QT_ROOT/bin/qmake" -query QT_VERSION
|
|
||||||
echo ">> Qt installed at: $QT_ROOT"
|
|
||||||
echo ">> Now build with: tools/docker/docker_build.sh (or host cmake, see README)"
|
|
||||||
Executable
+81
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Extract the Qt Creator payload from a QtIFW .run installer without running
|
||||||
|
its GUI. The official .run for Qt Creator (this vintage) hard-gates the wizard
|
||||||
|
behind a mandatory Qt account login with no Skip option, so the GUI/script
|
||||||
|
automation route is a dead end. The installer binary is a self-extracting
|
||||||
|
QtIFW archive: an ELF stub with one or more embedded 7z streams appended.
|
||||||
|
The real payload (bin/, lib/, share/, libexec/) lives in one of those streams;
|
||||||
|
this scans for the 7z magic, tries each occurrence, and keeps the one whose
|
||||||
|
contents include bin/qtcreator.
|
||||||
|
|
||||||
|
Usage: extract_qtcreator_payload.py <installer.run> <dest_dir>
|
||||||
|
"""
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import py7zr
|
||||||
|
|
||||||
|
MAGIC = b"7z\xbc\xaf\x27\x1c"
|
||||||
|
|
||||||
|
|
||||||
|
def find_offsets(data: bytes) -> list[int]:
|
||||||
|
offsets = []
|
||||||
|
start = 0
|
||||||
|
while True:
|
||||||
|
i = data.find(MAGIC, start)
|
||||||
|
if i == -1:
|
||||||
|
break
|
||||||
|
offsets.append(i)
|
||||||
|
start = i + 1
|
||||||
|
return offsets
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print(__doc__)
|
||||||
|
return 2
|
||||||
|
run_path = Path(sys.argv[1])
|
||||||
|
dest_dir = Path(sys.argv[2])
|
||||||
|
|
||||||
|
data = run_path.read_bytes()
|
||||||
|
offsets = find_offsets(data)
|
||||||
|
if not offsets:
|
||||||
|
print("no 7z signature found in installer", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
candidate = Path(tmp) / "candidate.7z"
|
||||||
|
staging = Path(tmp) / "staging"
|
||||||
|
for off in offsets:
|
||||||
|
# Overwrite the same candidate file each iteration so failed
|
||||||
|
# attempts don't accumulate on disk (offsets can be ~installer-size apart).
|
||||||
|
candidate.write_bytes(data[off:])
|
||||||
|
try:
|
||||||
|
with py7zr.SevenZipFile(candidate, mode="r") as z:
|
||||||
|
names = z.getnames()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
if "bin/qtcreator" not in names:
|
||||||
|
continue
|
||||||
|
print(f">> payload found at offset {off} ({len(names)} entries)")
|
||||||
|
# Extract into a staging dir first and only move it into dest_dir
|
||||||
|
# once extraction fully succeeds, so a crash/disk-full mid-extract
|
||||||
|
# never leaves a partially-populated dest_dir that later runs
|
||||||
|
# would mistake for a complete install.
|
||||||
|
with py7zr.SevenZipFile(candidate, mode="r") as z:
|
||||||
|
z.extractall(path=staging)
|
||||||
|
if dest_dir.exists():
|
||||||
|
shutil.rmtree(dest_dir)
|
||||||
|
dest_dir.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.move(str(staging), str(dest_dir))
|
||||||
|
print(f">> extracted to {dest_dir}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("no offset yielded a payload containing bin/qtcreator", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
# * 资源依赖(:/images/*.png 等)用脚本生成的纯色占位 png + .qrc 提供,qt5_add_resources。
|
# * 资源依赖(:/images/*.png 等)用脚本生成的纯色占位 png + .qrc 提供,qt5_add_resources。
|
||||||
# * Qt 代码修正(笔误/平台/过时 API)每处 record_erratum 进 docs/ERRATA.md(透明可审计)。
|
# * Qt 代码修正(笔误/平台/过时 API)每处 record_erratum 进 docs/ERRATA.md(透明可审计)。
|
||||||
#
|
#
|
||||||
# 验证:Docker 容器或宿主机用隔离 Qt 5.14.2 构建 →
|
# 验证:宿主机用隔离 Qt 5.14.2 构建 →
|
||||||
# QT_QPA_PLATFORM=offscreen tools/run_qt.sh <target> 自动退出验证。
|
# QT_QPA_PLATFORM=offscreen tools/run_qt.sh <target> 自动退出验证。
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import json, os, re, sys
|
import json, os, re, sys
|
||||||
|
|||||||
@@ -1,22 +1,26 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Install the ISOLATED Qt 5.14.2 toolchain into .qt514/ DIRECTLY ON THE HOST
|
# Install the ISOLATED Qt 5.14.2 toolchain + matching Qt Creator into .qt514/
|
||||||
# (no Docker), using a local venv for aqtinstall. The host already has the right
|
# directly on the host, using a local venv for aqtinstall. The host already
|
||||||
# toolchain (gcc 13.3, cmake 3.28); this just fetches Qt files into the repo.
|
# has the right toolchain (gcc 13.3, cmake 3.28); this just fetches files
|
||||||
|
# into the repo. No container involved (students are mostly on Windows).
|
||||||
#
|
#
|
||||||
# Usage: tools/install_qt_host.sh
|
# Usage: tools/install_qt_host.sh
|
||||||
# Prefer this over docker_install_qt.sh when you don't need a container.
|
|
||||||
# Verified: a binary built against .qt514/ links ONLY to .qt514/ (ldd shows 0
|
# Verified: a binary built against .qt514/ links ONLY to .qt514/ (ldd shows 0
|
||||||
# system-Qt refs) and runs on the host with tools/run_qt.sh.
|
# system-Qt refs) and runs on the host with tools/run_qt.sh.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
VENV="$REPO_ROOT/.venv-aqt"
|
VENV="$REPO_ROOT/.venv-aqt"
|
||||||
QT_VERSION="5.14.2"
|
QT_VERSION="5.14.2"
|
||||||
|
CREATOR_VERSION="4.11.0"
|
||||||
|
CREATOR_DIR="$REPO_ROOT/.qt514/Tools/QtCreator"
|
||||||
|
CREATOR_URL="https://download.qt.io/archive/qtcreator/${CREATOR_VERSION%.*}/${CREATOR_VERSION}/qt-creator-opensource-linux-x86_64-${CREATOR_VERSION}.run"
|
||||||
|
|
||||||
if [ ! -x "$VENV/bin/aqt" ]; then
|
if [ ! -x "$VENV/bin/aqt" ]; then
|
||||||
echo ">> Creating local venv with aqtinstall at $VENV ..."
|
echo ">> Creating local venv with aqtinstall at $VENV ..."
|
||||||
python3 -m venv "$VENV" --system-site-packages
|
python3 -m venv "$VENV" --system-site-packages
|
||||||
"$VENV/bin/pip" install --quiet aqtinstall
|
"$VENV/bin/pip" install --quiet aqtinstall
|
||||||
fi
|
fi
|
||||||
|
"$VENV/bin/pip" show py7zr >/dev/null 2>&1 || "$VENV/bin/pip" install --quiet py7zr
|
||||||
|
|
||||||
echo ">> Installing Qt ${QT_VERSION} gcc_64 into $REPO_ROOT/.qt514/ ..."
|
echo ">> Installing Qt ${QT_VERSION} gcc_64 into $REPO_ROOT/.qt514/ ..."
|
||||||
"$VENV/bin/aqt" install-qt linux desktop "${QT_VERSION}" gcc_64 -O "$REPO_ROOT/.qt514"
|
"$VENV/bin/aqt" install-qt linux desktop "${QT_VERSION}" gcc_64 -O "$REPO_ROOT/.qt514"
|
||||||
@@ -25,5 +29,26 @@ QT_ROOT="$REPO_ROOT/.qt514/${QT_VERSION}/gcc_64"
|
|||||||
echo ">> Verify:"
|
echo ">> Verify:"
|
||||||
"$QT_ROOT/bin/qmake" -query QT_VERSION
|
"$QT_ROOT/bin/qmake" -query QT_VERSION
|
||||||
echo ">> Qt installed at: $QT_ROOT"
|
echo ">> Qt installed at: $QT_ROOT"
|
||||||
echo ">> Build on host: cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON -DCMAKE_PREFIX_PATH='$QT_ROOT' && cmake --build build"
|
|
||||||
echo ">> Run Qt targets: tools/run_qt.sh <target>"
|
# Qt Creator ${CREATOR_VERSION} (period-matched to Qt ${QT_VERSION}). The official
|
||||||
|
# .run installer for this vintage hard-gates its wizard behind a mandatory Qt
|
||||||
|
# account login with no Skip option, so we pull the .run and lift its embedded
|
||||||
|
# payload directly instead of driving the GUI. See tools/extract_qtcreator_payload.py.
|
||||||
|
if [ -x "$CREATOR_DIR/bin/qtcreator" ]; then
|
||||||
|
echo ">> Qt Creator already installed at $CREATOR_DIR, skipping."
|
||||||
|
else
|
||||||
|
echo ">> Downloading Qt Creator ${CREATOR_VERSION} .run installer ..."
|
||||||
|
CREATOR_RUN="$(mktemp -t qtcreator-XXXXXX.run)"
|
||||||
|
trap 'rm -f "$CREATOR_RUN"' EXIT
|
||||||
|
curl -sL -o "$CREATOR_RUN" "$CREATOR_URL"
|
||||||
|
echo ">> Extracting Qt Creator payload (bypassing account-gated GUI) ..."
|
||||||
|
"$VENV/bin/python3" "$REPO_ROOT/tools/extract_qtcreator_payload.py" "$CREATOR_RUN" "$CREATOR_DIR"
|
||||||
|
rm -f "$CREATOR_RUN"
|
||||||
|
trap - EXIT
|
||||||
|
fi
|
||||||
|
echo ">> Qt Creator installed at: $CREATOR_DIR"
|
||||||
|
"$CREATOR_DIR/bin/qtcreator" -version 2>&1 | grep "^Qt Creator" || true
|
||||||
|
|
||||||
|
echo ">> Build on host: cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON -DCMAKE_PREFIX_PATH='$QT_ROOT' && cmake --build build"
|
||||||
|
echo ">> Run Qt targets: tools/run_qt.sh <target>"
|
||||||
|
echo ">> Open Qt Creator: tools/run_qtcreator.sh"
|
||||||
|
|||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Launch the ISOLATED Qt Creator 4.11.0 installed into .qt514/Tools/QtCreator
|
||||||
|
# (period-matched to the isolated Qt 5.14.2 SDK), wired to open this repo's
|
||||||
|
# CMakeLists.txt against .qt514/ by default.
|
||||||
|
# Usage: tools/run_qtcreator.sh [args...]
|
||||||
|
# -settingspath keeps this Creator's config separate from any system/other
|
||||||
|
# Qt Creator install on the host (avoids config-format crashes across versions).
|
||||||
|
set -euo pipefail
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
QT_ROOT="$REPO_ROOT/.qt514/5.14.2/gcc_64"
|
||||||
|
CREATOR_BIN="$REPO_ROOT/.qt514/Tools/QtCreator/bin/qtcreator"
|
||||||
|
export CMAKE_PREFIX_PATH="$QT_ROOT${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}"
|
||||||
|
exec "$CREATOR_BIN" -settingspath "$REPO_ROOT/.qt514/qtcreator-settings" "$@"
|
||||||
Reference in New Issue
Block a user