CMake之PUBLIC、PRIVATE、INTERFACE
创作时间:
作者:
@小白创作中心
CMake之PUBLIC、PRIVATE、INTERFACE
引用
CSDN
1.
https://blog.csdn.net/rainInSunny/article/details/141674359
写在前面
使用CMake必然离不开target_include_directories
和target_link_libraries
,这两个命令中都可以设置为三种属性:PRIVATE、PUBLIC、INTERFACE。CMake官方文档对于这三种属性的解释过于抽象,本文将从编译行为的角度来理解这三种属性有什么差异。
抽象版解释
以target_link_libraries(A B)
命令为例:
PRIVATE
依赖项B仅链接到目标A,若有C链接了目标A,C不链接依赖项B。INTERFACE
依赖项B并不链接到目标A,若有C链接了目标A,C会链接依赖项B。PUBLIC
依赖项B链接到目标A,若有C链接了目标A,C也会链接依赖项B。
从使用的角度解释:
- 如果依赖项B仅用于目标A的实现,且不在头文件中提供给C使用,使用
PRIVATE
。 - 如果依赖项B不用于目标A的实现,仅在头文件中作为接口提供给C使用,使用
INTERFACE
。 - 如果依赖项B不仅用于目标A的实现,而且在头文件提供给C使用,使用
PUBLIC
。
头文件和链接库传递
测试代码结构
testCMake
├─ add.cpp
├─ build
├─ CMakeLists.txt
├─ Iadd
│ └─ add.h
├─ Isub
│ └─ sub.h
├─ main.cpp
└─ sub.cpp
代码目录结构十分简单,add.cpp和add.h组成add模块,Iadd是add模块头文件目录,sub.cpp和sub.h组成sub模块,Isub为sub模块头文件目录。main.cpp最后被编译成sample可执行程序。接下来开始测试~
PUBLIC传递
//Iadd里面的头文件可以传递给链接add的target,头文件传递
target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件传递给链接sub库的target,头文件传递
target_include_directories(sub PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub链接add库,链接sub的库也将链接add,链接库传递(含头文件)
target_link_libraries(sub PUBLIC add)
//sample链接sub
target_link_libraries(sample PUBLIC sub) //无视,因为属于最尾子节点,没有下一级来传播
使用上面的CMake配置进行测试,得到结果如下。可以看出由于头文件包含属性和链接属性都是PUBLIC,因此sample虽然只链接了sub模块,此时sub链接的add模块会直接传递到sample模块,即sample模块也链接了add模块。
//add模块配置内容
//include
-ID:/workspace/testCmake/Iadd
// link
-lkernel32 -luser32
//sub模块配置内容
//include 由于add库包含头文件使用的是public,所以sub只要link了add库,就会自动包含add的头文件目录,不需要另外include_directories
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
// link
-ladd -lkernel32 -luser32
//sample模块配置内容
//include 同理Isub,另外由于sub是public链接add库,因此add库的头文件可以传递到链接sub的sample
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
//由于sub是public链接add库,sample也链接了add库
-lsub -ladd -lkernel32 -luser32
PRIVATE传递
//Iadd里面的头文件不可以传递给链接add的target
target_include_directories(add PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件不可以传递给链接sub库的target
target_include_directories(sub PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub链接add库,链接sub的库不能自动链接add
target_link_libraries(sub PRIVATE add)
//sample链接sub
target_link_libraries(sample PRIVATE sub)
使用上面的CMake配置进行测试,得到结果如下。由于使用PRIVATE属性,头文件和链接库都不能传递,所以sample包含的头文件目录为空,只链接了sub库。
//add模块配置内容
//include
-ID:/workspace/testCmake/Iadd
//link
-lkernel32 -luser32
//sub模块配置内容
//include 由于add库包含头文件使用的是PRIVATE,所以sub包含没有Iadd
-ID:/workspace/testCmake/Isub
// link
-ladd -lkernel32 -luser32
//sample模块配置内容
//include 为空,add及sub头文件都无法传递至sample
//link 只链接sub
-lsub -lkernel32 -luser32
INTERFACE传递
//Iadd里面的头文件可以传递给链接add的target,而add模块本身不包含该目录
target_include_directories(add INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Iadd)
//Isub的头文件可以传递给链接sub库的target,而sub模块本身不包含该目录
target_include_directories(sub INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Isub)
//sub没有链接add库,链接sub的库自动链接add
target_link_libraries(sub INTERFACE add)
//sample链接sub和add
target_link_libraries(sample PUBLIC sub) //private也可
使用上面的CMake配置进行测试,得到结果如下。由于头文件和链接库都设置为INTERFACE,所以add和sub模块都只做头文件和链接库的传递,传递到sample中,最终sample中包含add和sub的头文件并同时链接了add和sub。
//add模块配置内容
//include 为空,INTERFACE只给链接者提供接口,而被链接者不依赖该接口,只做include path的传递
//link
-lkernel32 -luser32
//sub模块配置内容
//include 为空,同上
// link 链接也是INTERFACE,不链接,只做链接库的传递
-lkernel32 -luser32
//sample模块配置内容
//include 由于是PUBLIC连接sub,所以前面INTERFACE传递的头文件和库都会包含在sample中
-ID:/workspace/testCmake/Isub -ID:/workspace/testCmake/Iadd
// 同上
-lsub -ladd -lkernel32 -luser32
热门推荐
里脊肉配青椒,炒出绝美辣椒炒肉
从基础到创意:12种辣椒炒法全攻略
百日咳与支原体肺炎如何区分?专家详解8大鉴别要点
最新!妙瓦底大规模建设电诈园区,专家呼吁按恐怖组织严打
缅泰边境妙瓦底成电信诈骗新据点,水电气网络由泰国提供
支票票据审核的注意事项及法律依据
减压真的能降血压吗?这些方法帮你轻松应对
八哥鸟会说话?揭秘这种宠物鸟的社交与情感世界
杭州东站满满都是人!朋友圈已经“堵了”!网友:你预判了我的预判
中山楼市推“9块9买房”:月供3000元起,开发商垫付首付
中山房价区域指南:8个板块价格及配套全解析
肝功能三项指标正常,肝脏通常很健康!
大厨教你顺德特色菜“三杯鹅煲”家常做法,味道很赞,收藏了
2024年AI影视频频“翻车”,行业仍对其保持热情
白菜虽好,但并非人人皆宜:一份实用的健康饮食指南
白菜猪肉的神仙搭配,你get了吗?
白菜里的维C,比柠檬还给力?
农业农村部发布汛期动物疫病防控指南,六大措施保障养殖安全
严子陵钓台:富春江畔的文化明珠
周末打卡富春江:绝美自然景观与文化体验的完美融合
富春江畔的隐逸胜地:严子陵钓台打卡全攻略
从食材到餐桌:十大含锌食物及补锌食谱详解
猫奴们必看:为啥猫科动物这么圈粉?
当归炖鸡:冬季养生的滋补佳品
很多人每天都喝酒,为什么身体却很健康?
当归:妇科圣药的秘密武器
联通6月起实施“一证五户”实名制查验,违规用户将被停机
柳蛳蛳螺蛳粉:从300家门店到十大品牌,揭秘其快速崛起之道
5G赋能智慧农业,河北塔元庄村10万斤葡萄半月售罄
5200亩无人农场背后的科技革命:智能感知让农民足不出户掌控田间