我是靠谱客的博主 自觉鼠标,最近开发中收集的这篇文章主要介绍CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解闲扯实例示例总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

闲扯

cmake 里面target_include_directories,target_link_libraries这两个命令里面有三种属性PRIVATE、PUBLIC、INTERFACE。

cmake PRIVATE、PUBLIC、INTERFACE的讲解网络上很多,但是总觉得太过偏概念了,看完并没有让人有深入细节的了解。

于是动手做个示例,就有了本杂文。

这三种属性,从根本上来讲属于cmake里面传播特性的三种等级。

实例

既然传播特性,那么我们肯定需要多个target来演示传播。

testCMake
├─ add.cpp
├─ build
├─ CMakeLists.txt
├─ Iadd
│
└─ add.h
├─ Isub
│
└─ sub.h
├─ main.cpp
└─ sub.cpp

项目结构如上,生成两个动态库,一个可执行文件

但三个cpp文件对头文件都没有包含关系,方便演示。
环境 minggw gcc 8.1.0+win10

add_library(add SHARED add.cpp)
add_library(sub SHARED sub.cpp)
add_executable(sample main.cpp)

示例

PUBLIC传播

这里我们sample(main) 只link sub库,不做另外的include_directories操作,sub在另外link add库做链接库和头文件库传递给sample。

//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)
//无视,因为属于最尾子节点,没有下一级来传播

可能光看上面还是不太明白,那我们查看build/cmakefiles/xxxx.dir下生成的gcc 语句吧。
includes_CXX.rsp存储include path
linklibs.rsp存储link library
add.dir,第一级节点,没啥好说的

//include
-ID:/workspace/testCmake/iadd
// link
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sub ,注意include

//include,由于add库包含头文件使用的是public,所以sub只要link了add库,就会自动包含add的头文件目录 不需要另外include_directories,
-ID:/workspace/testCmake/isub -ID:/workspace/testCmake/iadd
// link
libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sample

//include,isub同理,另外由于sub是public连接add库,因此add库的头文件可以传递到链接sub的sample 
-ID:/workspace/testCmake/isub -ID:/workspace/testCmake/iadd
// 由于sub是public连接add库,sample也连接了add库
libsub.dll.a libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

private 私有传播

将所有public,改为private,再次构建,查看对应的生成语句。

add.dir,第一级节点,没啥好说的

//include
-ID:/workspace/testCmake/iadd
// link
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sub ,注意include

//include,由于add库包含头文件使用的是private,所以sub包含没有iadd
-ID:/workspace/testCmake/isub
// link
libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sample

//include为空,add及sub头文件都无法传递至sample
// link 只link sub
libsub.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

INTERFACE

interface比较特殊,他是指给连接者提供接口,而被连接者不对该接口做调用。
还是具体举例加深理解,除sample全部改成interface


target_include_directories(add INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/iadd)
target_include_directories(sub INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/isub)
target_link_libraries(sub INTERFACE add)
target_link_libraries(sample PUBLIC sub) //private也可

add.dir

//include 为空,也就是上文中的只给连接者提供接口,而被连接不依赖该接口,只做include path的传递
// link
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sub

//include为空,同理
// link,link也是interface,不链接,只做链接库的传递
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

sample(public link sub)

//include,由于是public连接sub,所以sub传递给sample的interface include都显示在sample的编译语言里 
-ID:/workspace/testCmake/isub -ID:/workspace/testCmake/iadd
// 同上 
libsub.dll.a libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

总结

target_include_directories里面的关键字控制头文件目录传递。
target_link_libraries里的关键字控制头文件目录以及链接库传递。

  • PUBLIC:对内对外都公开,可将头文件目录以及链接库传递给连接者。
  • PRIVATE:对内公开,对外不公开,不可传递头文件目录以及链接库。
  • INTERFACE:对外公开,对内不公开,可传递头文件目录以及链接库,但内部不可使用头文件及连接库,只能接口传递。

最后

以上就是自觉鼠标为你收集整理的CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解闲扯实例示例总结的全部内容,希望文章能够帮你解决CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解闲扯实例示例总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部