news 2026/8/24 13:15:46

target_include_directories对比 PUBLIC / PRIVATE

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
target_include_directories对比 PUBLIC / PRIVATE

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一、表述详解
      • 核心结论
      • 补充核心定义(关键)
  • 二、完整项目示例
    • 1. 项目目录结构
    • 2. 源码文件
      • `include/lib.h`(库的公共接口)
      • `src/lib.cpp`(库的实现文件)
      • `src/main.cpp`(主程序)
    • 3. CMake 构建脚本
      • 写法1:使用 `PUBLIC`(标准正确用法)
      • 写法2:错误演示(改用 `PRIVATE`)
    • 4. 编译与效果测试
      • 编译命令(终端执行)
      • 结果对比
  • 三、`PRIVATE` 的**正确使用场景**
    • 调整后的目录结构
    • 新增文件:`src/private_inc/internal.h`
    • 修改 `src/lib.cpp`
    • 优化后的 CMake 配置
      • 效果
  • 四、总结

通过实操对比PUBLIC/PRIVATE的效果

一、表述详解

cmake_demo/ ├── include/ │ └── lib.h# 带导出宏的头文件├── src/ │ ├── lib.cpp# 动态库实现│ └── main.cpp# 调用方程序└── CMakeLists.txt

核心结论

target_include_directories(mylib PRIVATE 路径)的适用场景:
该头文件路径仅被lib.cpp(库的实现文件)使用,不会被main.cpp(依赖该库的外部代码)包含,此时用PRIVATE
如果外部代码(main.cpp)需要包含这个路径下的头文件(lib.h),必须用PUBLIC,否则外部目标会找不到头文件。


补充核心定义(关键)

作用域适用场景
PUBLIC路径既给lib.cpp用,也给所有依赖 mylib 的目标(如main.cpp)用(接口头文件路径)
PRIVATE路径仅给lib.cpp自用,不传递给外部依赖目标(库内部私有头文件路径)
INTERFACE路径不给自身用,仅传递给外部依赖目标

二、完整项目示例

1. 项目目录结构

采用标准工程规范,公共头文件放在include目录,源文件放在src目录:

cmake_demo/ ├── include/ # 公共头文件目录(外部可访问) │ └── lib.h # 库接口声明 ├── src/ │ ├── lib.cpp # 库实现文件 │ └── main.cpp # 主程序(调用库函数) └── CMakeLists.txt # 构建脚本

2. 源码文件

include/lib.h(库的公共接口)

头文件保护宏防止重复包含,声明加法函数,会被main.cpp直接包含:

#ifndefLIB_H#defineLIB_H// 加法函数声明:对外提供的接口intadd(inta,intb);#endif// LIB_H

src/lib.cpp(库的实现文件)

包含公共头文件,实现加法逻辑:

// 包含库的接口头文件#include"lib.h"// 实现加法函数intadd(inta,intb){returna+b;}

src/main.cpp(主程序)

调用库的add函数,需要包含lib.h

#include<stdio.h>// 包含库的公共头文件#include"lib.h"intmain(){intres=add(10,20);printf("10 + 20 = %d\n",res);return0;}

3. CMake 构建脚本

写法1:使用PUBLIC(标准正确用法)

因为main.cpp需要依赖include路径找到lib.h,因此路径需要传递给外部目标,用PUBLIC

cmake_minimum_required(VERSION 3.15) project(AddLibraryDemo) # C++标准配置 set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 1. 创建静态库目标 mylib add_library(mylib src/lib.cpp) # 2. 为库添加头文件路径:PUBLIC 表示路径自身可用,且传递给依赖它的目标 target_include_directories(mylib PUBLIC include) # 3. 创建可执行目标 add_executable(main_app src/main.cpp) # 4. 链接库:main_app 会自动继承 mylib 的 PUBLIC/INTERFACE 头文件路径 target_link_libraries(main_app PRIVATE mylib)

写法2:错误演示(改用PRIVATE

如果我们把PUBLIC改为PRIVATE,代表include路径仅给 mylib 自身使用,不传递

# 仅修改这一行,其余代码不变 target_include_directories(mylib PRIVATE include)

4. 编译与效果测试

编译命令(终端执行)

# 创建构建目录并进入mkdirbuild&&cdbuild# 生成构建文件cmake..# 编译make

结果对比

  1. PUBLIC配置:编译成功,运行./main_app,输出:
    10 + 20 = 30
  2. PRIVATE配置编译直接报错,提示找不到头文件:
    fatal error: lib.h: No such file or directory #include "lib.h"
    原因:main_app无法继承include路径,编译器找不到头文件。

三、PRIVATE正确使用场景

为了让你理解PRIVATE不是无用的,我们扩展场景:给库添加私有内部头文件,仅lib.cpp使用,外部无需访问。

调整后的目录结构

cmake_demo/ ├── include/ # 公共头文件(对外) │ └── lib.h ├── src/ │ ├── private_inc/ # 库私有头文件(仅内部用) │ │ └── internal.h │ ├── lib.cpp │ └── main.cpp └── CMakeLists.txt

新增文件:src/private_inc/internal.h

#ifndefINTERNAL_H#defineINTERNAL_H// 库内部使用的工具函数,不对外部暴露staticintcalc(intx){returnx*2;}#endif

修改src/lib.cpp

#include"lib.h"// 包含私有内部头文件#include"internal.h"intadd(inta,intb){// 调用内部工具函数returncalc(a+b);}

优化后的 CMake 配置

公共路径用PUBLIC,私有路径用PRIVATE

cmake_minimum_required(VERSION 3.15) project(AddLibraryDemo) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(mylib src/lib.cpp) # 公共头文件:传递给外部依赖目标 target_include_directories(mylib PUBLIC include) # 私有头文件:仅库自身使用,不传递 target_include_directories(mylib PRIVATE src/private_inc) add_executable(main_app src/main.cpp) target_link_libraries(main_app PRIVATE mylib)

效果

  1. main_app能继承include路径,正常找到lib.h
  2. main_app无法访问src/private_inc路径,保证了库内部实现的封装性;
  3. lib.cpp可以同时找到公共头文件和私有头文件。

四、总结

  1. 表述纠正main.cpp依赖该头文件路径时,必须用PUBLIC;仅lib.cpp依赖时,才用PRIVATE
  2. 核心规则
    • 对外暴露的接口头文件路径 →PUBLIC(传递给依赖目标);
    • 库内部私有的实现头文件路径 →PRIVATE(仅自身使用,封装隔离);
  3. 单目标/多目标通用:这套规则是现代CMake的标准规范,无论项目大小都推荐使用,比全局的include_directories更安全、更易维护。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/20 17:02:45

毕业设计任务书模板基于JSP的商品库存管理系统

目录 毕业设计任务书模板&#xff1a;JSP商品库存管理系统系统概述核心功能模块技术实现要点数据库设计示例预期成果 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 毕业设计任务书模板&#xff1a;JSP商…

作者头像 李华
网站建设 2026/8/21 3:37:24

建立普通的基类Building,用来存储一座楼房的层数、房间数以及它的总平方米数。建立派生类House,继承Building,并存储下面的内容:卧室与浴室的数量。另外,建立派生类Office,继承Bu

class Builing { private:int cengshu;//层数int fangjianshu;//房间数double total_area;//总平方米 public://构造函数Builing(int ceng 0, int fangjian 0, double area 0.0) :cengshu(ceng), fangjianshu(fangjian), total_area(area){//检验合法性if (cengshu < 0){c…

作者头像 李华
网站建设 2026/8/23 10:34:07

数字图像处理篇---小波变换

如果说傅里叶变换和DCT是用固定镜头观察世界&#xff0c;那么小波变换就是一部可以自由变焦、还能移动镜头的超强摄像机。核心比喻&#xff1a;用“显微镜”和“地图”分析图像想象你要分析一张城市全景图。傅里叶/DCT的做法&#xff08;固定视角&#xff09;&#xff1a;他们飞…

作者头像 李华
网站建设 2026/8/23 6:49:47

基于LSTM的剩余寿命预测附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/8/19 18:39:49

第七十八篇-CentOS-7+安装cmake-3.24.3

系统&#xff1a;CentOS-7 下载 wget https://github.com/Kitware/CMake/releases/download/v3.24.3/cmake-3.24.3-linux-x86_64.sh 赋予执行权限 chmod x cmake-3.24.3-linux-x86_64.sh 创建目录 mkdir -p /no_move/cmake 安装 sudo ./cmake-3.24.3-linux-x86_64.sh --…

作者头像 李华