Mac 下 CMake 的配置与使用

文章目录

  • 安装与配置
  • 编译单个源文件
    • 编译前的准备
    • 开始编译
  • 编译多个源文件
    • 多个源文件在同一目录下
    • 多个源文件在不同目录下
    • math 目录下的 CMakeLists.txt
    • 根目录的 CMakeLists.txt
      • option 选项
  • 导入外部库
    • 本地导入(find_package)
    • 外部导入(FetchContent)
  • 安装与测试
    • 安装
    • 测试
  • 生成安装包

安装与配置

  1. 进入 官网下载 dmg 文件:
    请添加图片描述

(在红圈中根据自己的Mac版本任选一个 dmg 下载)

  1. 安装完成后,从菜单栏选择:Tools–How to Install For Command Line Use请添加图片描述

  2. 在终端命令行中输入弹出弹窗中第二项 to install symlinks to '/usr/local/bin', run: 的指令:
    请添加图片描述

  3. 检查是否配置成功:
    请添加图片描述

cmake --version 可以正常识别,配置成功。


编译单个源文件

编译前的准备

使用 CMake 进行编译之前需要具备三大内容:
请添加图片描述

他们的作用及内容如下:

源文件 main.cpp

#include <iostream>int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";return 0;
}

cmake 构建规则 CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 
# cmake最低版本需求,不加入此行会受到警告信息PROJECT(HELLO) 
# 项目名称,同时会自动生成 PROJECT_NAME 变量,
# 使用${PROJECT_NAME} 即可访问到 hello_cmake。AUX_SOURCE_DIRECTORY(. SRC_LIST) 
# 把当前目录(.)下所有源代码文件和头文件加入变量SRC_LISTADD_EXECUTABLE(hello ${SRC_LIST}) # 生成应用程序 hello

在编译单个文件时,也可以不添加第三句规则,而是直接在第四句规则中指定编译的文件,例如,删除第三句,并将第四句改为如下内容,本编译规则依然有效:

ADD_EXECUTABLE(hello main.cpp) #生成应用程序 hello

AUX_SOURCE_DIRECTORY

  • 第一个参数是目录的路径
  • 第二个参数是变量名。当我们使用这个命令时,就会将指定目录下的所有源文件保存到指定的变量名中。
  • 这里将名为 main.cpp 的源文件编译成一个名称为 hello 的可执行文件。

保存临时构建文件和目标文件的文件夹 build

  • 本示例中,该步骤本质上是创建一个可以位于文件系统上任何位置的构建文件夹(这里只是选择了在当前文件夹中创建)。 所有临时构建和目标文件都位于此目录中,以保持源代码树的整洁。该种构建方式为外部构建
  • 其实也可以没有这个文件夹,而是以内部构建的形式直接在源文件目录构建项目,只是会导致临时文件和源代码放在一起,不好清理。

开始编译

  • 通过 cmake .. 命令开始进行编译:

请添加图片描述

  • 使用 cmake 生成的 makefile 编译得到可执行文件

请添加图片描述

  • 此时在当前目录下,就会生成可执行文件 hello

请添加图片描述

  • 将其运行查看是否成功编译:

请添加图片描述


编译多个源文件

多个源文件在同一目录下

与编译单个源文件相比,难点主要是对 AUX_SOURCE_DIRECTORY 命令的使用。

如果不想使用 AUX_SOURCE_DIRECTORY 命令,也可以使用 set 来手动将多个源文件保存到变量名中:

set(SRC_LISTother.cppmain.cpp
)

多个源文件在不同目录下

.
├── CMakeLists.txt
├── main.cc
└── math├── CMakeLists.txt├── MathFunctions.cc└── MathFunctions.h

在多个目录下有着多个源文件的情况下,需要在每个目录中都编写一个 CMakeLists.txt。这里为了方便,我们可以将 math 里的文件编译为一个静态库再通过 main 函数调用。

math 目录下的 CMakeLists.txt

math 目录下的 CMakeLists.txt 主要做的事是将当前目录下的文件编译为一个静态库:

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${DIR_LIB_SRCS})
  • add_library:用于从某些源文件创建一个库,默认生成在构建文件夹。
    • 第一个参数为库名(不需要 lib 前缀,会自动添加)
    • 第二个参数用于指定 SHARED(动态库)、STATIC(静态库)(如果不写,则通过全局的 BUILD_SHARED_LIBSFALSETRUE 来指定。上例中就没有写)
    • 第三个参数即为源文件列表。

根目录的 CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)# 项目信息
project (Demo3)# 查找目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)# 添加 math 子目录
add_subdirectory(math)# 指定生成目标
add_executable(Demo ${DIR_SRCS})# 添加链接库
target_link_libraries(Demo MathFunctions)
  • add_subdirectory:用于表示该项目包含一个子目录,此时会去处理子目录下的 CMakeLists.txt 与源文件。
  • target_link_libraries:该命令用于指明可执行文件 Demo 需要链接 MathFunctions 库。
    • 第一个参数为可执行文件名
    • 第二个参数为访问权限(PUBLICPRIVATEINTERFACE,默认为 PUBLIC
    • 第三个参数为库名(这里库名使用了 math 目录下的 CMakeLists.txt 中生成的 MathFunctions 链接库)
    • 【后两个参数可以为多个】

option 选项

面对 库文件很大 或者 库文件依赖第三方库 的时候,我们可能希望将 该库文件作为一个可选项(而不是非得链接不可)

  1. 这里仍以 MathFunctions 为例进行实现。首先在 顶层CMakeLists.txt 文件添加一个选项 option ,其基本格式如下:
option (USE_MYMATH "should we use our own math functions?" ON) 
  • 第一个参数定义选项名称。
  • 第二个参数说明选项的含义。
  • 第三个参数定义选项默认状态,一般是 OFF 或者 ON,除去 ON 之外,其他所有值都被认为是 OFF
  1. 接下来就是将构建和连接 MathFunctions 设置为可选项。修改 顶层CMakeLists.txt 文件如下所示:
if (USE_MYMATH)include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")add_subdirectory (math)# 将 ${EXTRA_LIBS} 变量中旧有的内容和 MathFunctions # 都加入到EXTRA_LIBS变量中set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)# add the executable
add_executable(Demo ${DIR_SRCS})
target_link_libraries(Demo ${EXTRA_LIBS})

PS: 这里我们使用了 USE_MYMATH 这个宏,倘若在源码中也想使用它,那么需要由 CMake 通过在配置文件 Config.h 添加以下代码:

#cmakedefine USE_MYMATH

之后源码 include 该头文件(Config.h)来实现。


导入外部库

本地导入(find_package)

本节示例的目录结构如下:

.
├── CMakeLists.txt
├── main.cpp
└── README.adoc

boost 为例,演示如何导入一个本地的第三方库, MakeLists.txt 内容如下:

cmake_minimum_required(VERSION 3.5)# Set the project name
project (third_party_include)
# 使用库文件系统和系统查找 boost install
# 注意这是第三方库,而不是自己生成的静态动态库
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
if(Boost_FOUND)message ("boost found")
else()message (FATAL_ERROR "Cannot find Boost")
endif()# Add an executable
add_executable(third_party_include main.cpp)# link against the boost libraries
target_link_libraries( third_party_includePRIVATEBoost::filesystem
)

使用 find_package 命令来在本地搜索对应的第三方库,它的参数的含义如下:

  • Boost 代表需要查询的库名称;
  • 1.46.1 代表需要库的最低版本;
  • REQUIRED 表示该库是必须的,如果找不到会报错;
  • COMPONENTS 用于检测该库的对应组件是否存在,如果不存在则认为找到的库不满足条件。
  • filesystemsystem 代表搜索的位置,分别是 库文件系统文件系统

外部导入(FetchContent)

FetchContent3.11.0 版本开始提供的功能,只需要一个 URL 或者 Git 仓库即可引入一个库,这里以 GoogleTest 库为例:

cmake_minimum_required(VERSION 3.14)
project(my_project)# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)include(FetchContent)
FetchContent_Declare(googletestURL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# 对于Windows:防止重写父项目的编译器/链接器设置
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
  1. include(FetchContent) :表示引入 FetchContent
  2. FetchContent_Declare(第三方库) :获取第三方库,可以是一个 URL 或者一个 Git 仓库。
  3. FetchContent_MakeAvailable(第三方库) :将这个第三方库引入项目。
  4. target_link_libraries(主项目 PRIVATE 子模块::子模块) :链接这个第三方库。

安装与测试

安装

示例的目录结构如下:

.
├── CMakeLists.txt
├── config.h.in
├── License.txt
├── main.cc
└── math├── CMakeLists.txt├── MathFunctions.cc└── MathFunctions.h

math 目录下的 CMakeLists.txt

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${DIR_LIB_SRCS})# 指定 MathFunctions 库的安装路径
install (TARGETS MathFunctions DESTINATION lib)
install (FILES MathFunctions.h DESTINATION include)

通过 install 命令:

  • 静态库 MathFunctions 安装到 /usr/local/lib 目录下
  • 头文件 MathFunctions.h 安装到 /usr/local/include 目录下。

根目录 下的 CMakeLists.txt 中的 install 内容:

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"DESTINATION include)
  • 可执行程序 Demo 安装到了 /usr/local/lib 目录下;
  • 头文件 config.h 安装到 /usr/local/lib 目录下。

PS:/usr/local/ 是默认安装的根目录,可以通过修改 CMAKE_INSTALL_PREFIX 变量来指定文件安装文件的根目录


测试

CMake 提供了一个名为 CTest 的测试工具。它通过 add_test 命令来进行相关测试,项目根目录的 CMakeLists.txt 文件中的 add_test 命令内容如下:

# 启用测试
enable_testing()# 测试程序是否成功运行
add_test (test_run Demo 5 2)# 测试帮助信息是否可以正常提示
add_test (test_usage Demo)
set_tests_properties (test_usagePROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent")# 测试 5 的平方
# add_test (test_5_2 Demo 5 2)# set_tests_properties (test_5_2
#  PROPERTIES PASS_REGULAR_EXPRESSION "is 25")# 测试 10 的 5 次方
# add_test (test_10_5 Demo 10 5)# set_tests_properties (test_10_5
#  PROPERTIES PASS_REGULAR_EXPRESSION "is 100000")# 测试 2 的 10 次方
# add_test (test_2_10 Demo 2 10)# set_tests_properties (test_2_10
#  PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")# 如果觉得上述过程过于复杂
# 也可以定义一个宏,用来简化测试工作
macro (do_test arg1 arg2 result)add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})set_tests_properties (test_${arg1}_${arg2}PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)# 利用 do_test 宏,测试一系列数据
do_test (5 2 "is 25")
do_test (10 5 "is 100000")
do_test (2 10 "is 1024")
  • enable_testing:用于启动测试。
  • add_test:用于添加测试
    • 第一个参数为测试名;
    • 第二个参数为可执行程序;
    • 剩下的为可执行程序的参数。
  • set_tests_properties:测试的提示信息。
  • PASS_REGULAR_EXPRESSION :测试属性(正则表达式)来验证输出中是否包含了特定的字符串。这里验证开方是否正确并且在计算错误时输出输出对应信息。
  • macro:宏,用于编写一个重复性操作来简化测试用例的编写。
  • do_test:编写的测试宏。

生成安装包

如果想要生成安装包,则需要使用 CMake 提供的打包工具 CPack。此时需要在 CMakeLists.txt 中添加以下内容:

# 构建一个 CPack 安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE"${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
include (CPack)
  • include (InstallRequiredSystemLibraries):导入 InstallRequiredSystemLibraries 模块。
  • 设置一些 CPack 相关变量。
  • include (CPack):导入 CPack 模块。

接着执行 cmakemake 构建工程,此时再执行 cpack 命令即可生成安装包:

#生成二进制安装包
cpack -C CPackConfig.cmake#生成源码安装包
cpack -C CPackSourceConfig.cmake

当命令执行成功后,就会在当前目录下生成 *.sh*.tar.gz*.tar.Z 这三个格式的安装包。

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

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

相关文章

五轴编程_沙井万丰数控数控编程五轴编程那个软件好用

沙井万丰数控数控编程五轴编程那个软件好用设计需要掌握很高很全面的知识和技能&#xff0c;模具做的好&#xff0c;产品质量好&#xff0c;模具结构合理&#xff0c;生产效率高&#xff0c;工厂效益好。正因如此&#xff0c;模具技术工在外打工的工资都非常的高。少则每月几千…

Linux学习:第二章-Linux安装

一虚拟机使用 VMware主要特点&#xff1a; 1、不需要分区或重新开机就能在同一台PC上使用两种以上的操作系统 2、本机系统可以与虚拟机系统网络通信 3、可以设定并且随时修改虚拟机操作系统的硬件环境 二安装方式 图形安装&#xff1a;直接回车 字符安装&#xff1a;linux tex…

keil3如何放大字体_国潮海报不会做?送你国风字体+图案笔刷+PSD素材+包装样机...

有很多朋友都问带鱼&#xff0c;国潮风的海报到底应该怎么做呢&#xff1f;首先你要知道什么是国潮风&#xff1a;国潮风就是现代文化和古代文化的碰撞&#xff0c;是年轻人的态度&#xff01;那么应该如何构图如何设计呢&#xff1f;如何配色如何搭配字体呢&#xff1f;这些方…

Google 开源项目风格指南学习笔记——C++篇

文章目录前言0. 缩写名词解释1. 头文件1.1. Self-contained 头文件1.2. 头文件保护1.3. 前置声明1.4 内联函数1.5. #include 的路径及顺序2. 作用域2.1. 命名空间2.2. 非成员函数、静态成员函数和全局函数2.3. 局部变量2.4. 静态和全局变量3. 类3.1. 构造函数的职责3.2. 隐式类…

hiveserver2启动不起来_给爱车配个充电宝,70迈汽车应急启动电源,让你远离搭电小广告...

说到汽车应急启动其实我有切身的痛&#xff0c;在哈尔滨零下35的严冬&#xff0c;晚上带着女神吃完饭&#xff0c;高高兴兴地吃完以后一上车&#xff0c;发现电瓶被冻没电了&#xff0c;天知道当时有多尴尬。马上叫了保险公司过来给搭电&#xff0c;结果在饭店从晚上8点一直等到…

Windows 下 VS 配置 OpenGL 环境

文章目录前言获取 GLFW打开 VS前言 感谢B站同学搬运YouTube上的教学视频。 获取 GLFW 从官网上下载GLFW macOS下64位二进制文件 打开 VS 新建解决方案 OpenGL test&#xff0c;并在解决方案中新建文件夹 Dependencies&#xff1a; 从下载好的 glfw 文件夹中找到最新版链接…

ubuntu 网卡双网口 配置_无线网卡m2 ngff keya keye、minipcie接口改转多口有线网卡实现软路...

小型主板及笔记本中的无线网卡m2ngffkeyakeye接口&#xff08;CNVI除外&#xff09;通过m2ngffkeyae转接pcie1x转接板&#xff0c;或者无线网卡的minipcie接口&#xff0c;通过minipcie转接pcie1x转接板可以改装有线网卡板卡&#xff0c;来实现软路由功能。m2ngffkeyae转接pcie…

OpenGL | 通过绘制一个三角形来入门 OpenGL 图形渲染管线

文章目录前言什么是 OpenGl &#xff1f;回顾openGL 的 Object显存结构工作阶段通过顶点缓冲对象将顶点数据初始化至缓冲中标准化设备坐标顶点缓冲对象 VBOglGenBuffersglBindBufferglBufferData建立了一个顶点和一个片段着色器着色器是什么&#xff1f;为什么需要使用着色器&a…

javascript特效_如何在网页添加鼠标点击特效

经常有同学问我怎么做到的&#xff0c;本论坛属于DZ当然用的是插件啦。偶然在网上找到一个关于wordpress的特效代码&#xff0c;分享给大家。WordPress 添加鼠标点击特效实际上这种教程在网上搜索一下有一大堆&#xff0c;已经是各大博主玩烂的东西了。不过既然给自己的博客加上…

android nio debug模式正常 release包crash_Flutter包大小治理上的探索与实践

Flutter作为一种全新的响应式、跨平台、高性能的移动开发框架&#xff0c;在性能、稳定性和多端体验一致上都有着较好的表现&#xff0c;自开源以来&#xff0c;已经受到越来越多开发者的喜爱。但是&#xff0c;Flutter的引入往往带来包体积的增大&#xff0c;给很多研发团队带…

sam格式的结构和意义_各种格式的练字本,对写字真有帮助吗

图片来源于笔势通各种格式的练字本现在越来越多&#xff0c;目的主要是便于学生把握好笔画的位置和布局&#xff0c;从而把整个字的结构处理好&#xff0c;常见的有米字格&#xff0c;回宫格等。这些练字本对于初学者来说肯定是有帮助的&#xff0c;特别是低年级学生。当然随着…

硬件结构图_那曲地表水电子除垢仪结构图

那曲地表水电子除垢仪结构图水处理设备也应断电停止使用&#xff0c;系统长期停止运行或季节性停止运行&#xff0c;在系统停止运行前&#xff0c;在水中投加适量缓蚀剂&#xff0c;并采取满水湿保护的措施&#xff0c;以减小腐蚀&#xff0c;保护系统。开启进水阀检查无误后电…

双屏怎么快速切换鼠标_在笔记本上实现双屏设计,怎么做到的?

如果给你的笔记本电脑安装两个屏幕&#xff0c;你会用来干什么&#xff1f;是上班时间主屏幕放着PPT&#xff0c;副屏幕偷摸玩游戏&#xff1b;还是主屏幕玩游戏&#xff0c;副屏幕刷刷B站视频&#xff1b;亦或是主屏幕P着图&#xff0c;副屏幕在网上找找能用的素材&#xff1f…

信元模式mpls 避免环路_【基础】交换机堆叠模式

堆叠是指将一台以上的交换机组合起来共同工作&#xff0c;以便在有限的空间内提供尽可能多的端口。多台交换机经过堆叠形成一个堆叠单元。可堆叠的交换机性能指标中有一个"最大可堆叠数"的参数&#xff0c;它是指一个堆叠单元中所能堆叠的最大交换机数&#xff0c;代…

为什么叫日上_古雷150万吨乙烯,为啥叫芒果项目?

古雷150万吨乙烯&#xff0c;为啥叫芒果项目&#xff1f;福建石油化工集团有限责任公司9月1日在福州举行的一场新闻通气会上透露&#xff0c;石化基地引进世界化工巨头——沙特基础工业公司(简称SABIC)&#xff0c;合资合作共建中沙古雷乙烯项目。中沙古雷乙烯项目将在福建古雷…

Linux学习:第四章-vi编辑器

一vi编辑器简介vim全屏幕纯文本编辑器别名alias命令‘命令别名’ aliasvi’vim’ alias lsls --colorttyls正常显示颜色 alias lsls --colornever 环境变量配置文件/root/.bashrc 二vim使用 1vi模式 vi文件名 命令模式 输入模式 末行模式 命令----》输入a&#xff1a;追加i&…

gradient设置上下渐变_PaintCode Mac使用教程:如何使用渐变色

Mac平台上一款强大的iOS矢量绘图编程软件PaintCode Mac&#xff0c;无论您是程序员还是设计师&#xff0c;paintcode3能够让你像在PS中画图一样绘制各种UI图形&#xff0c;而且paintcode3会自动帮你生成针对MacOS X或iOS平台Objective-C或C#代码&#xff0c;能够节约大量的编程…

opencv计算图像亮度调节_OpenCV教程创建Trackbar图像对比度、亮度值调整

这篇文章中我们一起学习了如何在OpenCV中用createTrackbar函数创建和使用轨迹条&#xff0c;以及图像对比度、亮度值的动态调整。文章首先详细讲解了OpenCV2.0中的新版创建轨迹条的函数createTrackbar&#xff0c;并给上一个详细注释的示例。然后讲解图像的对比度、亮度值调整的…

find linux 目录深度_浪里淘沙,详解Linux系统中Find命令的实用技巧

知了小巷&#xff1a;浪里淘沙&#xff0c;详解Linux系统中Find命令的实用技巧。啊哈&#xff0c;找到了&#xff01;当我们需要在Linux系统上定位某个文件或目录时&#xff0c;find命令通常是必备之选。它使用起来非常简单&#xff0c;但有许多不同的可选项&#xff0c;允许我…

剑指offer之从上到下打印二叉树

从上到下打印出二叉树的每个节点&#xff0c;同一层的节点按照从左到右的顺序打印。 例如: 给定二叉树: [3,9,20,null,null,15,7], 返回&#xff1a; [3,9,20,15,7] 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode-cn.com/problem…