Cmake Practice(三)
五,静态库与动态库构建
本节的任务:
1,建立一个静态库和动态库,提供 HelloFunc 函数供其他程序编程使用,HelloFunc向终端输出 Hello World 字符串。
2,安装头文件与共享库。
一,准备工作:
在/leran-cmake/目录建立practice3目录,用于存放本节涉及到的工程
mkdir practice3
cd practice3
二,建立共享库
mkdir lib
在 practice3 目录下建立 CMakeLists.txt,内容如下:
PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)
在 lib 目录下建立两个源文件 hello.c 与 hello.h
hello.c 内容如下:
#include “hello.h”
void HelloFunc()
{printf(“Hello World\n”);
}
hello.h 内容如下:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
void HelloFunc();
#endif
在 lib 目录下建立 CMakeLists.txt,内容如下:
SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
三,编译共享库:
还是在build目录中进行编译
cd ../../build/
rm -rf * //删除上一个工程的编译文件
cmake ../practice3/
make
这时,你就可以在 lib 目录得到一个 libhello.so,这就是我们期望的共享库。
如果你要指定 libhello.so 生成的位置,可以通过在主工程文件 CMakeLists.txt 中修改 ADD_SUBDIRECTORY(lib)指令来指定一个编译输出位置或者在 lib/CMakeLists.txt 中添加SET(LIBRARY_OUTPUT_PATH <路径>)来指定一个新的位置。
这两者的区别我们上一节已经提到了,所以,这里不再赘述,下面,我们解释一下一个新的指令 ADD_LIBRARY
ADD_LIBRARY(libname
[SHARED|STATIC|MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
你不需要写全 libhello.so,只需要填写 hello 即可,cmake 系统会自动为你生成libhello.X
类型有三种:
SHARED,动态库
STATIC,静态库
MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。
EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。
四,添加静态库:
同样使用上面的指令,我们在支持动态库的基础上再为工程添加一个静态库,按照一般的习惯,静态库名字跟动态库名字应该是一致的,只不过后缀是.a 罢了。
下面我们用这个指令再来添加静态库:
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
然后再在 build 目录进行外部编译,我们会发现,静态库根本没有被构建,仍然只生成了一个动态库。因为 hello 作为一个 target 是不能重名的,所以,静态库构建指令无效。
如果我们把上面的 hello 修改为 hello_static:
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
就可以构建一个 libhello_static.a 的静态库了。
这种结果显示不是我们想要的,我们需要的是名字相同的静态库和动态库,因为 target 名称是唯一的,所以,我们肯定不能通过 ADD_LIBRARY 指令来实现了。这时候我们需要用到另外一个指令:
SET_TARGET_PROPERTIES,其基本语法是:
SET_TARGET_PROPERTIES(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本。
在本例中,我们需要作的是向 lib/CMakeLists.txt 中添加:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
这样,我们就可以同时得到 libhello.so/libhello.a 两个库了。
目前lib/CMakeLists.txt的内容如下:
SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello_shared SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_shared PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
五,动态库版本号
按照规则,动态库是应该包含一个版本号的,我们可以看一下系统的动态库,一般情况是:
libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2
为了实现动态库版本号,我们仍然需要使用 SET_TARGET_PROPERTIES 指令。
具体使用方法如下:
SET_TARGET_PROPERTIES(hello_shared PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本。
将上述指令加入 lib/CMakeLists.txt 中,重新构建看看结果。
在 build/lib 目录会生成:
libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so ->libhello.so.1
六,安装共享库和头文件
以上面的例子,我们需要将 libhello.a, libhello.so.x 以及 hello.h 安装到系统目录,才能真正让其他人开发使用,在本例中我们将 hello 的共享库安装到/lib目录,将 hello.h 安装到/include/hello 目录。
利用上一节了解到的 INSTALL 指令,我们向 lib/CMakeLists.txt 中添加如下指令:
INSTALL(TARGETS hello_shared hello_staticLIBRARY DESTINATION libARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)
注意,静态库要使用 ARCHIVE 关键字
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
sudo make install //需要权限,否则会失败
我们就可以将头文件和共享库安装到系统目录/usr/lib 和/usr/include/hello 中了
七,小结:
本小节,我们谈到了:
如何通过 ADD_LIBRARY 指令构建动态库和静态库。
如何通过 SET_TARGET_PROPERTIES 同时构建同名的动态库和静态库。
如何通过 SET_TARGET_PROPERTIES 控制动态库版本
最终使用上一节谈到的 INSTALL 指令来安装头文件和动态、静态库。
在下一节,我们需要编写另一个高级一点的 Hello World 来演示怎么使用我们已经构建的
构建的共享库 libhello 和外部头文件。
Cmake Practice(三)相关推荐
- 《cmake practice》总结 | cmake的构建过程与基本指令
cmake 〇.基本语法规则 0.1 变量 0.2 指令规则 0.3 基本构建过程 一.基本指令 1. PROJECT指令 2. SET指令 3. MESSAGE指令 4. ADD_EXECUTABL ...
- Cmake Practice(一)
最近在编译安装OpenCV和OpenGL的时候,发现构建系统都换成了cmake自动生成Makefile,确实方便了不少,因此打算学习下cmake的语法规则. 参考书籍<< Cmake Pr ...
- Cmake Practice
0.前言 因为在使用OpenCV的过程中都接触到了许多关于CMake的使用,于是就想了解一下CMake究竟是怎样一个东西,有什么作用.顺便做一个学习笔记. 本文参考<CMake Practic ...
- Cmake Practice(二)
转载自 https://blog.csdn.net/xuewend/article/details/78228671 感谢作者:fishmov 上一节我们用一个实例简单地演示了cmake的用法,这一 ...
- 熟悉 CMake (三)—— 配置 opencv3
对 opencv 3 的配置十分简单,只需修改 CMakeLists.txt 文件: 在最后一行 add_executable 前后插入如下内容: find_package(OpenCV REQUIR ...
- 学习C++:C++进阶(三)CMake基础篇---用一个小型项目了解CMake及环境构建
V1.1 于2022年7月15日第二次修改:添加了比较多的解释图,解读了各类库的CMakelist.txt文件 目录 第一部分 基础篇(Basics) 1.0 本部分主要学什么(Intro) 1.1 ...
- HelloWorld CMake Demo 03:CMake中构建静态库与动态库及其使用
继续完善Hello World,建立它的共享库,包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc向终端输出Hello W ...
- 【CMake】Android Studio 中使用 CMake 编译单个 C++ 源文件 ( 常用的 CMake 命令解析 )
文章目录 一.Android Studio 中使用 CMake 编译单个 C++ 源文件 二.cmake_minimum_required 命令设置最小 CMake 版本 三.project 命令设置 ...
- 【错误记录】Android NDK 错误排查记录 ( Could not get version from cmake.dir path ‘xxx\cmake\3.6.4111459‘. )
文章目录 一. 报错信息 二. 问题分析 三. 解决方案 一. 报错信息 报错信息 : Executing tasks: [:app:assembleDebug] in project D:\002_ ...
最新文章
- AI视频行为分析系统项目复盘——技术篇2:视频流GPU硬解码
- python爬取百度文库付费文档_亲测免费转换百度文库付费文件
- 机器学习(MACHINE LEARNING)主成分分析(PCA降维)
- WCF获取客户端IP和端口
- Plugin org.apache.maven.plugins:maven-resources-plugin:2.6
- 7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)
- 怎么把页面按比例缩小_做PPT多图排版千万别套模板了,按这28种版式来,绝对靠谱!...
- scala不可变和可变_Scala使期货变得轻松
- Java中volatile的作用以及用法
- oracle算加权平均的函数,如何用变异函数计算加权平均数?
- 记录一次China GT比赛历程
- Jan Ozer:高清直播互动场景下的硬编码如何选型?
- 配对t检验的应用条件是什么_配对t检验的适用条件,独立样本T检验、配对T检...
- 编写程序验证四方定理C语言,C语言中怎么应用四方定理
- NoSQL之Redis配置与数据库常用命令
- the quieter you become,the more you could see.
- node+express+mongodb初体验
- 回溯法 | 求解装载问题
- 什么是Oracle AOL
- 互联网金融竞品分析:点融网、金蛋理财、懒投资(求指点 )