cmake使用教程,cmake快速入门,超详细的cmake入门教程

cmake使用教程,cmake快速入门,超详细的cmake入门教程

本文主要介绍cmake超详细的介绍教程,有需要的朋友可以参考一下。

什么是cmake

你可能听说过几个Make工具,比如GNU Make、QT qmake、微软MSnmake、BSD Make(pmake)、Makepp等等。这些Make工具遵循不同的规范和标准,它们执行的Makefile的格式也大相径庭。这就带来了一个严重的问题:软件要跨平台,就必须在不同的平台上编译。如果您使用上面的Make工具,您必须为每个标准编写一个Makefile,这将是一项令人抓狂的工作。

CMake CMake图1 CMake是针对上述问题设计的工具:它首先允许开发人员编写一个平台无关的CMakeList.txt文件来定制整个编译过程,然后根据目标用户的平台进一步生成所需的本地化Makefile和工程文件,如Unix的Makefile或Windows的Visual Studio项目。从而实现“写一次,到处跑”。很明显,CMake是比上面提到的Make更高级的编译器配置工具。使用CMake作为项目架构系统的知名开源项目有VTK、ITK、KDE、OpenCV、OSG等。

linux平台下使用CMake生成Makefile并编译的过程如下:

编写CMake配置文件CMakeLists.txt.

执行命令cmake PATH或ccmake PATH来生成Makefile。其中PATH是CMakeLists.txt所在的目录。(ccmake和cmake的区别在于前者提供了交互界面)

用make命令编译。

入门案例:单个源文件

本节对应的源代码目录:Demo1。

对于简单的项目,只需编写几行代码。举个例子,假设我们的项目现在只有一个源文件main.cc,这个程序的目的是计算一个数的指数幂。

#包含stdio.h

#包含stdlib.h

/**

*幂——计算数的幂。

* @param base:基本值。

* @param指数:指数值。

*

* @return base的幂指数。

*/

双幂(双基数,整数指数)

{

int result=base

int I;

if(指数==0) {

返回1;

}

for(I=1;I指数;i){

结果=结果*基数;

}

返回结果;

}

int main(int argc,char *argv[])

{

if (argc 3){

printf('用法:%s基本指数\n ',argv[0]);

返回1;

}

双基=atof(argv[1]);

int指数=atoi(argv[2]);

double result=power(底数,指数);

printf('%g ^ %d是%g\n ',底数,指数,结果);

返回0;

}

编写 CMakeLists.txt

首先,编写CMakeLists.txt文件,并将其保存在与main.cc源文件相同的目录中:

# CMake最低版本号要求

cmake_minimum_required(版本2.8)

#项目信息

项目(演示1)

#指定构建目标

add_executable(Demo main.cc)

CMakeLists.txt语法简单,由命令、注释和空格组成,其中命令不区分大小写。符号#后面的内容被视为注释。命令由命令名、括号和参数组成,用空格分隔。

对于上面的CMakeLists.txt文件,几个命令依次出现:

Cmake_minimum_required:指定运行此配置文件所需的Cmake的最低版本;

项目:参数值为Demo1,表示项目名称为Demo1。

Add_executable:将名为main.cc的源文件编译成名为Demo的可执行文件。

编译项目

之后,执行cmake。在当前目录下获取Makefile,然后用make命令编译它,得到Demo1可执行文件。

[ehome@xman Demo1]$ cmake。

-C编译器标识是GNU 4.8.2

CXX编译器标识是GNU 4.8.2

-检查正在工作的C编译器:/usr/sbin/cc

-检查工作的C编译器:/usr/sbin/cc - works

-检测C编译器ABI信息

-检测C编译器ABI信息-完成

-检查正在工作的CXX编译器:/usr/sbin/c

-检查正在工作的CXX编译器:/usr/sbin/c - works

-检测CXX编译器ABI信息

-检测CXX编译器ABI信息-完成

-配置完成

-生成完成

-构建文件已写入:/home/ehome/Documents/programming/C/power/demo 1

[ehome@xman Demo1]$ make

扫描目标演示的依赖关系

[100%]构建C对象CMakeFiles/Demo.dir/main.cc.o

链接C可执行文件演示

[100%]构建目标演示

[ehome@xman Demo1]$。/演示5 4

5 ^ 4是625

[ehome@xman Demo1]$。/演示7 3

7 ^ 3是343

[ehome@xman Demo1]$。/演示2 10

2 ^ 10是1024

多个源文件

同一个目录,多个源文件

本节对应的源代码目录:Demo2。

上面的例子只有一个源文件。现在,如果将幂函数单独写入名为MathFunctions.c的源文件中,该项目将变成以下形式:/Demo2

|

- main.cc

|

- MathFunctions.cc

|

-数学函数. h

此时,CMakeLists.txt可以更改为以下形式:

# CMake最低版本号要求

cmake_minimum_required(版本2.8)

#项目信息

项目(演示2)

#指定构建目标

add _ executable(Demo main . cc math functions . cc)

唯一的变化是在add_executable命令中添加了一个MathFunctions.cc源文件。这样写当然没有问题,但是如果源文件很多,要把所有源文件的名字都加进去,那就很烦人了。更方便的方法是使用aux_source_directory命令,该命令将查找指定目录中的所有源文件,然后将结果保存在指定的变量名中。其语法如下:

辅助源目录(目录变量)

因此,CMakeLists.txt可以修改如下:

# CMake最低版本号要求

cmake_minimum_required(版本2.8)

#项目信息

项目(演示2)

#在当前目录中查找所有源文件

#并将该名称保存到DIR_SRCS变量中

辅助源目录(。SRCS方向)

#指定构建目标

添加可执行文件(演示{ DIR _ SRCS })

这样,CMake会将当前目录下所有源文件的文件名赋给变量DIR_SRCS,然后指示需要将变量DIR_SRCS中的源文件编译成一个名为Demo的可执行文件。

多个目录,多个源文件

本节对应的源代码目录:Demo3。

现在将mathFunctions.h和MathFunctions.cc文件移动到Math目录中。/演示3

|

- main.cc

|

-数学/

|

- MathFunctions.cc

|

-数学函数. h

在这种情况下,需要在项目根目录Demo3和math目录下分别写一个CMakeLists.txt文件。为了方便,我们可以把math目录下的文件编译成一个静态库,然后由main函数调用。

根目录中的CMakeLists.txt:

# CMake最低版本号要求

cmake_minimum_required(版本2.8)

#项目信息

项目(演示3)

#在当前目录中查找所有源文件

#并将该名称保存到DIR_SRCS变量中

辅助源目录(。SRCS方向)

#添加数学子目录

add _子目录(数学)

#指定构建目标

add_executable(Demo main.cc)

#添加链接库

目标_链接_库(演示数学函数)

这个文件中添加了以下内容:第3行,使用add_subdirectory命令表示这个项目包含一个子目录math,这样math目录下的CMakeLists.txt文件和源代码也会被处理。第6行,使用命令target_link_libraries表示可执行文件main需要连接一个名为MathFunctions的链接库。

子目录中的CMakeLists.txt:

#在当前目录中查找所有源文件

#并将名称保存到DIR_LIB_SRCS变量中

辅助源目录(。自由SRCS)

#生成链接库

add_library(数学函数$ {目录_库_SRCS})

在这个文件中,使用add_library命令将src目录中的源文件编译成静态链接库。

自定义编译选项

本节对应的源代码目录:Demo4。

CMake允许为项目添加编译选项,以便根据用户的环境和需求选择最合适的编译方案。

例如,可以将MathFunctiONs库设置为可选库。如果此选项打开,您可以使用此库定义的数学函数来执行操作。否则调用标准库中的数学函数库。

修改CMakeLists文件

我们要做的第一步是在顶层的CMakeLists.txt文件中添加这个选项:

# CMake最低版本号要求

cmake_minimum_required(版本2.8)

#项目信息

项目(演示4)

#添加一个配置头文件,用于处理CMake的源代码设置。

配置文件(

$ { PROJECT _ SOURCE _ DIR }/config . h . in '

${PROJECT_BINARY_DIR}/config.h '

)

#你想使用你自己的数学函数库吗?

选项(使用_我的数学

使用提供的数学实现'开)

#加入MathFunctions库?

if(使用_我的数学)

include _ directory(' $ { PROJECT _ SOURCE _ DIR }/math ')

add _子目录(数学)

set (EXTRA_LIBS ${EXTRA_LIBS}数学函数)

endif (USE_MYMATH)

#在当前目录中查找所有源文件

#并将该名称保存到DIR_SRCS变量中

辅助源目录(。SRCS方向)

#指定构建目标

添加可执行文件(演示{ DIR _ SRCS })

目标_链接_库(演示$ {额外_LIBS})

其中包括:

第7行的configure_file命令用于添加一个配置头文件config.h。该文件由CMake从config.h生成。通过这种机制,可以通过预定义的一些参数和变量来控制代码的生成。

第13行的optiON命令添加了一个USE_MYMATH选项,默认值是ON。

第17行根据USE_MYMATH变量的值决定是否使用自己编写的MathFunctions库。

修改 main.cc 文件

然后修改main.cc文件,根据USE_MYMATH的预定义值决定是调用标准库还是MathFunctions库:

#包括

#包括

#include 'config.h '

#ifdef USE_MYMATH

#include 'math/MathFunctions.h '

#否则

#包括

#endif

int main(int argc,char *argv[])

{

if (argc 3){

printf('用法:%s基本指数\n ',argv[0]);

返回1;

}

双基=atof(argv[1]);

int指数=atoi(argv[2]);

#ifdef USE_MYMATH

printf(‘现在我们用自己的数学库。\ n’);

double result=power(底数,指数);

#否则

printf('现在我们使用标准库。\ n’);

double result=power(底数,指数);

#endif

printf('%g ^ %d是%g\n ',底数,指数,结果);

返回0;

}

编写 config.h.in 文件

上面的程序在第2行值得注意,这里引用了一个config.h文件,它预定义了USE_MYMATH的值。但是我们不直接写这个文件。为了从CMakeLists.txt导入配置,我们编写一个config.h.in文件,其内容如下:

#cmakedefine USE_MYMATH

这样,CMake将根据CMakeLists配置文件中的设置自动生成config.h文件。

编译项目

现在编译这个项目。为了交互式地选择这个变量的值,您可以使用ccmake命令(或者cmake -i命令,它将提供一个对话式交互式配置界面)。)

可以找到刚刚定义的USE_MYMATH选项。按键盘箭头键在不同的选项窗口之间跳转,按enter键修改该选项。修改后可以按C选项完成配置,然后按G键确认生成Makefile。CC的其他操作可以参考窗口底部给出的指令提示。

我们可以尝试分别将USE_MYMATH设置为ON和OFF所获得的结果:

USE_MYMATH已打开。

运行结果:

[ehome@xman Demo4]$。/演示

现在我们使用自己的数学函数库。

7 ^ 3=343.000000

10 ^ 5=100000.000000

2 ^ 10=1024.000000

此时,config.h的内容是:

#define USE_MYMATH

USE_MYMATH已关闭。

运行结果:

[ehome@xman Demo4]$。/演示

现在我们使用标准库。

7 ^ 3=343.000000

10 ^ 5=100000.000000

2 ^ 10=1024.000000

此时,config.h的内容是:

/* #undef USE_MYMATH */

下面是其他网友的补充

用cmake编译,组织c工程

这个博客是我对cmake使用经验的总结,它还是很简单的。如有错误或更好的方案,请指正~

该方法统一在构建目录中执行:

$: cmake.

$:制造

我觉得养成外部编译是个好习惯。

例一

目录结构是:

lzj @ lzj:~/C-Plus-Plus/makefile _ cmake/cmake _ 1 $ tree。

大厦

CMakeLists.txt

src

你好

hello.cc

hello.h

缅因河

世界

世界. cc

世界

src目录中不同的属性类在不同的目录中维护。

main.cpp中使用hello.h和world.h

CMakeLists.txt是:

cmake _ minimum _ required(3.0版)

项目(测试_1)

辅助源目录($ { CMAKE _ CURRENT _ LIST _ DIR }/src/HELLO SOURCE _ HELLO)

辅助源目录($ { CMAKE _ CURRENT _ LIST _ DIR }/src/WORLD SOURCE _ WORLD)

add _ definitions('-g-Wall-STD=c11 ')

add_executable(主

$ { CMAKE _ CURRENT _ LIST _ DIR }/src/main。卡片打印处理机(Card Print Processor的缩写)

${SOURCE_HELLO}

${SOURCE_WORLD})

例二

目录结构为:

lzj @ lzj:~/C-Plus-Plus/makefile _ cmake/cmake _ 2 $ tree。

大厦

CMakeLists.txt

包括

person.h

src

缅因河

人。复写的副本

包括目录下统一包含头文件和宏定义之类,源文件放在科学研究委员会目录下维护

人类是一个简单的空类,拥有一个私有成员变量瓦尔,一个公有成员函数来打印该变量,在主页面中调用

CMakeLists.txt为:

cmake _ minimum _ required(3.0版)

项目(测试2)

包含目录($ {项目源目录}/包含)

add _ definitions('-g-Wall-STD=c11 ')

add_executable(主

$ { PROJECT _ SOURCE _ DIR }/src/main。CPP #这个路径看这个主页面位于哪里了

$ { PROJECT _ SOURCE _ DIR }/src/person。抄送)

例三

目录结构为:

lzj @ lzj:~/C-Plus-Plus/makefile _ cmake/cmake _ 3 $ tree。

大厦

CMakeLists.txt

缅因河

src

CMakeLists.txt

hello.cc

你好

世界。复写的副本

世界

将编写的代码编译为库,在主页面中使用,编译主页面时链接该库

顶层目录中CMakeLists.txt为:

cmake _ minimum _ required(3.0版)

项目(测试_3)

添加子目录(src)

add _ definitions('-g-Wall-STD=c11 ')

add_executable(main main.cpp)

目标_链接_库(主测试3) #自己的库名为测试3

子目录科学研究委员会中的CMakeLists.txt为:

辅助源目录(。自由SRCS)

添加库(测试3 $ {目录库SRCS})

当然如果科学研究委员会目录下为多文件时,每个目录下都要添加该语句的CMakeLists.txt

源代码

这篇文章就介绍到这了,希望大家以后多多支持我们。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: