前言: 自己在使用cmake进行编译工程的时候不太了解cmake的基本使用方法,有时候出现找不到第三方库的问题也不知如何排查,因此相对cmake有个稍微系统的认识,希望能用这个强大的工具来更好的为自己的工程服务,因此总结为了几篇博客,主要参考的是官网的Tutorial,加入了自己的认识,另外,其实cmake本质上是一个工具,工具的作用就是用来帮助我们更好的构建项目的,所以对于工具能够满足使用要求就好,不必细枝末节的完全掌握,如有错误请斧正.
测试cmake版本:3.20.4
测试平台:ubuntu16.04
Tutorial源代码:https://github.com/FreddyName/cmake_tutorialshttps://github.com/FreddyName/cmake_tutorials
系列博客目录:
cmake学习1: 基本的CMakeLists.txt的编写https://blog.csdn.net/Heart_M/article/details/120626697
cmake学习2: 如何将源代码编译成库并使用https://blog.csdn.net/Heart_M/article/details/120632708
cmake学习3: 如何安装自己的工程在本地https://blog.csdn.net/Heart_M/article/details/120640741
cmake学习4: 如何将自己的工程打包给别人https://blog.csdn.net/Heart_M/article/details/120641933
cmake学习5: 如何将自己的库作为第三方库给别人使用https://blog.csdn.net/Heart_M/article/details/120643023
最基本的项目就是通过一个.cpp源文件构建而成的可执行文件,对于此简单项目,CMakeLists.txt只需要三行内容(CMakeLists.txt与tutorial.cxx在同级目录):
#required cmake minimum version
cmake_minimum_required(VERSION 3.10)
# set the project name
project(Tutorial)
# add the executable
add_executable(Tutorial tutorial.cxx)
注意: cmake对于大写或者小写或者大小写混合都是兼容的.
上面的三行命令分别制定了cmake的最小版本需求, 将project命名为Tutorial,将tutorial.cxx编译为名为Tutorial的可执行文件(tutorial.cxx在这里实现的是对一个符合条件的数进行平方根运算,只依赖于c++的基本库,因此无需链接其他库)
tutorial.cxx内容如下:
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// convert input to double
const double inputValue = atof(argv[1]);
// calculate square root
const double outputValue = sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
return 0;
}
在step1文件夹同级下构建build_Step1文件夹并编译:
mkdir build_Step1
cd build_Step1
cmake ../Step1
cmake --build .
然后在build_Step1文件夹中生成Tutorial可执行文件, 验证
接下来我们希望为我们的工程指定一个版本号,因为如果我们自己实现一个库的时候肯定是有版本的,比如说opencv 3.4.3版本等,我们是可以在源码中进行操作的,不过在CMakeLists.txt中操作更加的灵活. 这个主要涉及到如何将CMakeLists.txt中的版本信息传递到其他文件中,操作步骤如下:
在project(Tutorial)中指定版本号
project(Tutorial VERSION 1.0)
配置一个头文件将CMakeLists.txt中的版本号传到源代码: 新建一个TutorialConfig.h.in文件, 写入如下内容:
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
然后在CMakeLists.txt中配置:
configure_file(TutorialConfig.h.in TutorialConfig.h)
这里说明一下configure_file的作用:
configure_file,复制一份输入文件到输出文件,替换输入文件中被@VAR@或者${VAR}引用的变量值。也就是说,让普通文件,也能使用CMake中的变量
例如:我们在CMakeLists.txt中指定了project的版本号, 那么Tutorial_VERSION_MAJOR和Tutorial_VERSION_MINOR就是1和0,在生成的TutorialConfig.h文件中就变成了
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 0
然后在源码中就可以使用这两个变量的值了(前提是include TutorialConfig.h)生成的TutorialConfig.h文件就在build_Step1目录下
这个时候配置文件要被写入到二进制文件中,因此需要在CMakeLists.txt中包含这个路径:
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
这里说一下include_directories与target_include_directories的区别:
include_directories(x/y) 影响的是所有构建的target的路径范围, 使用这个命令指定,所有的target都包含了这个路径.
target_include_directories(t x/y)仅仅是影响t的路径范围,对于其他的target的include路径并不影响, 支持PRIVATE PUBLIC INTERFACE三个属性
然后就可以在源码中获得版本号了
#include <TutorialConfig.h>
if (argc < 2) {
// report version
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
如果使用c++11标准, 那么需要在CMakeLists.txt中显示指定
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)