五,静态库与动态库构建
本节的任务:

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(三)相关推荐

  1. 《cmake practice》总结 | cmake的构建过程与基本指令

    cmake 〇.基本语法规则 0.1 变量 0.2 指令规则 0.3 基本构建过程 一.基本指令 1. PROJECT指令 2. SET指令 3. MESSAGE指令 4. ADD_EXECUTABL ...

  2. Cmake Practice(一)

    最近在编译安装OpenCV和OpenGL的时候,发现构建系统都换成了cmake自动生成Makefile,确实方便了不少,因此打算学习下cmake的语法规则. 参考书籍<< Cmake Pr ...

  3. Cmake Practice

    0.前言 因为在使用OpenCV的过程中都接触到了许多关于CMake的使用,于是就想了解一下CMake究竟是怎样一个东西,有什么作用.顺便做一个学习笔记.  本文参考<CMake Practic ...

  4. Cmake Practice(二)

    转载自 https://blog.csdn.net/xuewend/article/details/78228671  感谢作者:fishmov 上一节我们用一个实例简单地演示了cmake的用法,这一 ...

  5. 熟悉 CMake (三)—— 配置 opencv3

    对 opencv 3 的配置十分简单,只需修改 CMakeLists.txt 文件: 在最后一行 add_executable 前后插入如下内容: find_package(OpenCV REQUIR ...

  6. 学习C++:C++进阶(三)CMake基础篇---用一个小型项目了解CMake及环境构建

    V1.1 于2022年7月15日第二次修改:添加了比较多的解释图,解读了各类库的CMakelist.txt文件 目录 第一部分 基础篇(Basics) 1.0 本部分主要学什么(Intro) 1.1 ...

  7. HelloWorld CMake Demo 03:CMake中构建静态库与动态库及其使用

    继续完善Hello World,建立它的共享库,包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc向终端输出Hello W ...

  8. 【CMake】Android Studio 中使用 CMake 编译单个 C++ 源文件 ( 常用的 CMake 命令解析 )

    文章目录 一.Android Studio 中使用 CMake 编译单个 C++ 源文件 二.cmake_minimum_required 命令设置最小 CMake 版本 三.project 命令设置 ...

  9. 【错误记录】Android NDK 错误排查记录 ( Could not get version from cmake.dir path ‘xxx\cmake\3.6.4111459‘. )

    文章目录 一. 报错信息 二. 问题分析 三. 解决方案 一. 报错信息 报错信息 : Executing tasks: [:app:assembleDebug] in project D:\002_ ...

最新文章

  1. AI视频行为分析系统项目复盘——技术篇2:视频流GPU硬解码
  2. python爬取百度文库付费文档_亲测免费转换百度文库付费文件
  3. 机器学习(MACHINE LEARNING)主成分分析(PCA降维)
  4. WCF获取客户端IP和端口
  5. Plugin org.apache.maven.plugins:maven-resources-plugin:2.6
  6. 7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)
  7. 怎么把页面按比例缩小_做PPT多图排版千万别套模板了,按这28种版式来,绝对靠谱!...
  8. scala不可变和可变_Scala使期货变得轻松
  9. Java中volatile的作用以及用法
  10. oracle算加权平均的函数,如何用变异函数计算加权平均数?
  11. 记录一次China GT比赛历程
  12. Jan Ozer:高清直播互动场景下的硬编码如何选型?
  13. 配对t检验的应用条件是什么_配对t检验的适用条件,独立样本T检验、配对T检...
  14. 编写程序验证四方定理C语言,C语言中怎么应用四方定理
  15. NoSQL之Redis配置与数据库常用命令
  16. the quieter you become,the more you could see.
  17. node+express+mongodb初体验
  18. 回溯法 | 求解装载问题
  19. 什么是Oracle AOL
  20. 互联网金融竞品分析:点融网、金蛋理财、懒投资(求指点 )

热门文章

  1. minikube DNS fails after SRV query
  2. 货源清单与ME57分配时显示的信息记录
  3. 兼容ie(8、9、10、11),google等浏览器的多附件上传完整演示
  4. 押注电动化和自动驾驶的关键零部件,博世国产第二代 iBooster 智能助力器
  5. vue+antdesign 高德地图根据名称选点功能,并去除logo 封装组件
  6. python中eval方法的妙用
  7. 全球及中国充电桩行业建设动态与竞争格局展望报告2022版
  8. 文献回顾 | 你还在这样使用工业企业数据库吗?
  9. MFC判断一个点是否在一个区域内
  10. 如何让你的U盘在电脑上传输文件时速度快一些