CMake自动构建工程学习总结

       由于接手项目的测试例平台融合,而测试例平台是使用CMake来构建工程的,一开始工程可以生成,但是编译时出现各种头文件未包含的致命错误。当时心里很疑惑,明明可以直接通过头文件跳转至相应目的头文件,例如:include “time.h”,但编译就是出错,这是什么鬼,很是纳闷。最后,才发现原来CMakeLists.txt中没有包含某些文件的头文件,导致出现头文件未包含的致命错误。作为一个初级码农的我,CMake是什么?一问度娘,瞬间想get这项新技能。

       CMake可以生成一个本地构建环境,它将编译源代码,创建库,生成包装器并以任意组合构建可执行文件。那么,CMake有什么方便之处呢?如果目标平台是windows,它可以帮你自动构建出vs工程;如果是安卓,自动构建出eclipse工程,如果是IOS,自动构建出xcode工程。对于我这个初级码农而言,怎么学呢?果断各种问度娘,不过并没有找到比较有价值的学习资料,很多人都是贴出了CMake的源文件CMakeLists.txt,然后对文件中的每行都讲了下作用。看完这些,我依然不知道为什么要这么写,为什么这行要这样写,最终还是要自己动手实际操作一波,不断尝试。直接通过官网找到了详细的指导书,为了自己深入理解CMake,决定把每个步骤都操作一波。

       首先,第一步当然是下载CMake工具,路径:CMake工具下载 ,由于本人在windows下操作,因此下载工具包:cmake-3.15.0-rc1-win64-x64.msi,CMake工具示意图如图1所示。

                                   

                                                                                图1 CMake工具示意图

       工具下好之后,那么如何使用这个CMake工具呢?接下来一步一步的操作。

步骤1:基本起点

       1.1:新建一个需要执行tutorial.cxx源文件,该文件需要含有main函数,可直接运行的,tutorial.h文件可不需要。文件内容如下所示(自己可随便写,本人是复制官网的代码):

// 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;
}

        1.2:CMake生产工程,最基础的一点就是在源文件同级目录下需要新增一个CMakeLists.txt文件,那么如何编写CMakeLists.txt呢?先使用CMakeLists.txt生成一个最简单的工程(CMakeLists.txt代码如下所示)。

#设置项目最低CMake版本
cmake_minimum_required (VERSION 2.6)

#为项目设置名称,也就是生成的工程名
project (Tutorial)

#使用指定的源文件将可执行文件添加到项目中
add_executable(Tutorial tutorial.cpp)

        -- cmake_minimum_required:改命令就如同翻译的字面意思一样,设置项目的最低要求的CMake版本(本人下载3.15的版本)。如果自己电脑上版本的CMake低于所需版本,则它将停止处理项目并报告错误。

        -- project:为需要生产的工程设置名字,并且会将项目的名称存储在 PROJECT_NAME变量中(CMake自带变量),同时还会将工程源代码路径存储在PROJECT_SOURCE_DIR变量中,以及将工程路径存储在PROJECT_SOURCE_DIR变量中。

    -- add_executable:添加可执行文件,其实也就是将main所在的文件添加。

     1.3:在源文件和CMakeLists.txt同级目录下新增一个空文件夹(可新增在任意地方,只是个人方便),用于存放所生成的工程,名字自拟,新建了build文件夹。最终完成1.1~1.3后,其新增文件或文件夹示意图如图2所示。

                                              

                                                                      图2 新增文件或文件夹示意图

         1.4:运行CMake工具,生成工程,如图3所示。

                                                                             图3 CMake工具执行示意图

       如图3所示,配置完成后点击Finish即可,最后Configure白色框会显示Configuring done,其示意图如图4所示。

                             

                                                                           图4 Configure完成示意图

         Configure完成后,并不会生成工程,只会在build文件夹中生产CMakeFiles和CMakeCache.txt,那么VS工程才生成需要点击Generate键即可,会出现Generating done则表示VS工程已生成,其Generating done示意图如图5所示,而build文件夹中的VS工程如图6所示。

                            

                                                                         图5 Generating done示意图

                               

                                                               图6 生成VS工程示意图

       点击图6中的Tutorial.sln即可,其运行示意图如图7所示。

                                                                          图7 Tutorial.sln工程运行示意图

        1.5:添加版本号和配置头文件。接下来将为我们的可执行文件和项目提供版本号。虽然可以在源代码中专门执行此操作,但在CMakeLists.txt文件中执行此操作可提供更大的灵活性。要添加版本号,我们修改CMakeLists.txt文件,如下所示:

#设置项目最低CMake版本
cmake_minimum_required (VERSION 2.6)

#为项目设置名称,也就是生成的工程名
project (Tutorial)

#设置版本号
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# 配置头文件
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
 
#添加头文件路径,以便能够查找到头文件
include_directories("${PROJECT_BINARY_DIR}")
 
#使用指定的源文件将可执行文件添加到项目中
add_executable(Tutorial tutorial.cxx)

   -- set:该函数有多种方式,而上述中描述的是:set(<variable> <value>... [PARENT_SCOPE]),其设置<variable>的值为<value>。如果给出PARENT_SCOPE选项,则将在当前范围上方的范围中设置变量。

  -- configure_file:该函数形式是configure_file(<input> <output> [COPYONLY] [ESCAPE_QUOTES] [@ONLY] [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ]),作用是复制<input>文件至<output>文件。其中<input>是输入文件的路径,输入路径必须是文件,而不是目录;<output>是输出文件或目录的路径,如果在输出目录中有命名相同的文件,则输出文件会覆盖目录中文件。

  -- include_directories:将include目录添加至构建中。

       configure_file中PROJECT_SOURCE_DIR表示的是源目录,也就是tutorialConfig.cpp所在目录,PROJECT_BINARY_DIR表示的是工程目录,也就是上述build文件中,在上述图中有TutorialConfig.h是由TutorialConfig.h.in所产生的文件,不需要在build目录下新建该文件。换句话说,通过TutorialConfig.h.in在build下产生TutorialConfig.h文件,然后在工程中需要添加TutorialConfig.h文件,则通过在include_directories函数中填写TutorialConfig.h所在目录即可。TutorialConfig.h.in或TutorialConfig.h的路径可放入其他文件夹中,但是在configure_file中填写TutorialConfig.h.in或TutorialConfig.h的路径时,一定要填写对,例如:想把生成的TutorialConfig.h文件放入与源代码同级目录的include文件中,则configure_file中"${PROJECT_BINARY_DIR}/TutorialConfig.h"应该改成"${PROJECT_BINARY_DIR}/../include/TutorialConfig.h",则会把TutorialConfig.h生成至源文件的同级include文件夹中,同时include_directories中路径也得改成"${PROJECT_BINARY_DIR}/../include/"。TutorialConfig.h.in文件的内容如下所示。

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

        此时为了体现TutorialConfig.h文件中所定义的宏Tutorial_VERSION_MAJOR和Tutorial_VERSION_MINOR是否生效,tutorialConfig.cpp文件内容修改如下所示。

// 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;
}

       使用工程generate后,会在相应的路径下生成TutorialConfig.h文件,如图8所示,而TutorialConfig.h文件内容如图9所示。

                                                                     

                                                          图8 TutorialConfig.h所在目录示意图

                                           

                                                             图9 TutorialConfig.h内容示意图

     执行工程,其示意图如图10所示。

                                                                                  图10 工程示意图

步骤2:

未完待续......

发布了42 篇原创文章 · 获赞 86 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_33206497/article/details/92740560