本文是阅读《Professional-CMake-A-Practical-Guide》第四章做的一点笔记。
1、add_library
在 CMakeLists.txt 文件可以通过如下命令创建库文件
add_library(targetName [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...]
)
STATIC 和 SHARED 都好理解,就是 C 语言里的静态库和动态库的意思,文章是建议不要在 add_library 中直接指定是要何种类型库,而是在编译的时候通过宏来开关指定,如下:
cmake .. -DBUILD_SHARED_LIBS=YES
也可以在 add_library 语句之前进行如下配置
set(BUILD_SHARED_LIBS YES)
2、target_link_libraries
如果 A 库需要链接库 B,可以通过如下命令进行链接
target_link_libraries(targetName
<PRIVATE|PUBLIC|INTERFACE> item1 [item2 ...]
[<PRIVATE|PUBLIC|INTERFACE> item3 [item4 ...]]
...
)
上面三个关键词需要理解下:
PRIVATE:B 只是给 A 自己用,对于链接 A 库的对象,不需要用到 B;即只是 A 的源码实现中会包含 B 的头文件;对于链接 A 的执行程序是无法调用 B 中的接口实现
PUBLIC:链接 A 库的对象一定需要 B 的对我接口才能使用 A,如 A 接口的入参是在 B 中声明的;即 A 的头文件中也要包含 B 的头文件,且源码实现中会用到;对于链接 A 的执行程序是可以调用 B 中的接口实现
INTERFACE:A 自己不用,给链接 A 的对象使用;对于链接 A 的执行程序可以调用 B 中的接口实现
具体效果可以按下面的部分示例代码操作下:
hello_test $ tree
.
├── build
├── CMakeLists.txt
├── hello_world
│ ├── CMakeLists.txt
│ ├── hello
│ │ ├── CMakeLists.txt
│ │ ├── hello.c
│ │ └── hello.h
│ ├── hello_world.c
│ └── hello_world.h
└── main.c
//main.c
#include "hello_world.h"
#include "hello.h"
int main(int argc, char const *argv[])
{
hello_word();
hello();
return 0;
}
// hello_test/CMakeLists.txt
...
add_executable(test
main.c
)
include_directories(hello_world)
target_link_libraries(test PRIVATE hello_world)
add_subdirectory(hello_world)
// hello_world/CMakeLists.txt
add_library(hello_world SHARED hello_world.c)
# 如果main.c 要使用hello接口,则这里使用 PUBLIC
target_link_libraries(hello_world PUBLIC hello)
target_include_directories(hello_world PUBLIC hello)
# 如果main.c 不需要使用hello接口,则这里使用 PRIVATE
# target_link_libraries(hello_world PRIVATE hello)
# target_include_directories(hello_world PRIVATE hello)
# 如果main.c 需要使用到,hello_world.c不需要使用,可以使用 INTERFACE
#target_link_libraries(hello_world INTERFACE hello)
#target_include_directories(hello_world INTERFACE hello)
add_subdirectory(hello)
// hello_world.c
#include "hello.h"
void hello_word(void)
{
printf("[FILE:%s] [FUNC:%s] [Line:%d] hello_world \n", __FILE__, __func__, __LINE__ );
hello();
}
// hello/CMakeLists.txt
add_library(hello SHARED hello.c)
// hello.c
void hello(void)
{
printf("[FILE:%s] [FUNC:%s] [Line:%d] hello \n", __FILE__, __func__, __LINE__ );
}