CMake代码示例

CMake代码示例(注:此文只贴了部分示例代码,详细文章见最后参考文章):

1、为工程和可执行文件指定一个版本号

虽然可以在源代码中唯一指定它,但是在CMakeLists文件中指定它可以提供更好的灵活性

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# 版本号
set (
Tutorial_VERSION_MAJOR
 1)
set (
Tutorial_VERSION_MINOR
 0)
# 配置一个头文件,通过它向源代码中传递一些CMake设置。
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
# 将二进制文件树添加到包含文件的搜索路径中,这样我们可以找到TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")
# 添加可执行文件
add_executable(Tutorial tutorial.cxx)

     由于配置过的文件将会被写到二进制文件目录下,所以必须把该目录添加到包含文件的搜索路径清单中,因此在源目录下创建一份TotorialConfig.h.in文件:

 // 与tutorial相关的配置好的选项与设置; 
#define Tutorial_VERSION_MAJOR @
Tutorial_VERSION_MAJOR
@
#define Tutorial_VERSION_MINOR @
Tutorial_VERSION_MINOR
@
    当CMake配置这份头文件时,@Tutorial_VERSION_MAJOR@和@Tutorial_VERSION_MINOR@的值将会被

从CMakeLists文件中

传递过来的值

替代

 
2、引入

可选库

(对于更大型的库或者依赖于第三方代码的库,你可能需要这种可选择性。)
# 是否使用自己的数学函数,可选项;
option (USE_MYMATH
"Use tutorial provided math implementation" ON)

  这将会在CMake的GUI中显示一个默认的ON值,并且用户可以随需改变这个设置。这个设置会被存储在cache中,那么用户将不需要在cmake该工程时,每次都设置这个选项。

# 是否添加MathFunctions库
if (USE_MYMATH)
    include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
    add_subdirectory (MathFunctions)
    set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# 添加可执行文件
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

  USE_MYMATH决定是否MathFunctions应该被编译和执行。注意到,要用一个变量(在这里是EXTRA_LIBS)来收集所有以后会被连接到可执行文件中的可选的库。

//main函数中的修改
#ifdef USE_MYMATH
  #include "MathFunctions.h"
#endif
  
#ifdef USE_MYMATH
  double outputValue = mysqrt(inputValue);
#else
  double outputValue = sqrt(inputValue);
#endif

 

3、引入安装规则以及测试支持

     安装规则相当直白,对于MathFunctions库,我们通过向MathFunctions的CMakeLists文件添加如下两条语句来设置要安装的库以及头文件

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

  对于应用程序,在顶层CMakeLists文件中添加下面几行,它们用来安装可执行文件以及配置头文件

 

# 添加安装目标
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)

  构建tutorial工程,敲入命令make install(或者从IDE中构建INSTALL目标)然后它就会安装需要的头文件,库以及可执行文件CMake的变量CMAKE_INSTALL_PREFIX用来确定这些文件被安装的根目录。添加测试同样也只需要相当浅显的过程。在顶层CMakeLists文件的的尾部补充许多基本的测试代码来确认应用程序可以正确工作。

 

# 应用程序是否运行
add_test (TutorialRuns Tutorial 25)

# 它是否对25做了开平方运算
add_test (TutorialComp25 Tutorial 25)

set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")

# 它是否能处理是负数作为输入的情况
add_test (TutorialNegative Tutorial -25)

set_tests_properties (TutorialNegative

PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")

# 它是否可以处理较小的数字

add_test (TutorialSmall Tutorial 0.0001)

set_tests_properties (TutorialSmall

PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")

# 用法信息是否可用
add_test (TutorialUsage Tutorial)

set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

  第一个测试用例仅仅用来验证程序可以运行,没有出现 错误或其他的崩溃,并且返回值必须是0。这是CTest所做测试的基本格式。余下的几个测试都是用PASS_REGULAR_EXPRESSION 测试属性来验证测试代码的输出是否包含有特定的字符串。在本例中,测试样例用来验证计算得出的平方根与预定值一样;当指定错误的输入数据时,要打印用法信息。如果想要添加许多测试不同输入值的样例,应该考虑创建如下所示的宏:

 

#定义一个宏来简化添加测试的过程,然后使用它

macro (do_test arg result)

add_test (TutorialComp${arg} Tutorial ${arg})

set_tests_properties (TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})

endmacro (do_test)<br># 做一系列基于结果的测试

do_test (25 "25 is 5")

do_test (-25 "-25 is 0")

对于每个do_test宏调用,都会向工程中添加一个新的测试用例宏参数是测试名函数的输入以及期望结果

 

# 整个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 functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings
# to the source code 向src传递参数
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 MathFunctions library?
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif ()

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

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


# enable testing 测试
enable_testing ()

# 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" )

 

# 子文件夹CMakelists.txt
# 文件夹中有这两个文件:mysqrt.cxx,MathFunctions.h
add_library(MathFunctions mysqrt.cxx)

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

 

4、向工程引入一些依赖于目标平台上可能不具备的特性的代码(例如目标平台没有的数学函数

    在本例中,我们会增加一些依赖于目标平台是否有log或exp函数的代码。当然,几乎每个平台都有这些函数;但是对于tutorial工程,我们假设它们并非如此普遍。如果该平台有log函数,那么我们会在mysqrt函数中使用它去计算平方根。我们首先在顶层CMakeLists文件中使用宏CheckFunctionExists.cmake测试这些函数的可用性

# 整个CMakelists.txt
cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# 系统是否提供
the log and exp functions?

include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

# 是否应该使用 our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# 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}")

# 是否添加 the MathFunctions library
?
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif ()

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

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

# 使能testing
enable_testing ()

# does the application run
add_test (TutorialRuns Tutorial 25)

# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

#define a 
macro
 to 
simplify adding tests

macro (do_test arg result)
  add_test (TutorialComp${arg} Tutorial ${arg})
  set_tests_properties (TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endmacro ()

# do a bunch of result based tests
do_test (25 "25 is 5") # arg,result
do_test (-25 "-25 is 0")
do_test (0.0001 "0.0001 is 0.01")

源文件:

# 子函数中

 // if we have both log and exp then use them
#if defined(
HAVE_LOG
) && defined (
HAVE_EXP
)
  result = exp(log(x)*0.5);
  fprintf(stdout,"Computing sqrt of %g to be %g using log\n",x,result);
#else
  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);
    }
#endif

# main函数

#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif

#ifdef USE_MYMATH
    outputValue = mysqrt(inputValue);
#else
    outputValue = sqrt(inputValue);
#endif

5、向一个应用程序的构建过程中添加一个生成的源文件

# 首先,我们添加生成这个表的可执行文件
add_executable(MakeTable MakeTable.cxx)
# 添加生成源代码的命令
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  )
# 为包含文件向搜索路径中添加二进制树目录
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
  
# 添加main库
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

 

创建一个预先计算出的平方根表作为构建过程的一部分。MathFunctions子路径下,一个新的MakeTable.cxx源文件来完成这事。

// MakeTable.cxx文件
// A simple program that builds a sqrt table
#include <stdio.h>
#include <math.h>

int main (int argc, char *argv[])
{
  int i;
  double result;

  // make sure we have enough arguments
  if (argc < 2)
    {
    return 1;
    }

  // open the output file
  FILE *fout = fopen(argv[1],"w");
  if (!fout)
    {
    return 1;
    }

  // create a source file with a table of square roots
  fprintf(fout,"double sqrtTable[] = {\n");
  for (i = 0; i < 10; ++i)
    {
    result = sqrt(
static_cast
<double>(i));
    fprintf(fout,"%g,\n",result);
    }

  // close the table with a zero
  fprintf(fout,"0};\n");
  fclose(fout);
  return 0;
}

6、使用CPack来创建Packaging with CPack一章中描述的特定平台的安装器

# 构建一个CPack驱动的安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
     "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include (CPack)

如果要构建一个二进制发行包,你应该运行:

cpack
 -C CPackConfig.cmake

为了创建一个源代码发行版,你应该键入:

cpack
 -C CPack
Source
Config.cmake

7、实现向一个dashboard提交我们的测试结果的功能

为包含对dashboards的支持,我们需要在顶层CMakeLists文件中包含CTest模块

# 支持dashboard脚本
include (CTest)

创建一个CTestConfig.cmake文件,在其中来指定该dashboard的工程名。

set (CTEST_PROJECT_NAME "Tutorial")

CTest 将会在运行期间读取这个文件。

 

详细文章请移步:http://www.cnblogs.com/coderfenghc/archive/2013/01/20/2846621.html#3176055

posted @ 2015-06-13 20:42  _木头人  阅读(1258)  评论(0编辑  收藏  举报