examples/cmake/visibility/README.md

2.5 KiB
Raw Permalink Blame History

CMake target 可见性 Demovisibility

来自博客 docs/编程/20-接口可见性.md §5.2「完整 Demo」。 演示 target_include_directories / target_link_libraries / target_compile_definitions 上 PUBLIC / PRIVATE / INTERFACE 的传播语义。

运行

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 colorPRIVATE color 未跑printer 自身编译过app 找不到 color/color.h 报错

判断口诀

打开自己的公开头文件看一眼:

  • 头文件里 #include 了谁 → 那个库 PUBLIC
  • 头文件里 #ifdef 了哪个宏(宏影响 API 形状)→ 那个宏 PUBLIC
  • 只在 .cpp 里出现的库/宏/路径 → PRIVATE