Imported from rpan2022/qnx-800-study (
AGENTS.md). Install upstream withnpx skills add rpan2022/qnx-800-study. Copyright stays with the author.
AGENTS.md
QNX SDP 8.0 C++20 hello-world 项目,用于验证跨平台 QNX 8.0 C++ 交叉编译环境。
项目已做可移植化处理:无硬编码用户路径,CMake Presets 自包含环境(基于 %USERPROFILE%),VS Code 开箱即用。
目标平台:x86_64(QEMU 仿真)、aarch64le(Raspberry Pi 4/5)。开发主机:Windows。
Session Startup Hook(会话启动指令)
每次新 agent 会话开始时,必须遵循以下环境规则:
- CMake 构建(
cmake --preset/scripts\build.bat):无需手动加载环境,CMake Preset 自包含 QNX 环境变量。 - 直接调用 QNX 工具链(
ntox86_64-g++、ntoaarch64-g++、mkifs、nto*-objdump、nto*-gdb等):必须先加载环境,因为每个 Shell 调用是独立进程,环境变量不跨调用持久。直接用 exec 模式:scripts\load-env.bat <command>(推荐,自动 load-env 后执行命令)cmd /c "call scripts\load-env.bat && <command>"
- cmake 不在系统 PATH:命令行调用时使用
.env中CMAKE_EXE指定的完整路径,或通过scripts\build.bat/scripts\load-env.bat间接调用。 - 验证环境是否就绪:
scripts\load-env.bat ntox86_64-g++ --version应输出 GCC 12.2.0。
快速构建
CMake Presets(VS Code / 命令行通用)
Preset 已内置 QNX 环境变量和 Ninja 路径(基于 %USERPROFILE% 自动解析),无需预先 source 任何脚本:
cmake --preset qnx-x86_64-debug :: QEMU x86_64, Debug
cmake --build --preset qnx-x86_64-debug
cmake --preset qnx-aarch64le-debug :: Raspberry Pi AArch64, Debug
cmake --build --preset qnx-aarch64le-debug
VS Code CMake Tools 扩展:直接在状态栏选择 preset,点 Build 即可。
一键批量构建
scripts\build.bat :: 构建全部 4 个 preset
scripts\build.bat qnx-x86_64-debug :: 构建指定 preset
scripts\build.bat clean :: 清理 build/
可用 preset:qnx-x86_64-debug / qnx-x86_64-release / qnx-aarch64le-debug / qnx-aarch64le-release。
产物输出到 build/<preset名>/hello(ELF64 PIE,无 .exe 后缀)。
环境变量
.env 配置文件(推荐)
项目根目录的 .env 文件集中管理所有环境变量,已加入 .gitignore(不提交)。模板为 .env-demo(提交到 git)。
加载方式:
call scripts\load-env.bat
该脚本读取 .env,设置 QNX_BASE / QNX_HOST / QNX_TARGET / QNX_CONFIGURATION / MAKEFLAGS / PYTHONDONTWRITEBYTECODE,并将 QNX 工具链追加到 PATH。.env 不存在时自动使用默认值(%USERPROFILE%\qnx800)。
scripts\build.bat 会自动调用 load-env.bat,无需手动加载。
CMake Preset 自包含
CMake Presets 也内置了 QNX 环境变量(基于 %USERPROFILE%\qnx800 默认安装位置),运行 cmake --preset 时自动生效,无需预先 load-env:
| 变量 | 值 |
|---|---|
QNX_BASE |
%USERPROFILE%\qnx800 |
QNX_HOST |
%USERPROFILE%\qnx800\host\win64\x86_64 |
QNX_TARGET |
%USERPROFILE%\qnx800\target\qnx |
PATH |
追加 QNX 工具链 + VS2022 Ninja(Community/Pro/Enterprise/BuildTools 全版本自动检测) |
工具链文件 cmake/qnx800-*.cmake 具备三级解析:环境变量 → QNX_BASE 推导 → ~/qnx800 默认回退,并在 CMake 进程中导出 QNX_HOST/QNX_TARGET 供原生编译器使用。
直接调用编译器(不走 CMake 时)
使用 exec 模式,加载环境后直接执行命令:
scripts\load-env.bat ntox86_64-g++ -std=c++20 src/hello/src/hello.cpp -o hello
或在交互终端中先加载环境,再连续调用:
call scripts\load-env.bat
ntox86_64-g++ --version
ntoaarch64-g++ --version
也可使用 SDP 自带脚本(功能等价):
%QNX_BASE%\qnxsdp-env.bat
非默认安装位置
QNX 装在 %USERPROFILE%\qnx800 以外的路径时,创建 CMakeUserPresets.json(已 gitignore):
{
"version": 6,
"configurePresets": [{
"name": "qnx-x86_64-debug",
"inherits": "qnx-x86_64-debug",
"environment": { "QNX_BASE": "D:\\custom\\qnx800" }
}],
"buildPresets": [{
"name": "qnx-x86_64-debug",
"configurePreset": "qnx-x86_64-debug",
"environment": { "QNX_BASE": "D:\\custom\\qnx800" }
}]
}
SDP 安装与工具链
安装概览
| 组件 | 路径 | 版本/状态 |
|---|---|---|
| QNX SDP 8.0 | %QNX_BASE%(默认 %USERPROFILE%\qnx800) |
8.0.0,已安装 |
| QNX Software Center | C:\QNX\QNX Software Center |
2025-01 构建 |
| QNX Momentics IDE | C:\QNX\qnxmomenticside |
基于 Eclipse,启动器 qde.exe |
| 许可证 | %USERPROFILE%\.qnx\license\ |
QNX Everywhere 非商业许可证,已激活 |
| QSC 配置 | %USERPROFILE%\.qnx\qconfig\com.qnx.qnx800_1.xml |
安装名 qnx800 |
工具链详情
- 编译器:原生 GCC 前端
nto{arch}-gcc(C)/nto{arch}-g++(C++),GCC 12.2.0 后端,支持 C++17/20 - 传统驱动:
qcc/q++仍可用,但 SDP 8.0 中-lang-c++已弃用会产生警告;本项目使用原生 GCC 前端 - 调试器:GDB 14.2
- binutils:2.43.0
- make:GNU Make(
make.exe) - CMake / Ninja:VS2022 Community 自带(CMake 3.31.6 + Ninja 1.12.1),路径
C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\;cmake 未加入系统 PATH,需用完整路径或在 VS Code 中使用
支持的编译目标
| 原生编译器前缀 | 目标架构 | 用途 |
|---|---|---|
ntox86_64-gcc/g++ |
x86_64 | QEMU x86_64 虚拟目标(默认) |
ntoaarch64-gcc/g++ |
AArch64 小端 | Raspberry Pi 4/5、ARM 开发板 |
完整工具前缀:
- x86_64:
ntox86_64-gcc、ntox86_64-g++、x86_64-pc-nto-qnx8.0.0-* - AArch64:
ntoaarch64-gcc、ntoaarch64-g++、aarch64-unknown-nto-qnx8.0.0-*
Target 目录结构
%QNX_BASE%\target\qnx\
├── aarch64le\ # ARM64 目标头文件和库
├── x86_64\ # x86_64 目标头文件和库
├── etc\ # 目标系统配置
├── sbin\ # 系统二进制
└── usr\ # 用户空间库、头文件、工具
Host 工具:
%QNX_BASE%\host\
├── win64\x86_64\ # Windows 主机工具
└── common\bin\ # 跨平台通用工具
已安装 Target 包清单
核心系统:微内核核心、kdumper、libslog2、slogger2、进程管理、slm、shutdown、libc、libm、C++ 标准库(18.0.0)、libregex、libxml2
网络:io-sock 网络栈(QNX 8.0 唯一网络栈)、OpenSSH、tcpdump、iperf2/3、curl、NFS client、NTP、mdnsresponder;网卡驱动:virtio(QEMU)、genet(Pi 4)、cgem、dwceqos、ffec、USB 网络;PHY 驱动:brgphy、adinphy 等
文件系统:extfs、dosfs、qnx6fs、squashfs、udffs、cndfs、flash3;压缩:zstd、lz4、lzma、bzip2、libz、lzo2;镜像工具:mkifs、mkxfs、mkqfs、mkqnx6fsimg、mkshadow、dumpifs、dumpefs
图形与多媒体:Screen Graphics 框架(screen.base)、视频采集(video_capture)、Kalman 触摸滤波、设备输入(devh)、键盘驱动
安全:OpenSSL 3.0、qcrypto 框架、PKCS#11、cryptodev、secpol 安全策略、PAM 认证、随机数生成器、TCG
硬件与连接:CAN 总线、I2C、SPI BSP 驱动、DMA、DVFS、Flash 驱动、PCI 子系统(含 x86 硬件支持)、字符设备、串口(devc、io_char)
开源包(OSR):toybox 0.8.11、bsdtar 3.8.1、less、libffi、sqlite3、Python 3.13
关键路径
| 项 | 路径 |
|---|---|
| 环境变量配置 | .env(本机,gitignore)/ .env-demo(模板) |
| 环境加载/执行 | scripts/load-env.bat(无参=加载环境到终端;带参=加载后执行命令) |
| CMake 工具链文件(项目内) | cmake/qnx800-{x86_64,aarch64le}.cmake |
| QNX SDP 8.0 | 默认 %USERPROFILE%\qnx800(可通过 .env 或 CMakeUserPresets.json 覆盖) |
| CMake / Ninja | VS2022 Community 自带,cmake 未在系统 PATH(.env 中 CMAKE_EXE 指定) |
| 一键构建脚本 | scripts/build.bat(自动 load-env) |
| QEMU 自动化运行 | scripts/run-qemu-auto.ps1 [-Binary path] [-Timeout secs] |
验证状态
2026-08-23 已通过实际编译验证(C++20 + 原生 GCC 前端):
ntox86_64-g++ -std=c++20— 成功,ELF x86-64 PIE,零警告ntoaarch64-g++ -std=c++20— 成功,ELF AArch64 PIE,零警告- CMake preset 交叉编译 — x86_64 + aarch64le 均生成 ELF64 PIE(Debug/Release 共 4 个 preset)
- QEMU x86_64 运行闭环 — 已通过(multiboot IFS +
qemu-system-x86_64 -kernel)
hello.cpp 使用 C++20 consteval 演示:
#include <iostream>
#include <string_view>
consteval std::string_view make_greeting() {
return "Hello QNX SDP 8.0 (C++20)";
}
int main() {
constexpr auto greeting = make_greeting();
std::cout << greeting << '\n';
return 0;
}
项目结构
.
├── README.md # 学习模板入口(快速开始、文档索引、学习路线)
├── .env # 本机环境变量(gitignore,不提交)
├── .env-demo # 环境变量模板(提交 git)
├── CMakeLists.txt # 顶层 CMake(全局 C++20 设置 + 模块汇总)
├── CMakePresets.json # 4 个 preset(双架构 × Debug/Release),自包含环境
├── .gitignore
├── .clang-format # clang-format 配置(LLVM 基础,C++20,4 空格缩进)
├── .clang-format-ignore # 批量格式化时排除的路径
├── cmake/ # 项目内工具链文件(可移植,三级路径解析)
│ ├── qnx800-x86_64.cmake
│ └── qnx800-aarch64le.cmake
├── src/ # 功能模块(每个子目录 = 一个独立可执行文件)
│ ├── CMakeLists.txt # 模块汇总(add_subdirectory)
│ └── hello/ # 模块:C++20 consteval 问候演示
│ ├── CMakeLists.txt
│ ├── include/ # 模块头文件(预留)
│ └── src/
│ └── hello.cpp
├── scripts/
│ ├── build.bat # 一键批量构建 / 清理(自动 load-env)
│ ├── load-env.bat # 加载 .env(无参=加载到终端;带参=加载后执行命令)
│ ├── run-qemu-auto.ps1 # QEMU x86_64 自动化运行(构建IFS→启动→捕获输出→自动退出)
│ └── format.bat # clang-format 批量格式化 / 检查
├── qemu/ # QEMU 运行时工作目录(生成 IFS 镜像、复制二进制、输出日志)
├── skills/
│ ├── run-qemu-simulation/ # QEMU 仿真 Skill(运行 ELF、捕获串口输出)
│ │ ├── SKILL.md
│ │ ├── scripts/ # build-ifs.bat / run-qemu.bat / qemu-x86_64.build
│ │ └── references/ # qemu-technical-notes.md
│ └── add-new-module/ # 功能模块 Skill(脚手架 + 格式检查 + 构建验证)
│ ├── SKILL.md
│ ├── scripts/ # add-module.bat / verify-module.bat
│ └── references/ # module-templates.md
├── todo/ # 学习路线与任务追踪
│ ├── study-00-roadmap.md # 总路线图(应用场景、阶段路径、进阶方向、Rust、资源)
│ ├── study-01-posix-programming.md
│ ├── study-02-message-passing.md
│ ├── study-03-resource-manager.md
│ ├── study-04-realtime-performance.md
│ ├── study-05-ros2-on-qnx.md
│ ├── study-06-iceoryx2-zerocopy.md
│ ├── study-07-hypervisor.md
│ ├── study-08-driver-bsp.md
│ ├── study-09-functional-safety.md
│ └── study-10-resources.md
├── .vscode/ # QNX Toolkit 扩展生成的配置
└── docs/
└── ide_tools.md # Momentics IDE / VS Code Toolkit / 命令行对比
注:原
docs/QNX8_BUILD_ENV.md的 SDP 安装、环境变量、工具链、Target 包清单等内容已预加载到本 AGENTS.md 的"SDP 安装与工具链"和"验证状态"章节中,无需额外读取。
模块规范
每个功能模块是一个独立的可执行目标,放在 src/<模块名>/ 下,包含自己的 CMakeLists.txt、src/(源文件)和可选的 include/(头文件)。新增模块时在 src/CMakeLists.txt 中添加 add_subdirectory(<模块名>)。所有模块的可执行文件通过顶层 CMAKE_RUNTIME_OUTPUT_DIRECTORY 统一输出到 build/<preset>/ 根目录。
代码格式化
项目使用 clang-format 统一 C/C++ 代码风格,配置文件为根目录 .clang-format(基于 LLVM,C++20,4 空格缩进,100 列宽,指针右对齐 Type* var)。
- VS Code:安装 C/C++ 扩展(
ms-vscode.cpptools),保存文件时自动格式化(formatOnSave已在.vscode/settings.json启用)。 - 命令行批量格式化:
scripts\format.bat(格式化src/下所有.cpp/.h)。 - CI 检查模式:
scripts\format.bat check(只报告不修改,返回非零退出码表示有文件需格式化)。 - clang-format 不在 PATH 时,脚本会提示安装 LLVM 或使用 VS Code 扩展内置版本。
可移植性说明
- 项目内不包含任何硬编码用户路径(如
C:\Users\xxx\)。 - CMake Presets 通过
$penv{USERPROFILE}和$penv{ProgramFiles}自动解析路径,换用户/换机器零修改。 - configure preset 和 build preset 均内置环境变量(QNX_BASE/QNX_HOST/QNX_TARGET/PATH),确保
cmake --build阶段编译器也能找到工具链。 - 工具链文件位于项目
cmake/目录,使用${sourceDir}相对路径引用,不依赖 SDP 安装目录下的 cmake 文件。 - Ninja 路径覆盖 VS2022 全部四个版本(Community/Professional/Enterprise/BuildTools),不存在的路径无害忽略。
- 换机器 / 换用户时:安装 QNX SDP 8.0 到默认位置 → 直接
cmake --preset构建,无需修改任何项目文件。
注意事项
- 未使用
mkqnximage --type=qemu创建官方虚拟目标;QEMU 仿真通过手动构建 multiboot IFS +qemu-system-x86_64 -kernel实现,详见skills/run-qemu-simulation/。 - VS Code 中 QNX Toolkit 扩展(
qnx.qnx-vscodev1.1.0)和 CMake Tools 扩展共存,共用同一套 CMakeLists.txt 和工具链文件。 cmake未在系统 PATH 中(VS2022 Community 自带但未添加),命令行使用时需完整路径或在 VS Code 中操作。Preset 内置的 PATH 仅在 cmake 子进程内生效,不影响终端本身。CMakeUserPresets.json已加入 .gitignore,用于个人路径覆盖。- aarch64le 编译器前缀为
ntoaarch64-g++(非ntoaarch64le-g++),target 目录名为aarch64le。