闲扯
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。
target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/iadd)
target_include_directories(sub PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/isub)
target_link_libraries(sub PUBLIC add)
target_link_libraries(sample PUBLIC sub)
可能光看上面还是不太明白,那我们查看build/cmakefiles/xxxx.dir下生成的gcc 语句吧。
includes_CXX.rsp存储include path
linklibs.rsp存储link library
add.dir,第一级节点,没啥好说的
-ID:/workspace/testCmake/iadd
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
sub ,注意include
-ID:/workspace/testCmake/isub -ID:/workspace/testCmake/iadd
libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
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
private 私有传播
将所有public,改为private,再次构建,查看对应的生成语句。
add.dir,第一级节点,没啥好说的
-ID:/workspace/testCmake/iadd
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
sub ,注意include
-ID:/workspace/testCmake/isub
libadd.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
sample
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)
add.dir
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
sub
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
sample(public link sub)
-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:对外公开,对内不公开,可传递头文件目录以及链接库,但内部不可使用头文件及连接库,只能接口传递。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)