CMake 七步入门

来源:互联网 发布:nodejs 数据库 编辑:程序博客网 时间:2024/04/29 17:36

前言

CMake是什么? 官网给出的定义是这样的:”an open-source, cross-platform family of tools designed to build, test and package software”。很容易理解它是一个编译工具,是一个测试工具,也是一个打包工具,它其实就是一个工具箱,可以完成编译,测试以及打包的工作。在使用OpenCV的时候,已经对CMake有了认识。
CMake是跨平台的,这里就win7系统下结合Visual Studio的使用给出一点说明,本文主要内容是基于官方的使用文档,个人认为,官方的文档一直是学习新知识的第一手资料。


Step 1 基础

最简单的应用就是直接利用源码文件来编译可执行程序,利用有这样一份源码,计算一个数的平方根。文件名为tutorial.cpp,代码如下

#tutorial.cpp// 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;}

这里生成一个简单的VS工程,只需要给出一个有2行命令的CMakeLists.txt文件,文件内容是这样的:

  cmake_minimum_required (VERSION 2.6)  project (Tutorial)  add_executable(Tutorial tutorial.cpp)

利用上面CMakeLists文件,可以生成一个名为Tutorial的工程文件。

假设你已安装好CMake程序,并且版本号是2.6以上的。打开CMake,按如图界面操作:
step1

其中源文件路径就是放置上述Tutorial.cpp以及CMakeLists.txt文件的位置,编译路径是一个空目录。配置编译器时,会提示创建build文件夹,点击确定。编译器的配置如图,根据实际情况选择,这里选择VS2010。
step1

点击Generate,生成工程文件,如图:
step1

编译运行结果:
step1

针对上述这样一个简单的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}/config.h.in"        "${PROJECT_BINARY_DIR}/config.h"    )   # add the binary tree to the search path for include files   # so that we will find config.h   include_directories("${PROJECT_BINARY_DIR}")   # add the executable   add_executable(Tutorial tutorial.cpp)

接着,我们在源文件路径下创建一个文件config.h.in,内容为:

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

当CMake配置congfig.h文件时,@Tutorial_VERSION_MAJOR@以及
@Tutorial_VERSION_MINOR@的值就会被替换成CMakeLists.txt中设置的值。
最后,我们修改tutorial.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;}

编译运行结果如图:
step1


step 2 添加依赖库

这里为工程添加一个依赖库,这个库的功能就是计算一个数的平方根。首先,在源文件路径下新建一个子目录MathFunc,定义使用的库函数:头文件MathFunc.h,源文件mysqrt.cpp以及CMakeLists.txt。

//MathFunc.hdouble mysqrt(double x);
//mysqrt.cpp#include "MathFunc.h"#include <stdio.h>// a hack square root calculation using simple operationsdouble mysqrt(double x){  if (x <= 0) {    return 0;  }  double result;  double delta;  result = x;  // do ten iterations  int i;  for (i = 0; i < 10; ++i) {    if (result <= 0) {      result = 0.1;    }    delta = x - (result * result);    result = result + 0.5 * delta / result;    fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result);  }  return result;}
CMakeLists.txtadd_library(MathFunc mysqrt.cpp)

接下来,修改主目录(源文件路径)下的CMakeLists.txt,让主工程能够调用子目录下的库函数,同时,添加一个可选项,可以选择是否使用该库函数。修改如下:

cmake_minimum_required (VERSION 2.6)project (Tutorial)# The version number.set (Tutorial_VERSION_MAJOR 1)set (Tutorial_VERSION_MINOR 0)# should we use our own math functionsoption(USE_MYMATH "Use tutorial provided math implementation" ON)# configure a header file to pass some of the CMake settings# to the source codeconfigure_file (  "${PROJECT_SOURCE_DIR}/config.h.in"    "${PROJECT_BINARY_DIR}/config.h" )# add the binary tree to the search path for include files# so that we will find config.hinclude_directories ("${PROJECT_BINARY_DIR}")# add the MathFunc library?if (USE_MYMATH)  include_directories ("${PROJECT_SOURCE_DIR}/MathFunc")  add_subdirectory (MathFunc)  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunc)endif ()# add the executableadd_executable (Tutorial tutorial.cpp)target_link_libraries (Tutorial  ${EXTRA_LIBS})

修改主函数代码,如下:

// A simple program that computes the square root of a number#include <stdio.h>#include <stdlib.h>#include <math.h>#include "config.h"#ifdef USE_MYMATH#include "MathFunc.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_MYMATH  double outputValue = mysqrt(inputValue);  #else  double outputValue = sqrt(inputValue);  #endif  fprintf(stdout,"The square root of %g is %g\n",          inputValue, outputValue);  return 0;}

最后,修改配置文件config.h.in,在文件末尾添加如下一行内容:

  #cmakedefine USE_MYMATH

编译运行结果如图:
step3


step 3 安装与测试

这里将在CMakeLists文件中添加安装规则与测试支持命令。
首先在子目录MathFunc中的CMakeLists.txt添加如下安装指令:

 install (TARGETS MathFunc DESTINATION bin) install (FILES MathFunc.h DESTINATION include)

然后修改主目录下CMakeLists.txt末尾添加如下内容:

 # add the install targets install (TARGETS Tutorial DESTINATION bin) install (FILES "${PROJECT_BINARY_DIR}/config.h"             DESTINATION include)

在CMake界面中可以设置安装路径,如图:
step3

在VS工程中可看到安装选项,右击生成即可将项目文件安装到指定目录。
step3

在主目录下的CMakeLists.txt结尾可加入测试用例,验证程序是否能正常运行。

  include(CTest)  #define a macro to simplify adding tests, then use it  macro (do_test arg result)    add_test (TutorialComp${arg} Tutorial ${arg})    set_tests_properties (TutorialComp${arg}    PROPERTIES PASS_REGULAR_EXPRESSION ${result}) endmacro (do_test) # do a bunch of result based tests do_test (25 "25 is 5") do_test (-25 "-25 is 0") # does it handle negative numbers add_test (TutorialNegative Tutorial -25) set_tests_properties (TutorialNegative PROPERTIES  ASS_REGULAR_EXPRESSION "-25 is 0") # does it handle small numbers add_test (TutorialSmall Tutorial 0.0001) set_tests_properties (TutorialSmall PROPERTIES  ASS_REGULAR_EXPRESSION "0.0001 is 0.01") # does the usage message work? add_test (TutorialUsage Tutorial) set_tests_properties (TutorialUsage PROPERTIES 

测试结果:
step3


step 4-7

至此,CMake的应用有了初步了解和认识。CMake还有其他的功能与特性有待了解,比如CheckFunctionExists.cmake 宏的使用,Generated File and Generator的使用,生成安装包文件等等。具体内容可参考这里。

                                                Unicorn Lewis, 04.08.2017
0 0