CMake Tutorial(5)——Adding a Generated File and Generator

这一节,我将向你展示如何将一个生成的源文件添加至应用程序的构建过程中。在本次示例,我们会创建一个预计算数值平方根的表(文本文件),将其作为构建过程的一部分,然后将这个表编译到你的应用程序中。为了实现该功能,我需要一个用于生成该表的程序,我们在MathFunctions目录中创建一个MakeTable.cxx文件内容如下:

这里写代码片// A simple program that builds a sqrt table
#include <cstdio>
#include <cstdlib>
#include <cmath>

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

    if (argc < 2) {
        return 1;
    }

    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 (int 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;
}

程序通过接受argv[1]作为文件名并将数据写入。接下来我们需要在MathFunctions文件下的CMakeLists.txt文件中加入合适的命令去构建MakeTable的可执行文件,并且让它作为构建过程的一部分运行。需要添加的命令如下:

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)

# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  )

# add the binary tree directory to the search path for 
# include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h  )

首先我们像添加其他可执行文件一样添加MakeTable,接着我们添加一个自定义命令用于指定如何通过运行MakeTable来产生文件Table.h(CMAKE_CURRENT_BINARY_DIR表示当前正在构建的目录)。接下来,我们需要让CMake知道,mysqrt.cxx依赖生成文件Table.h,可以把Table.h添加至MathFunctions库的源文件列表中来达到这一目的。当这个工程构建时,会先构建MakeTable可执行文件。接着会运行它动态产生Table.h。最后让mysqrt.cxx包含Table.h,并编译它来生成MathFunctions库。完成上面以及前面几节的内容后,顶层CMakeLists.txt文件内容如下:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
include(CTest)

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

# does this system provide the log and exp functions?
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)

check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

# 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
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 (USE_MYMATH)

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

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

# do a bunch of result based tests
do_test (4 "4 is 2")
do_test (9 "9 is 3")
do_test (5 "5 is 2.236")
do_test (7 "7 is 2.645")
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")
do_test (0.0001 "0.0001 is 0.01")

TutorialConfig.h

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

// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

MathFunctions目录下的CMakeLists.txt

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  )
# add the binary tree directory to the search path 
# for include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)

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

猜你喜欢

转载自blog.csdn.net/YZS_L_H/article/details/64131749