当前位置 博文首页 > fareast_mzh的博客:CMake教程 Step 2: Adding a Library

    fareast_mzh的博客:CMake教程 Step 2: Adding a Library

    作者:[db:作者] 时间:2021-08-13 15:52

    Step 2: Adding a Library

    ?

    ?* ../Step2/CMakeLists.txt

    cmake_minimum_required(VERSION 3.10)
    
    # specify the C++ standard
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # set the project name and version
    project(Tutorial VERSION 1.1)
    
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    
    if (USE_MYMATH)
      # add the MathFunctions library
      add_subdirectory(MathFunctions)
      list(APPEND EXTRA_LIBS MathFunctions)
      list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
    endif()
    
    # add the executable
    add_executable(Tutorial tutorial.cxx)
    
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
    
    # add the binary tree to the search path for include files
    # so that we will find TutorialConfig.h
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
    			   ${EXTRA_INCLUDES}
                               )

    *?../Step2/TutorialConfig.h.in

    #cmakedefine USE_MYMATH

    * ../Step2/tutorial.cxx

    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include "TutorialConfig.h"
    
    #ifdef USE_MYMATH
    #  include "MathFunctions.h"
    #endif
    
    #ifndef INPUT_VALUE
     #define INPUT_VALUE 3.0f
    #endif
    
    int main(int argc, char *argv[]) {
      double inputValue = 0;
      if (argc < 2) {
        inputValue = INPUT_VALUE;
      } else {
        inputValue = atof(argv[1]);
      }
    #ifdef USE_MYMATH
      const double outputValue = mysqrt(inputValue);
    #else
      const double outputValue = sqrt(inputValue);
    #endif
      std::cout << outputValue << std::endl;
    }

    *?../Step2/MathFunctions/CMakeLists.txt

    add_library(MathFunctions mysqrt.cxx)

    *?../Step2/MathFunctions/MathFunctions.h

    #ifndef MATH_FUNCTIONS
    #define MATH_FUNCTIONS
    
    #define NaN -2147483648.0
    #define abs(v) ((v)>0?(v):(-v))
    
    double mysqrt(double c);
    
    #endif

    *?../Step2/MathFunctions/mysqrt.cxx

    #include "MathFunctions.h"
    
    double mysqrt(double c) {
      if (c < 0) {
        return NaN;
      }
      double err = 1e-15;
      double t = c;
      while (abs(t - c/t) > err * t) {
        t = (c/t + t) / 2.0;
      }
      return t;
    }

    ?编译测试

    cmake ../Step2
    make
    ./Tutorial 6

    关掉USE_MYMATH试试:

    cmake ../Step2 -DUSE_MYMATH=OFF
    make

    需要引入math头文件

    ?

    ?../Step2/tutorial.cxx

    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include "TutorialConfig.h"
    
    #ifdef USE_MYMATH
    #  include "MathFunctions.h"
    #else
    #  include <cmath>
    #endif
    
    #ifndef INPUT_VALUE
     #define INPUT_VALUE 3.0f
    #endif
    
    int main(int argc, char *argv[]) {
      double inputValue = 0;
      if (argc < 2) {
        inputValue = INPUT_VALUE;
      } else {
        inputValue = atof(argv[1]);
      }
    #ifdef USE_MYMATH
      const double outputValue = mysqrt(inputValue);
    #else
      std::cout << "System cmath\n";
      const double outputValue = sqrt(inputValue);
    #endif
      std::cout << outputValue << std::endl;
    }

    abs用宏定义有bug, ./Tutorial 0.0001这个case跑不过。

    ================================================================

    添加install, test命令

    ../Step2/CMakeLists.txt

    cmake_minimum_required(VERSION 3.10)
    
    # specify the C++ standard
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # set the project name and version
    project(Tutorial VERSION 1.1)
    
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    
    if (USE_MYMATH)
      # add the MathFunctions library
      add_subdirectory(MathFunctions)
      list(APPEND EXTRA_LIBS MathFunctions)
    #  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
    endif()
    
    # add the executable
    add_executable(Tutorial tutorial.cxx)
    
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
    
    # add the binary tree to the search path for include files
    # so that we will find TutorialConfig.h
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
                               )
    
    install(TARGETS Tutorial DESTINATION bin)
    install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
      DESTINATION include
    )
    
    enable_testing()
    
    # does the application run
    add_test(NAME Runs COMMAND Tutorial 25)
    
    # does the usage message work?
    add_test(NAME Usage COMMAND Tutorial)
    set_tests_properties(Usage
      PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
      )
    
    # define a function to simplify adding tests
    function(do_test target arg result)
      add_test(NAME Comp${arg} COMMAND ${target} ${arg})
      set_tests_properties(Comp${arg}
        PROPERTIES PASS_REGULAR_EXPRESSION ${result}
        )
    endfunction(do_test)
    
    # do a bunch of result based tests
    do_test(Tutorial 4 "4 is 2")
    do_test(Tutorial 9 "9 is 3")
    do_test(Tutorial 5 "5 is 2.236")
    do_test(Tutorial 7 "7 is 2.645")
    do_test(Tutorial 25 "25 is 5")
    do_test(Tutorial -25 "-25 is [-nan|nan|0]")
    do_test(Tutorial 0.0001 "0.0001 is 0.01")
    

    ../Step2/tutorial.cxx

    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include "TutorialConfig.h"
    
    #ifdef USE_MYMATH
    #  include "MathFunctions.h"
    #else
    #  include <cmath>
    #endif
    
    int main(int argc, char *argv[]) {
      double inputValue = 0;
      if (argc < 2) {
        std::cout << "Usage: "<< argv[0] << "number\n";
        return 0;
      }
      inputValue = atof(argv[1]);
    
    #ifdef USE_MYMATH
      const double outputValue = mysqrt(inputValue);
    #else
      std::cout << "System cmath\n";
      const double outputValue = sqrt(inputValue);
    #endif
      std::cout << "sqrt " << inputValue << " is " << outputValue << "\n";
    }
    

    ../Step2/MathFunctions/CMakeLists.txt

    add_library(MathFunctions mysqrt.cxx)
    
    target_include_directories(MathFunctions
      INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
      )
    
    install(TARGETS MathFunctions DESTINATION lib)
    install(FILES MathFunctions.h DESTINATION include)

    ../Step2/MathFunctions/MathFunctions.h

    #ifndef MATH_FUNCTIONS
    #define MATH_FUNCTIONS
    
    #define NaN 0
    
    double mysqrt(double c);
    
    #endif

    ../Step2/MathFunctions/mysqrt.cxx

    #include "MathFunctions.h"
    
    double abs(double x) {
      if (x >= 0) {
        return x;
      }
      return 0-x;
    }
    
    double mysqrt(double c) {
      if (c < 0) {
        return NaN;
      }
      double err = 1e-15;
      double t = c;
      while (abs(t - c/t) > err * t) {
        t = (c/t + t) / 2.0;
      }
      return t;
    }

    编译安装测试

    mkdir Step2_build
    cd Step2_build
    cmake ../Step2
    make install
    make test

    cs
    下一篇:没有了