C++ Cmake的构建静态库和动态库详解

2022-07-16,,,,

静态库和动态库的区别

1、静态库的扩展名一般为".a"或者".lib";动态库的扩展名一般为".so"或者".dll"。

2、静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可以独立运行

3、动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行。

构建示例

创建新项目cmake02,包含目录如下

​hello.h中的内容

#ifndef hello_h
#define hello_h
 
void hellofunc();
 
#endif

 hello.cpp中的内容

#include "hello.h"
#include <iostream>
using namespace std;
 
void hellofunc()
{
    cout<<"hello world"<<endl;
}

项目中cmakelists.txt内容

project(hello)
add_subdirectory(lib bin)

lib中cmakelists.txt内容

set(libhello_src hello.cpp)
add_library(hello shared ${libhello_src})

add_library

add_library(hello shared ${libhello_src})

hello:就是正常的库名,生成的名字前面会加上lib,最终产生的文件是libhello.so

shared,动态库static,静态库

${libhello_src}:源文件

同时构建静态和动态库

//如果用这种方式,只会构建一个动态库,不会构建出静态库,虽然静态库的后缀是.a

add_library(hello shared ${libhello_src})

add_library(hello static ${libhello_src})

//修改静态库的名字,这样是可以的,但是我们往往希望他们的名字是相同的,只是后缀不同而已

add_library(hello shared ${libhello_src})

add_library(hello_static static ${libhello_src})

set_target_properties

这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和api版本

同时构建静态和动态库示例

set(libhello_src hello.cpp)
 
add_library(hello_static static	${libhello_src})
 
set_target_properties(hello_static properties output_name "hello")
 
set_target_properties(hello_static properties clean_direct_output$
 
add_library(hello shared ${libhello_src})
 
set_target_properties(hello properties output_name "hello")
set_target_properties(hello properties clean_direct_output 1)

动态库的版本号

一般动态库都会有一个版本号的关联

libhello.so.1.2

libhello.so->libhello.so.1

libhello.so.1->libhello.so.1.2

cmakelist.txt插入如下

set_target_properties(hello properties version 1.2 soversion 1)

 version指代动态库版本,soversion指代api版本

安装共享库和头文件

本例中我们将hello的共享库安装到<prefix>/lib目录

将hello.h安装到<prefix>/include/hello目录

//文件放到该目录下
install(files hello.h destination include/hello)
 
//二进制,静态库,动态库安装都是用targets
//archive特指静态库,libraty特指动态库,runtime特指可执行目标二进制
install(targets hello hello_static library destination lib archive destination lib)

注意:安装的时候,指定一下路径,放到系统下

cmake -dcmake_install_perfix=/usr ..

使用外部共享库和头文件

新建cmake03目录来使用外部共享库和头文件

main.cpp内容

#include <hello.h>
 
int main()
{
    hellofunc();
}

解决 :make后头文件找不到的问题

 ps:include 这样是可以的

关键字:include_directories 这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割

在cmakelists.txt中加入头文件搜索路径

include_directories(/usr/local/include/hello)

解决:找到引用的函数问题

关键字:link_dirctories 添加非标准的共享库搜索路径

指定第三方库锁在路径,link_directories(/home/myproject/libs)

关键字target_link_libraries 添加需要链接的共享库

target_link_libraries的时候,只需要给出动态链接库的名字就行了。

cmakelists.txt中插入连接共享库,主要要插在executable的后面

target_link_libraries(hello libhello.so)

 cmake后make

执行bin目录下的./hello报错

解决:mv /usr/local/lib/libhello.so /usr/lib64/

 查看main的链接情况

链接静态库

target_link_libraries(hello libhello.a) 

特殊的环境变量cmake_include_path和cmake_library_path

注意:这两个是环境变量而不是cmake变量,可以在linux的bash中进行设置

在上面例子中使用了绝对路径include_directories(/usr/include/hello)来指明include路径的位置

我们还可以使用环境变量export cmake_include_path=/usr/local/include/hello

生产debug版本的方法:

cmake .. -dcmake_build_type=debug

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!  

《C++ Cmake的构建静态库和动态库详解.doc》

下载本文的Word格式文档,以方便收藏与打印。