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

 更新时间:2022年03月18日 10:20:48   作者:静·无羡  
这篇文章主要为大家详细介绍了C++ Cmake的构建静态库和动态库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

静态库和动态库的区别

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语言详细分析讲解多文件的程序设计

    C语言详细分析讲解多文件的程序设计

    所谓的C语言多文件编程就是,将代码实现模块化。比如说一个项目的一项功能放在一个一个文件里,然后将实现这个功能的函数放在一个c文件<BR>
    2022-04-04
  • C语言每日练习之冒泡排序

    C语言每日练习之冒泡排序

    这篇文章主要介绍了C语言冒泡排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • 详谈全排列next_permutation() 函数的用法(推荐)

    详谈全排列next_permutation() 函数的用法(推荐)

    下面小编就为大家带来一篇详谈全排列next_permutation() 函数的用法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 基于C语言字符串函数的一些使用心得

    基于C语言字符串函数的一些使用心得

    以下是对C语言中字符串函数的一些使用心得进行了详细的介绍,需要的朋友可以过来参考下
    2013-08-08
  • 简易Dota改键程序制作

    简易Dota改键程序制作

    利用全局钩子制作一个个性化的dota游戏改键功能,大家可以参考使用
    2013-11-11
  • C语言中求余运算符的使用解读

    C语言中求余运算符的使用解读

    这篇文章主要介绍了C语言中求余运算符的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 浅析C++中的函数重载

    浅析C++中的函数重载

    这篇文章主要介绍了浅析C++中的函数重载,在C++中,可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同,或者参数类型相同而参数个数不同,又或者参数类型参数个数相同,参数次序不同,称为函数重载,需要的朋友可以参考下
    2023-08-08
  • C/C++数字与字符串互相转换的实现示例

    C/C++数字与字符串互相转换的实现示例

    本文主要介绍了C/C++数字与字符串互相转换的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • C++实现飞机大战游戏

    C++实现飞机大战游戏

    这篇文章主要为大家详细介绍了C++实现飞机大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++初始化列表学习

    C++初始化列表学习

    在C++中,struct和class的唯一区别是默认的克访问性不同,而这里我们不考虑访问性的问题,所以下面的代码都以struct来演示
    2013-09-09

最新评论