examples/cmake/visibility/README.md

64 lines
2.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.

# CMake target 可见性 Demovisibility
> 来自博客 `docs/编程/20-接口可见性.md` §5.2「完整 Demo」。
> 演示 `target_include_directories` / `target_link_libraries` /
> `target_compile_definitions` 上 PUBLIC / PRIVATE / INTERFACE 的传播语义。
## 运行
```bash
cd cmake/visibility
cmake -B build && cmake --build build
./build/app
```
预期输出(终端里是彩色的):
```
10:37:06 hello (绿色)
bright red (高亮红 —— PUBLIC 宏 COLOR_ENABLE_BRIGHT 传播到 app 的证据)
(没有 "leaked!" —— printer 的 PRIVATE 宏 PRINTER_TIME_FORMAT 被隔离的证据)
```
## 目录结构
```
visibility/
├── CMakeLists.txt
├── app/
│ └── main.cpp # 最终用户,只认识 printer
├── color/
│ ├── public/color/color.h # 对外 API 头(含 PUBLIC 宏开关 COLOR_ENABLE_BRIGHT
│ ├── include/rgb_convert.h # 内部中间件头,仅库内 .cpp 共享PRIVATE 目录)
│ └── src/{color,rgb_convert}.cpp
├── timeutil/
│ └── {timeutil.h,timeutil.cpp} # printer 的私有依赖
└── printer/
├── public/printer/printer.h # 对外 API 头(引用了 color → color 是 PUBLIC 依赖)
└── src/printer.cpp
```
依赖与可见性一图流:
```
app ──PRIVATE──> printer ──PUBLIC──> color ✓ app 能 include color.h、感知 COLOR_ENABLE_BRIGHT
│ └─(内部) rgb_convert.h ✗ 外部看不见include/ 是 PRIVATE 目录)
└────PRIVATE──> timeutil ✗ app 看不见 timeutil.h
└────PRIVATE 宏 PRINTER_TIME_FORMAT ✗ 不泄漏给 app
```
## 验证实验§5.3
| # | 操作 | 实测结果 |
|---|------|---------|
| 1 | 直接编译运行 | ✅ 输出 bright red不输出 leaked! |
| 2 | main.cpp 加 `#include "rgb_convert.h"` | ✅ `fatal error: rgb_convert.h: No such file or directory` |
| 3 | main.cpp 加 `#include "timeutil.h"` | ✅ `fatal error: timeutil.h: No such file or directory` |
| 4 | printer 的 `PUBLIC color``PRIVATE color` | 未跑printer 自身编译过app 找不到 color/color.h 报错 |
## 判断口诀
打开自己的公开头文件看一眼:
- 头文件里 `#include` 了谁 → 那个库 **PUBLIC**
- 头文件里 `#ifdef` 了哪个宏(宏影响 API 形状)→ 那个宏 **PUBLIC**
- 只在 .cpp 里出现的库/宏/路径 → **PRIVATE**