C++ Cmake的构建静态库和动态库详解
作者:静·无羡 发布时间:2023-06-28 08:28:15
静态库和动态库的区别
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
来源:https://blog.csdn.net/qq_43577213/article/details/123531206


猜你喜欢
- 一、对象的综述面向对象编程(OOP)具有多方面的吸引力。对管理人员,它实现了更快和更廉价的开发与维护过程。对分析与设计人员,建模处理变得更加
- 前言我曾经在一篇介绍 Compose Navigation 的文章 中提到了 Navigation 的状态保存实际是由 rememberSa
- 前言复习一下spring实现IOC的源码流程准备工作:强烈建议大家从git上拉取spring源码来学习Spring源码。因为里面相较于IDE
- 自定义类:using System;using System.Collections.Generic;using System.Linq;u
- 本文实例为大家分享了Unity实现弧形移动效果的具体代码,供大家参考,具体内容如下一、实现效果二、第一种实现方法——弧形插值using Un
- InheritableThreadLocal的作用: 当我们需要在子线程中使用父线程中的值得时候我们就可以像使用ThreadLocal那样来
- Input源码解读——从"Show tabs"开始本文基于Android T版本
- float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。而且使用BigDe
- 1 低层级 asyncio 索引低层级 API 索引¶ 列出所有低层级的 asyncio API。1.1 获取事件循环获取
- 1.首先在 build.gradle 里导入包implementation 'com.github.PhilJay:MPAndroi
- 今晚上在编写udp传输文件的时候发现无法用JSON传输字节数组,试了很多种办法都会报错,最后查资料找到了Base64这个类,这个类可以将字节
- 有时安全不得不考虑,看看新闻泄漏风波事件就知道了我们在用Spring boot进行开发时,经常要配置很多外置参数ftp、数据库连接信息、支付
- 合理的使用规则引擎可以极大的减少代码复杂度,提升代码可维护性。业界知名的开源规则引擎有Drools,功能丰富,但也比较庞大。在一些简单的场景
- 第 1 步:将这个 Spring Boot 项目的打包方式设置为 war。<packaging>war</packagin
- 本文实例讲述了Android显示网络图片的方法,分享给大家供大家参考。具体方法如下:一般来说,在Android中显示一张网络图片其实是非常简
- 看到某些App里面有读取联系人的功能,然后自己尝试了一下。发现这个挺简单的。然后自己就做了一个demo给大家,希望借这个demo可以让大家学
- 1. 起源KV项目下载底层重构升级决定采用独立进程进行Media下载处理,以能做到模块复用之目的,因此涉及到了独立进程间的数据传递问题。目前
- 拆分实现流程请看下面这张图首先我们得对线程池进行一个功能拆分Thread Pool 就是我们的线程池,t1,t2,t3代表三个线程Block
- android root权限破解分析许多机友新购来的Android机器没有破解过Root权限,无法使用一些需要高权限的软件,以及进行一些高权
- 前言通常在工作中比较常用到的Microsoft Word是属于国外的文档内容编辑软件,其编译技术均属国外。而OFD是一种我国的自主文档格式,