CMake学习笔记(一)——CMake官网教程
CMake学习笔记(一)——CMake官网教程
前言:
经历了一星期痛苦的交叉编译,笔者深刻认知到Linux下make的重要性。所以准备放缓两三天自己的工作进度,并学习一下CMake与Makefile。毕竟就像陈浩大神说的那样:会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
给自己设置的第一课,就是先学习一下CMake官网提供的入门教程。
CMake官网教程地址:https://cmake.org/cmake-tutorial/
一. 基本开始
1. 构建简单工程
最基础的工程都是由源文件构建生成的。此处我们构建一个最简单的工程,其CMakeLists.txt文件只需要两三行,我们就用它来开始我们的教程。
CMakeLists.txt如下:
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)
需要注意的是,在这个例程中的CMakeLists.txt文件中,使用的是小写字符。在CMake中,大小写、甚至大小写混合的命令都是被支持的。
源代码文件tutorial.cxx将完成计算一个数字的平方根的功能,且第一个版本十分简单,代码如下:
// tutorial.cxx
// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{if (argc < 2){fprintf(stdout,"Usage: %s number\n",argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout,"The square root of %g is %g\n",inputValue, outputValue);return 0;
}
2. 添加版本号并配置头文件
我们要假的第一个特征,是给我们的可执行文件和工程提供一个版本号。当你可以独自在源代码中做到这些,那么在CMakeLists.txt中写入版本号可以提供更高的灵活性。
添加版本号,我们可以将CMakeLists.txt修改如下:
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)# configure a header file to pass some of the CMake settings
# to the source code
configure_file ("${PROJECT_SOURCE_DIR}/TutorialConfig.h.in""${PROJECT_BINARY_DIR}/TutorialConfig.h")# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")# add the executable
add_executable(Tutorial tutorial.cxx)
既然配置文件将被写入二进制树结构,我们就必须将配置文件的地址添加到路径列表中,这样才可以找到包含文件。
接下来我们在树中创建一个TutorialConfig.h.in文件,内容如下:
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
这样,当CMake配置头文件时,@Tutorial_VERSION_MAJOR@
与@Tutorial_VERSION_MINOR@
将会被CMakeLists.txt文件中的值代替。
接下来,我们修改tutorial.cxx,将头文件包含在内,并使用先前加入的版本号。
最终的源代码如下所示:
// tutorial.cxx
// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"int main (int argc, char *argv[])
{if (argc < 2){fprintf(stdout,"%s Version %d.%d\n",argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout,"Usage: %s number\n",argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout,"The square root of %g is %g\n",inputValue, outputValue);return 0;
}
主要的改变,在于将头文件TutorialConfig.h包含进去,并将版本号作为使用信息的一部分打印了出去。
二. 添加库
这一步骤中,我们将在我们的工程中添加一个库。
这个库包含了我们计算平方根的实现。执行文件可以使用这个库而代替编译器自己提供的标准平方根计算方法。在这个教程中,我们将该库设置为一个子库,并命名为MathFunctions。在CMakeLists.txt中实现如下:
add_library(MathFunctions mysqrt.cxx)
源文件mysqrt.cxx中有一个名为mysqrt的函数,这个函数提供了相比于编译器版本平方根函数的简化版本。为了使用新库,我们在顶层根目录中的CMakeLists.txt调用add_subdirectory
,如此一来该库便建成了。
我们也可以添加另外一个包含路径,这样的话,头文件MathFunctions/MathFunctions.h
便可以被函数原型找到。
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions) # add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)
现在,我们来考虑一下是否使MathFunctions库可用。在大型库,或者依赖于第三方代码的库中,很需要这种功能。
第一步,在顶层根目录的CMakeLists.txt中添加选项:
# should we use our own math functions?
option (USE_MYMATH "Use tutorial provided math implementation" ON)
在CMake-GUI中,该值将以默认的ON值显示,用户可以随意更改。该值将存储在缓存文件中,用户不需要每次运行cmake指令时都对其进行一次设定。
# add the MathFunctions library?
#
if (USE_MYMATH)include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")add_subdirectory (MathFunctions)set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial ${EXTRA_LIBS})
注:
1、代码中的USE_MYMATH会在后面定义;
2、如果MathFunctions需要被编译与使用,那么USE_MYMATH就需要被定义;
3、变量(该例程中的EXTRA_LIBS)的使用,可以用来收集任意可选的库,并在后面的代码中慢慢被链接到可执行文件;在维护大型工程时,通常有很多可选部分,为了保持工程的清晰,这是一种普遍用法。
// tutorial.cxx
// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endifint main (int argc, char *argv[])
{if (argc < 2){fprintf(stdout,"%s Version %d.%d\n", argv[0],Tutorial_VERSION_MAJOR,Tutorial_VERSION_MINOR);fprintf(stdout,"Usage: %s number\n",argv[0]);return 1;}double inputValue = atof(argv[1]);#ifdef USE_MYMATHdouble outputValue = mysqrt(inputValue);
#elsedouble outputValue = sqrt(inputValue);
#endiffprintf(stdout,"The square root of %g is %g\n",inputValue, outputValue);return 0;
}
上面的源码中我们也使用到了USE_MYMATH。我们在之前的TutorialConfig.h.in配置文件中添加下面的一行:
#cmakedefine USE_MYMATH
三. 安装与测试
这一步骤中,我们将向我们的工程中添加安装规则和测试支持。
安装规则很简单直接。对于MathFunctions,我们可以在MathFuncitions的CMakeLists.txt中添加两行代码,即可安装库与头文件。
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)
另外在顶层根目录的CMakeLists.txt中,也需要加入几行代码,用来安装可执行文件与头文件:
# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)
到了这一步,你应该已经可以构建其自己的教程了。这时候输入make install,工程将安装合适的头文件、库文件和可执行文件。其中,CMake变量CMAKE_INSTALL_PREFIX被用来定义安装文件的根目录。
添加测试也是一个简单直接的操作。在顶层根目录中的CMakeLists.txt中,我们可以添加几行简单测试代码来衡量应用是否正确。
include(CTest)# does the application run
add_test (TutorialRuns Tutorial 25)# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")
构建之后,运行ctest命令行可以运行这些测试。
PS:官网教程中还有剩余几步,但笔者感觉好像没有什么用…… 所以就写到这里好了。
注:略去的几步:
4、添加系统内省(Adding System Introspection)
5、添加已生成文件和生成器(Adding a Generated File and Generator)
6、构建一个安装程序(Building an Installer)
CMake学习笔记(一)——CMake官网教程相关推荐
- Python+Selenium学习笔记5 - python官网的tutorial - 交互模式下的操作
这篇笔记主要是从Python官网的Tutorial上截取下来,再加上个人理解 1. 在交互模式下,下划线'_'还可以表示上一步的计算结果 2.引号转义问题. 从下图总结的规律是,字符串里的引号如果和引 ...
- cmake学习笔记(2)--CMake常用的预定义变量
cmake常用的预定义变量不多,根据经验掌握如下几个就基本上够用了: PROJECT_NAME : 通过 project() 指定项目名称 PROJECT_SOURCE_DIR : 工程的根目录 PR ...
- Docker 官网教程实践 自定义 bridge 网络
前言 这篇笔记是 docker 官网教程 自定义 bridge 网络的实践. 用户自定义 bridge 网络是在生产环境中推荐到最佳方式,因此这篇教程要特别注意. 这个教程中,启动了2个 alpine ...
- Spring Cloud学习笔记—网关Spring Cloud Gateway官网教程实操练习
Spring Cloud学习笔记-网关Spring Cloud Gateway官网教程实操练习 1.Spring Cloud Gateway介绍 2.在Spring Tool Suite4或者IDEA ...
- cmake 学习笔记(三) (转)
接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我 ...
- CMake 学习笔记 02 - 更复杂的项目
CMake 学习笔记 02 - 更复杂的项目 源代码见 https://github.com/fengyc/cmake-tutorial 源代码目录组织 一般的项目,会划分为多个子目录,每个子目录中包 ...
- cmake学习笔记(七)编写自己的xxxConfig.cmake
cmake学习笔记(七)编写自己的xxxConfig.cmake 1. onnxruntimeConfig.cmake 2. 进阶版onnxruntimeConfig.cmake 1. onnxrun ...
- cmake学习笔记(五)
cmake学习笔记(五) 添加系统检测 检测代码环境中是否存在某些库文件,在MathFunctions/CMakeLisits.txt添加如下代码: include(CheckSymbolExists ...
- 新学Python之学习官网教程序言
大家好,我是 herosunly.985 院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用.曾获得阿里云天池安全恶意程序检测第一名,科大讯飞恶意软件分类挑战赛第三名,CCF 恶意软 ...
最新文章
- 引用的定义、使用及其和指针的区别与联系
- ifelse语句是否必须以else结尾?
- java sql 登录失败_java – 接收连接到SQL Server 2008的SQLException“用户登录失败”
- 常规dll 的接口函数定义+客户端程序接口函数导入
- 关于范围for语句的使用
- React中useEffect使用
- 电脑硬件知识大扫盲:主板知识大全
- 丁向荣单片机pdf_《单片微机原理与接口技术--基于STC15系列单片机》,丁向荣主编.doc...
- R语言大数据分析之新闻文本数据分析
- 通过这18000个Python项目对比,并从中精选出 45 个值得学习的!
- C A+B for Input-Output Practice (II) SDUT
- Entegris EUV 1010光罩盒展现极低的缺陷率,已获ASML认证
- 蚂蚁金服宫孙:guava探究系列之优雅校验数据
- 市场营销问题 (二):产品属性的效用函数
- 利用python画空间分布图
- 敏涵控股集团董事长刘敏:让世界了解敏涵 让敏涵走向世界
- CATIA CAA二次开发专题(四)------创建自己的Addin
- 【最详细,最新】电脑网站接入支付宝接口
- iMeta | 华南农大陈程杰/夏瑞等发布TBtools构造Circos图的简单方法
- 卖座网一处SQL注射(Http Referer sqlinjection)