cmake-3
本节内容,转载文章:https://www.zhihu.com/column/c_200294809 ;参考程序:https://github.com/BrightXiaoHan/CMakeTutorial
实验环境:MacOS
find_package引入外部库
为了方便我们在项目中引入外部依赖包,cmake官方为我们预定义了许多寻找依赖包的Module,他们存储在path_to_your_cmake/share/cmake-/Modules目录下。每个以Find.cmake命名的文件都可以帮我们找到一个包。我们也可以在官方文档中【https://cmake.org/cmake/help/latest/module/FindCURL.html】查看到哪些库官方已经为我们定义好了。
find_package用于引入外部库,通过查找依赖库的文件路径,有两种模式:
(1)Module模式
在Module模式中,cmake需要找到一个叫做Find.cmake的文件。这个文件负责找到库所在的路径,为我们的项目引入头文件路径和库文件路径。cmake搜索这个文件的路径有两个,一个是cmake安装目录下的share/cmake-/Modules目录,另一个使我们指定的CMAKE_MODULE_PATH的所在目录。
(2)Config模式
如果Module模式搜索失败,没有找到对应的Find.cmake文件,则转入Config模式进行搜索。它主要通过Config.cmake 或者-config.cmake这两个文件来引入我们需要的库。以我们下面安装的glog库为例,在我们安装之后,它在/usr/local/lib/cmake/glog/目录下生成了glog-config.cmake文件,而/usr/local/lib/cmake//正是find_package函数的搜索路径之一。
通过模式Module引入外部库
引入外部库:curl库
curl是Linux下一个非常著名的下载库,通过这个库,可以很简单的实现文件的下载等操作。支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。
官方定义好的
我们看到官方已经定义好了FindCURL.cmake。所以我们在CMakeLists.txt中可以直接用find_pakcage进行引用,可以看作安装CMake时自带的!
(1)引用
find_package(CURL)
add_executable(curltest curltest.cc)
if(CURL_FOUND)
target_include_directories(curltest PRIVATE ${CURL_INCLUDE_DIR})
target_link_libraries(curltest ${CURL_LIBRARY})
else(CURL_FOUND)
message(FATAL_ERROR "CURL library not found")
endif(CURL_FOUND)
对于系统预定义的 Find.cmake 模块,使用方法一般如上例所示。
每一个模块都会定义以下几个变量 -
<LibaryName>_FOUND
<LibaryName>_INCLUDE_DIR or <LibaryName>_INCLUDES <LibaryName>_LIBRARY or <LibaryName>_LIBRARIES
你可以通过_FOUND 来判断模块是否被找到,如果没有找到,按照工程的需要关闭 某些特性、给出提醒或者中止编译,上面的例子就是报出致命错误并终止构建。 如果_FOUND 为真,则将_INCLUDE_DIR 加入 INCLUDE_DIRECTORIES。
通过模式Config引入非官方的库
假设此时我们需要引入glog库来进行日志的记录,我们在Module目录下并没有找到 FindGlog.cmake。所以我们需要自行安装glog库,再进行引用。
glog库:Google glog是一个基于程序级记录日志信息的C++库,编程使用方式与c++的stream操作类似,例如:LOG(INFO) << “one” << “two” << “three”;
其中“LOG”宏为日志输出关键字,”INFO”为严重性程度
(1)安装
# clone该项目
git clone https://github.com/google/glog.git
# 切换到需要的版本
cd glog
git checkout v0.40
# 根据官网的指南进行安装
cmake -H. -Bbuild -G "Unix Makefiles"
cmake --build build
cmake --build build --target install
在我们安装之后,它在/usr/local/lib/cmake/glog/目录下生成了glog-config.cmake文件,而/usr/local/lib/cmake//正是find_package函数的搜索路径之一。
(2)引用
find_package(glog)
add_executable(glogtest glogtest.cc)
if(GLOG_FOUND)
# 由于glog在连接时将头文件直接链接到了库里面,所以这里不用显示调用target_include_directories
target_link_libraries(glogtest glog::glog)
else(GLOG_FOUND)
message(FATAL_ERROR ”glog library not found”)
endif(GLOG_FOUND)
引入自定义库
编写了一个新的函数库,我们希望别的项目可以通过find_package对它进行引用
在当前目录下新建一个ModuleMode的文件夹,在里面我们编写一个计算两个整数之和的一个简单的函数库。库函数以手工编写Makefile的方式进行安装,库文件安装在/usr/lib目录下,头文件放在/usr/include目录下。
(1)Makefile文件
# 1、准备工作,编译方式、目标文件名、依赖库路径的定义。
CC = g++
CFLAGS := -Wall -O3 -std=c++11
OBJS = libadd.o #.o文件与.cpp文件同名
LIB = libadd.so # 目标文件名
INCLUDE = ./ # 头文件目录
HEADER = libadd.h
all : $(LIB)
# 2. 生成.o文件
$(OBJS) : libadd.cc
$(CC) $(CFLAGS) -I ./ -fpic -c $< -o $@
# 3. 生成动态库文件
$(LIB) : $(OBJS)
rm -f $@
g++ $(OBJS) -shared -o $@
rm -f $(OBJS)
# 4. 删除中间过程生成的文件
clean:
rm -f $(OBJS) $(TARGET) $(LIB)
# 5.安装文件
install:
mkdir -p /usr/lib/add
cp $(LIB) /usr/lib/add
cp $(HEADER) /usr/include
(2)编译安装
make
sudo make install
(3)接下来我们回到我们的Cmake项目中来,在cmake文件夹下新建一个FindAdd.cmake的文件。我们的目标是找到库的头文件所在目录和共享库文件的所在位置。
# 在指定目录下寻找头文件和动态库文件的位置,可以指定多个目标路径
find_path(ADD_INCLUDE_DIR libadd.h /usr/include/ /usr/local/include ${CMAKE_SOURCE_DIR}/ModuleMode)
find_library(ADD_LIBRARY NAMES add PATHS /usr/lib/add /usr/local/lib/add ${CMAKE_SOURCE_DIR}/ModuleMode)
if (ADD_INCLUDE_DIR AND ADD_LIBRARY)
set(ADD_FOUND TRUE)
endif (ADD_INCLUDE_DIR AND ADD_LIBRARY)
这时我们便可以像引用curl一样引入我们自定义的库了。
(4)在CMakeLists.txt中添加
# 将项目目录下的cmake文件夹加入到CMAKE_MODULE_PATH中,让find_pakcage能够找到我们自定义的函数库
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
add_executable(addtest addtest.cc)
find_package(ADD)
if(ADD_FOUND)
target_include_directories(addtest PRIVATE ${ADD_INCLUDE_DIR})
target_link_libraries(addtest ${ADD_LIBRARY})
else(ADD_FOUND)
message(FATAL_ERROR "ADD library not found")
endif(ADD_FOUND)
cmake-3的更多相关文章
- 使用cmake自动构建工程
公司引擎是用cmake根据目标平台来构建工程的,刚接触的时候深深体会到cmake的方便:如果目标平台是windows,它可以帮你自动构建出vs工程:如果是安卓,自动构建出eclipse工程,如果是IO ...
- CMake
使用CMake编译跨平台静态库 http://www.tuicool.com/articles/3uu2Yj cmake命令 安装.用法简介 https://fukun.org/archives/04 ...
- CMake学习笔记
C++开发者必备技能CMake 先简单介绍一下,CMake是一个跨平台的编译工具,它可以根据不用的平台,不同的编译环境,生成不同的MakeFile,从而控制编译的过程. 使用CMake的步骤: 1. ...
- VS 2013编译64位版本QT 4.8.6及使用cmake为依赖QT生成VS项目时Could NOT find Qt4
对于一些已经解决的问题,本博客不再讨论.只将本人遇到的问题做简单的说明. 一.VS 2013编译64位版本QT 4.8.6 QT项目官网中,对于QT4,其只提供了windows X86的版本,并且支持 ...
- cmake cannot find package
cmake 找不到package,如 find_package (OpenMesh REQUIRED) 出现错误 在项目的文件夹中找到 FindOpenMesh.cmake 文件,将其所在路径添加到 ...
- Cmake的交叉编译
http://www.cmake.org/Wiki/CMake_Cross_Compiling
- CMake命令/函数汇总(翻译自官方手册)
查看官方文档 cmake命令 选项 CMake变量 CMake命令汇总 / add_custom_command add_custom_target/add_definitions/add_depen ...
- 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
随机推荐
- 初识cuda一文通
cuda学习博客 本文为本人cuda学习过程中的记录和理解,多参考@谭升等大佬前辈的博客,以及NVIDIA官方文档.如有错误烦请指正,如有侵权请联系删除. 0. 并行计算与计算机架构 计算机架构是并行 ...
- Visual Studio 快速分析 .NET Dump 文件
前言 在开发和维护 .NET 应用程序的过程中,有时会遇到难以捉摸的性能瓶颈或内存泄漏等问题.这些问题往往发生在生产环境中,难以复现.为了更准确地诊断这些运行时问题,通常会收集应用程序在生产环境中的内 ...
- RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配
RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源.GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配 Text Embedding 榜单:MTEB.C-MTEB <MTEB: Mas ...
- 使用wxpython开发跨平台桌面应用,设计系统的登录界面
一般的系统登统界面,设计好看一些,系统会增色不少,而常规的桌面程序,包括Web上的很多界面,都借助于背景图片的效果来增色添彩,本篇随笔介绍基于WxPython来做一个登录界面效果,并对系统登录界面在不 ...
- nginx配置php-fpm虚拟主机站点
ubuntu下安装nginx 很简单 sudo apt-get install nginx 然后安装php-fpm 我这本地php7.4所以这么写 sudo apt search php7.4-fpm ...
- MyBatis入门示例——MyBatis学习笔记之一
MyBatis是另外一款优秀的ORM框架,前身为iBATIS.凡事预则立,不预则废.鉴于以后的项目可能会用到它,因此决定提前学习.本着分享和督促自己学习的目的,笔者将陆续把学习笔记贴出,希望对朋友们有 ...
- ANTLR语法层的选项及动作 - ANTLR
ANTLR语法层的选项 ANTLR语法层的选项中可以设置一系列的键值从而影响ANTLR输出的代码.这些选项是全局的,除非在某条规 则中覆盖了这些选项,否则这些选项会影响到该语法中的所有元素.选项应该紧 ...
- python之常用开发包
1.passlib (https://passlib.readthedocs.io/en/stable/) passlib 目前常见的不可逆加密算法有以下几种: 一次MD5(使用率很高) 将密码与一个 ...
- 鸿蒙UI布局实战 —— 个人中心页面开发
1.前言 接下里我们将开启"鸿蒙UI布局系列"的学习,第一站:学习线性布局(Row/Column)+ 弹性布局(Flex) 在展开学习前,先上一个实战demo--开发一个个人中心页 ...
- orangepi zero3开启指定频段WiFi热点的指令
步骤 通过 -c 命令即可指定wifi频段,避免和其他wifi的频段撞在一起. 例如下面这条命令创建了一个频段为40,WiFi名为zero3,网段为192.168.12.0/24的WiFi热点 sud ...