Files
wind_power_cal/.claude/skills/third-party-libs/SKILL.md
T
2026-07-14 15:43:18 +08:00

137 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: third-party-libs
description: 第三方编译库管理规范。用于新增、修改或引用 third_party 下需编译的第三方库时,统一目录结构、架构分层与 CMake 链接方式。
---
# 第三方编译库管理规范
## 适用范围
`third_party/` 目录下所有**需要编译**的 C/C++ 第三方库。
纯头文件库(如 `nlohmann``spdlog`)不受此规范约束。
## 编译架构原则
- 默认只编译、整理**当前运行机器架构**的库或工具文件。
- 禁止在未被明确要求时自动交叉编译其他架构产物。
- 需要 arm64/x64 等非当前架构产物时,必须由用户明确要求或提供已编译产物,再按对应架构目录放置。
- 同一次任务中不要为了“完整性”主动补齐所有架构;以当前部署目标为准。
## 目录结构
每个需要编译的第三方库拆分为两个目录:
```
third_party/
├── <库名>/ # 编译产物(头文件 + 静态/动态库)
│ ├── include/ # 公开头文件
│ └── libs/ # 编译后的库文件,按架构分层
│ ├── x64/
│ ├── arm32/
│ └── arm64/
└── <库名>_repo/ # 源码仓库(带 _repo 后缀标识)
```
### 示例
```
third_party/
├── fwlib/ # Fanuc SDK 编译产物
│ ├── include/
│ └── libs/{x64,arm32,arm64}/
├── fwlib_repo/ # Fanuc SDK 源码
├── lib60870/ # IEC 60870 编译产物
│ ├── include/
│ └── libs/{x64,arm32,arm64}/
├── lib60870_repo/ # IEC 60870 源码
├── libplctag/ # CIP/EtherNet/IP 编译产物
│ ├── include/
│ └── libs/{x64,...}/
├── paho-mqtt/ # MQTT 编译产物
│ ├── include/
│ └── libs/{x64,...}/
├── nlohmann/ # 纯头文件库(不受此规范约束)
└── spdlog/ # 纯头文件库(不受此规范约束)
```
## 命名规则
| 目录 | 用途 | 示例 |
|------|------|------|
| `<库名>/` | 编译产物(include + libs | `fwlib/``libplctag/` |
| `<库名>_repo/` | 源码仓库,用 `_repo` 后缀区分 | `fwlib_repo/``lib60870_repo/` |
## 架构标识
库文件必须放在 `libs/<arch>/` 子目录下,`<arch>` 取值:
| 架构标识 | 对应处理器 |
|----------|-----------|
| `x64` | x86_64 |
| `arm32` | armv7l / arm |
| `arm64` | aarch64 / arm64 |
## CMake 链接规范
### 架构检测(统一写法)
```cmake
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7.*|arm)$")
set(TARGET_ARCH "arm32")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
set(TARGET_ARCH "arm64")
else()
set(TARGET_ARCH "x64")
endif()
```
### 引用编译产物
```cmake
set(XXX_DIR "${REPO_ROOT}/third_party/<库名>")
# 头文件
target_include_directories(target PRIVATE ${XXX_DIR}/include)
# 链接库(使用 TARGET_ARCH 定位架构)
target_link_libraries(target ${XXX_DIR}/libs/${TARGET_ARCH}/libxxx.a)
# 或通过 link_directories
target_link_directories(target PRIVATE ${XXX_DIR}/libs/${TARGET_ARCH})
target_link_libraries(target xxx)
```
### 条件编译(可选库)
对于非必须的协议库,使用 `EXISTS` 检测并控制编译:
```cmake
set(XXX_DIR "${REPO_ROOT}/third_party/<库名>")
if(EXISTS "${XXX_DIR}/libs/${TARGET_ARCH}/libxxx.a")
target_include_directories(target PRIVATE ${XXX_DIR}/include)
target_link_libraries(target ${XXX_DIR}/libs/${TARGET_ARCH}/libxxx.a)
target_compile_definitions(target PRIVATE HAS_XXX=1)
message(STATUS "<库名> found — XXX driver enabled")
else()
get_target_property(_sources target SOURCES)
list(FILTER _sources EXCLUDE REGEX ".*driver/xxx/.*")
set_target_properties(target PROPERTIES SOURCES "${_sources}")
message(STATUS "<库名> NOT found — XXX driver disabled")
endif()
```
## 禁止事项
- **禁止** 将编译后的库文件直接放在 `lib/` 而不分架构
- **禁止** 在 CMake 中硬编码 `lib/` 路径,必须使用 `libs/${TARGET_ARCH}/`
- **禁止** 将源码和编译产物混放在同一目录
- **禁止** 将 `third_party` 改名为 `third_partys``third_party` 是业界标准命名)
## 新增第三方库流程
1. 将源码克隆到 `third_party/<库名>_repo/`
2. 编译出目标架构的库文件
3. 创建 `third_party/<库名>/include/`,放入公开头文件
4. 创建 `third_party/<库名>/libs/<arch>/`,放入编译产物
5. 在 CMakeLists.txt 中按上述规范引用