// a hack square root calculation using simple operations doublemysqrt(double x) { if (x <= 0) { return0; }
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; }
# 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")
#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 this system provide the log and exp functions? include (CheckFunctionExists) check_function_exists (log HAVE_LOG) check_function_exists (exp HAVE_EXP)
Next we modify the TutorialConfig.h.in to define those values if CMake found them on the platform as follows: 下一步,如果CMake发现平台有我们需要的这些函数,则需要修改TutorialConfig.h.in来定义这些值
1 2 3 4
// does the platform provide exp and logfunctions? #cmakedefine HAVE_LOG #cmakedefine HAVE_EXP
// if we have both log and exp then use them #if defined (HAVE_LOG) && defined (HAVE_EXP) result = exp(log(x)*0.5); #else// otherwise use an iterative approach . . .
// A simple program that builds a sqrt table #include<stdio.h> #include<stdlib.h> #include<math.h> intmain(int argc, char *argv[]) { int i; double result; // make sure we have enough arguments if (argc < 2) { return1; } // open the output file FILE *fout = fopen(argv[1],"w"); if (!fout) { return1; } // 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); return0; }
# 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 )
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})
# 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.in 文件如下:
1 2 3 4 5 6 7
// 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如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
# 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)