原文网址:http://cmake.org/cmake/help/cmake_tutorial.html
教程中所有的代码都可以在这里找到:http://public.kitware.com/cgi-bin/viewcvs.cgi/CMake/Tests/Tutorial/
在这一节中,我们会展示如何在项目的编译过程中使用一个间接生成的文件。例如我们建立一个保存事先计算好的平方根的表做为编译的一部分,之后将这个表编译到我们的应用中。要完成这一功能,我们首先需要一个程序生成这个表。我们用在MathFunctions子目录下新建的MakeTable.cxx来完成这一工作:
// A simple program that builds a sqrt table #include <stdio.h> #include <stdlib.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; }
注意,这个表是使用C++代码生成的,并且输出文件名也通过参数传了过去。接下来就是在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 # MakeTable是第二行编译出的可执行文件,接下来是输出文件名 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知道mysqrt.cxx依赖于生成的Table.h。这是通过将生成的Table.h添加到MathFunctions所需的代码文件实现的。我们也需要include生成的Table.h的目录,让编译器找得到Table.h。
当编译项目时,MakeTable会被首先编译出来。之后MakeTable会被运行来生成Table.h。最后,include了Table.h的mysqt.cxx文件会被编译来生成MathFunctions库。
现在,完整的顶层的CMakeLists.txt如下所示:
cmake_minimum_required (VERSION 2.6) project (Tutorial) # 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)