一个程序通常会按照功能需求,进行一定的划分,拆分成不同的子功能,子功能一般会被编译成库,每个库可能包含多个源文件和头文件,并且由不同的人同时进行开发。
可以使用add_library完成静态库和动态的编译:
程序文件结构如下:
├── build
├── CMakeLists.txt
├── install
├── lib_o
│ ├── CMakeLists.txt
│ ├── lib_o.c
│ └── lib_o.h
├── lib_so
│ ├── CMakeLists.txt
│ ├── lib_so.c
│ └── lib_so.h
└── m.c
其中lib_o会被编译为静态库:
//lib_o.h
void call_lib_o();
//lib_o.c
#include
#include "lib_o.h"void call_lib_o()
{printf("this is call_lib_o\n");
}
#CMakeLists.txt in lib_o
#aux_source_directory将当前目录下的所有源文件名字放入变量O_SRCS
aux_source_directory(. O_SRCS)
#add_library指令用于编译库,STATIC表示是静态库
add_library(lib_o STATIC ${O_SRCS})#target_include_directories用于设置库所依赖的头文件路径
target_include_directories(lib_o PUBLIC .)
lib_so会被编译为动态库:
//lib_so.h
void call_lib_so();
//lib_so.c
#include
#include "lib_so.h"void call_lib_so()
{printf("this is call_lib_so\n");
}
#CMakeLists.txt in lib_so
#aux_source_directory将当前目录下的所有源文件名字放入变量O_SRCS
aux_source_directory(. SO_SRCS)
#add_library指令用于编译库,STATIC表示是动态库
add_library(lib_so SHARED ${SO_SRCS})#target_include_directories用于设置库所依赖的头文件路径
target_include_directories(lib_so PUBLIC ${CMAKE_SOURCE_DIR}/lib_so)#INSTALL用于设定动态库的安装路径
#其中变量INSTALL_DIR由顶层CMakeLists.txt定义并传递下来
INSTALL(TARGETS lib_so DESTINATION ${INSTALL_DIR})
主程序需要调用两个库中提供的函数:
//m.c
#include
#include "lib_o.h"
#include "lib_so.h"int main()
{call_lib_o();call_lib_so();return 0;}
#CMakeLists.txt in 工程的顶层目录
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
project(call_lib)#设置INSTALL_DIR变量为安装目录
set(INSTALL_DIR ${CMAKE_SOURCE_DIR}/install)#将lib_o及lib_so目录加入到工程中,即执行其中的CMakeLists.txt
add_subdirectory(lib_o)
add_subdirectory(lib_so)
add_executable(call_lib m.c)
#设置依赖的库
target_link_libraries(call_lib PRIVATE lib_o)
target_link_libraries(call_lib PRIVATE lib_so)
INSTALL(TARGETS call_lib DESTINATION ${INSTALL_DIR})
编译完成后,可执行文件和动态库文件将位于install目录:
install
│ ├── call_lib
│ └── liblib_so.so
直接执行call_lib可能会报错,需要通过LD_LIBRARY_PATH指定动态库的运行路径,可以参照:
GCC:头文件和库文件的路径_风静如云的博客-CSDN博客_gcc 头文件路径