CMake:add_library静态库和动态库

一个程序通常会按照功能需求,进行一定的划分,拆分成不同的子功能,子功能一般会被编译成库,每个库可能包含多个源文件和头文件,并且由不同的人同时进行开发。

可以使用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.h void call_lib_o();
//lib_o.c
#include <stdio.h>
#include "lib_o.h"

void call_lib_o()
{
    printf("this is call_lib_o
");
}
//lib_o.c #include #include "lib_o.h" void call_lib_o() { printf("this is call_lib_o "); }
#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.h void call_lib_so();
//lib_so.c
#include <stdio.h>
#include "lib_so.h"

void call_lib_so()
{
    printf("this is call_lib_so
");
}
//lib_so.c #include #include "lib_so.h" void call_lib_so() { printf("this is call_lib_so "); }
#CMakeLists.txt in lib_so #aux_source_directory将当前目录下的所有源文件名字放入变量SO_SRCS aux_source_directory(. SO_SRCS) #add_library指令用于编译库,SHARED表示是动态库 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 <stdio.h>
#include "lib_o.h"
#include "lib_so.h"

int main()
{
    call_lib_o();
    call_lib_so();
    return 0;

}
//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) 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指定动态库的运行路径,可以参照:

经验分享 程序员 微信小程序 职场和发展