CMake静态库和动态库构建实例

news2024/10/7 7:26:14

任务

  1. 建⽴⼀个静态库和动态库,提供 HelloFunc 函数供其他程序编程使⽤,HelloFunc 向终端输出 Hello World 字
    符串。
  2. 安装头⽂件与共享库。

构建过程

构建动态库

目录结构

jyhlinux@ubuntu:~/share/makefile_cmake/cmake01$ tree
.
├── build   #在一个build文件中进行外部构建
├── CMakeLists.txt
└── lib
    ├── CmakeLists.txt
    ├── hello.cpp
    └── hello.h

hello.h

#ifndef HELLO_H
#define Hello_H
void HelloFunc();
#endif

hello.cpp

#include "hello.h"
#include <iostream>
void HelloFunc(){
std::cout << "Hello World" << std::endl;
}

cmake01/CMakeLists.txt

PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)

cmake01/lib/CMakeLists.txt

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) 解释:

用${LIBHELLO_SRC}生成动态库,生成的动态库名字为libhello.so

生成的动态库存放在cmake01/build/bin 目录下,这是cmake01/CMakeLists.txt中代码导致的。

开始构建

  • 进入build目录,并执行cmake生成makefile文件,最后再执行make生成动态库文件
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/lib$ cd ../build/
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make
  • 得到的结果,可以看到bin目录下有libhello.so这个动态库文件:
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build/bin$ ls
CMakeFiles  cmake_install.cmake  libhello.so  Makefile

同时构建动态库和静态库

只需要修改cmake01/lib/CMakeLists.txt

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

#对hello_static进行重命名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
#表示在执行make clean时会删除名为hello_static的目标文件
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)


ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

开始构建

jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make

在这里插入图片描述

安装共享库和使用外部共享库及头文件

修改cmake01/lib/CMakeLists.txt

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

#对hello_static进行重命名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
#表示在执行make clean时会删除名为hello_static的目标文件
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)


ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

#安装头文件
INSTALL(FILES hello.h DESTINATION include/hello)
#⼆进制,静态库,动态库安装都⽤TARGETS
#ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执⾏⽬标⼆进制。
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

开始构建动态库和静态库并安装

jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake -DCMAKE_INSTALL_PREFIX=/usr ..  #指定安装路径的前缀
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ sudo make install

在这里插入图片描述

使用外部共享库及头文件

新建一个项目,结构如下

jyhlinux@ubuntu:~/share/makefile_cmake/cmake02$ tree
.
├── build
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    └── main.cpp

main.cpp

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

cmake02/CMakeLists.txt

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

cmake02/src/CMakeLists.txt

ADD_EXECUTABLE(hello main.cpp)

开始编译

jyhlinux@ubuntu:~/share/makefile_cmake/cmake02/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake02/build$ make

此时会出现如下错误

在这里插入图片描述

表示找不到这个头文件,原因是:

这个头文件在 /usr/include/hello中,而系统默认只会在/usr/include/目录下查找头文件。所以得添加该目录,即修改cmake02/src/CMakeLists.txt

INCLUDE_DIRECTORIES(/usr/include/hello) #注意位置
ADD_EXECUTABLE(hello main.cpp) 

之后再次编译,又会出现如下错误:undefined reference to .

在这里插入图片描述

这个错误一般是缺失库文件,解决办法就是**添加需要连接的共享库。**在cmake02/src/CMakeLists.txt进行修改

INCLUDE_DIRECTORIES(/usr/include/hello)
ADD_EXECUTABLE(hello main.cpp)
TARGET_LINK_LIBRARIES(hello libhello.so) #添加需要连接的共享库 /usr/lib/libhello.so

如果要连接静态库,就改变为TARGET_LINK_LIBRARIES(hello libhello.a)

再次编译后可以通过,并生成目标可执行文件 hello,存放在cmake/02/build/bin目录下,并可以成功执行

在这里插入图片描述

参考资料

  1. 从零开始详细介绍CMake

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/80695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

m基于多用户MIMO系统的分布式可重构注水算法的matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 在单用户MIMO场景中&#xff0c;空间复用技术能够带来高数据速率的传输&#xff0c;但是也需要一些前提条件&#xff0c;比如发射端的预编码或者接收端的信道估计与信号检测。然而&#xff0c;在…

java项目-第169期ssm二手交易平台网站-ssm毕业设计_计算机毕业设计

java项目-第169期ssm二手交易平台网站-ssm毕业设计 【源码请到下载专栏下载】 《ssm二手交易平台网站》 该项目分为3个角色&#xff0c;管理员、用户、商家。 用户可以浏览前台商品并且进行购买。在个人后台可以看到自己的商品。 商家可以对商品进行商品分类管理、商品信息管理…

React 学习笔记:组件通信

组件通信 组件为什么需要通信呢&#xff1f;这是因为组件是独立且封闭的单元&#xff0c;默认情况下&#xff0c;组件只能使用自己的数据&#xff0c;但是多个组件之间不可避免的要共享某些数据&#xff0c;为了实现这些功能&#xff0c;就需要打破组件的独立封闭性&#xff0…

深度学习入门(五十九)循环神经网络——通过时间反向传播

深度学习入门&#xff08;五十九&#xff09;循环神经网络——通过时间反向传播前言循环神经网络——通过时间反向传播教材1 循环神经网络的梯度分析1.1 完全计算1.2 截断时间步1.3 随机截断1.4 比较策略2 通过时间反向传播的细节3 小结前言 核心内容来自博客链接1博客连接2希…

基于java+springboot+vue+mysql的甜品蛋糕销售商城网站

项目介绍 随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。人们生活水平的不断提高&#xff0c;日常生活中用户对网上蛋糕商城方面的要求也在不断提高&#xff0c;网上蛋糕商城得到广大用户的青睐&#xff0c;使得网上蛋糕商城的开发成为必需而且紧迫的事情。本系…

Docker笔记--使用数据卷实现容器与宿主机的数据交互

1--数据卷的介绍和作用 在 Docker 架构中&#xff0c;宿主机系统和容器之间不能直接传递数据&#xff0c;同时当容器被删除时&#xff0c;容器所有的数据都会被清除&#xff1b; 数据卷能够在宿主机与容器、容器与容器之间搭建数据传输和共享的通道&#xff0c;当容器内的目录与…

C++ 快速复习-数据类型

内置数据类型 int、unsigned int 、long、unsigned long 、short、char、signed char、bool、 long long float、double、long double 等 无符号的数据类型 主要在于 不在区分 -&#xff0c;数据波动范围变大。另外&#xff0c;值得注意的是 unsigned 类型的数据 不建议在输出…

玩以太坊链上项目的必备技能(变量作用域-Solidity之旅五)

在前文我们讲过 Solidity 是一种静态类型的语言&#xff0c;这就意味着在声明变量前需先指定类型。 而 Solidity 对变量划分了以下三种作用域范围&#xff1a; 状态变量&#xff08;State Variable&#xff09;&#xff1a; ​ 该变量的值被永久地存放在合约存储中&#xff…

JS新年倒计时

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;前端案例分…

Java---线程详解

目录 一、线程的介绍 二、线程的使用 &#xff08;1&#xff09;多线程的实现 1&#xff1a;继承Thread类 2&#xff1a;实现Runnable接口 &#xff08;2&#xff09;设置和获取线程名称 1:继承Thread类 2&#xff1a;实现Runnable接口 &#xff08;3&#xff09;线程…

Java学习—多线程Thread

多线程1. 线程简介1.1 普通方法和多线程1.2 程序、进程、线程2. 线程创建2.1 Thread类案例&#xff1a;下载图片2.2 Runnable接口案例&#xff1a;龟兔赛跑2.3 Callable接口3. 静态代理4. Lamda表达式5. 线程状态5.1 线程方法5.2 停止线程5.3 线程休眠5.4 线程礼让-yield5.5 Jo…

揭秘SpringMVC-DispatcherServlet之九大组件(二)

前言 上回聊到了HandlerAdapter&#xff0c;今天继续聊后面的组件。今天的主角是HandlerMapping&#xff0c;这篇文章全为他服务了。 HandlerMapping 上回说的Handler&#xff0c;我们说是处理特定请求的。也就是说&#xff0c;不是所有的请求都能处理。那么问题来了&#x…

gateway初始化与配置

1、排除依赖 spring-boot-starter-webflux 2、添加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency><groupId>org.springf…

基于GDAL的JAVA生成GDB文件实战

前言 在之前博客中&#xff0c;陆续的介绍了关于gdb文件的读取&#xff0c;gis利器之Gdal&#xff08;三&#xff09;gdb数据读取&#xff0c;玩转GDAL一文带你深入Windows下FileGDB驱动支持&#xff0c;这些文章主要都是介绍gdal的读取gdb以及简单的gdb文件读写。在实际工作中…

VJ个人周赛

A:模拟 题意&#xff1a;给定了N个任务&#xff0c;每个任务都有一个优先级&#xff08;1~9&#xff09;&#xff0c;数字越大&#xff0c;优先级越高。将这些任务放入队列中&#xff0c;如果出队的元素&#xff08;x&#xff09;&#xff0c;x的优先级不是最高的&#xff0c;那…

从高级测试到测试开发有什么感悟

最近加入了新的团队&#xff0c;角色发生较大的转变&#xff0c;在这里分享一下自己的感受。 测试的划分 如果我们把产品的生产看成一个流水线的话&#xff0c;那么测试就是流水线上的一个重要岗位&#xff0c;把控着产品的质量。 当然&#xff0c;产品类型的不同&#xff0…

信息系统安全管理

信息系统安全是一个绕不开的话题。从事IT行业&#xff0c;不论何种角色&#xff0c;哪个工种&#xff0c;都需要有所了解。 一、信息系统安全策略 1、概述 信息系统安全策略是指对&#xff08;本单位&#xff09;信息系统的安全风险&#xff08;安全威胁&#xff09;进行有效…

小白学编程(js):通过按钮变换背景颜色

《JavaScript从入门到精通》【例9.1】 代码演示&#xff1a; <body><form class"form1" action"" name"form1" method"psot"><p><input type"button" name"Submit" value"变换背景&qu…

[附源码]计算机毕业设计基于Java的图书购物商城Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux常用环境配置及软件安装(持续更新)

1、jdk 1、下载jdk Linux安装包 把安装包放到自己定义的目录下 安装包网盘 提取码&#xff1a;n5hj 2、解压 解压安装包&#xff0c;输入命令&#xff1a; tar -xvf jdk-8u221-linux-x64.tar.gz 解压完成后会生成一个新文件 3、配置环境变量 编辑profile文件 vim /etc/p…