当前位置:网站首页>Cmake tutorial Step2 (add Library)

Cmake tutorial Step2 (add Library)

2022-07-05 17:45:00 It's beginning to boil

CMake Official documents

Refer to the official cmake3.24 Course translation
https://cmake.org/cmake/help/v3.24/guide/tutorial/index.html
https://gitlab.kitware.com/cmake/cmake/-/tree/master/Help/guide/tutorial
step2
https://cmake.org/cmake/help/v3.24/guide/tutorial/Adding%20a%20Library.html
My warehouse :
https://github.com/FRBoiling/cmake-tutorial.git

Add a library

Now? , We will add a library to the project . This library will contain our own implementation of calculating the square root of numbers . then , Executable files can use this library , Instead of the standard square root function provided by the compiler .
In this tutorial , We will put the library into a file named MathFunctions In the subdirectory of . This directory contains a header file MathFunctions.h And a source file mysqrt.cxx. The source file has a name mysqrt Function of , It provides with the compiler sqrt Functions similar functions .
Add the following line CMakeLists.txt Add files to MathFunctions Catalog :

Initialize the library

Go to the project folder Step2, Create subdirectories MathFunctions, This directory contains a header file MathFunctions.h、 A source file mysqrt.cxx And a CMakeLists.txt file

mkdir Step2 Step2_build
cd Step2
mkdir MathFunctions
cd MathFunctions
touch MathFunctions.h mysqrt.cxx CMakeLists.txt

MathFunctions.h The contents are as follows :

double mysqrt(double x);

mysqrt.cxx The contents in are as follows :

#include <iostream>

// a hack square root calculation using simple operations
double mysqrt(double x)
{
    
  if (x <= 0) {
    
    return 0;
  }

  double result = x;

  // do ten iterations
  for (int i = 0; i < 10; ++i) {
    
    if (result <= 0) {
    
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
  }
  return result;
}

CMakeLists.txt The contents are as follows

add_library(MathFunctions mysqrt.cxx)

Project reference library

The project structure is as follows :
image.png
In order to use the new library , We will be in the top-level directory (Step2)CMakeLists.txt Add a add_subdirectory() call , In order to build a library . We add the new library to the executable , And add MathFunctions As include Catalog , So that you can find MathFunctions.h The header file . top CMakeLists.txt The last few lines of the file should now look like this :

# add the MathFunctions library
add_subdirectory(MathFunctions)

# add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC MathFunctions)

# 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}"
                          "${PROJECT_SOURCE_DIR}/MathFunctions"
                          )

1.1、 Build optional options

Now? Let's go MathFunctions The library is set to optional . For this tutorial , There is really no need to do this , But for the Bigger projects Come on , This is a common situation . The first step is at the top CMakeLists.txt Add an option to the file .

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(tutorial_config.h.in tutorial_config.h)

This option will be displayed in cmake-gui and ccmake in , The default value is ON, The user can change this value . This setting will be stored in the cache , In this way, users do not need to run on the build directory every time CMake This value is set when .

1.2、 Condition building and linking

next The change is to build and link MathFunctions The library is set to condition . So , We're going to create one if Statement to check the value of this option . stay if In block , Put it in the top add_subdirectory() Commands and some additional list commands , To store the information needed to link to the Library , And take the subdirectory as include Add the directory to the tutorial target . top CMakeLists.txt The end of the file now looks like this :

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

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

Be careful , Using variables EXTRA_LIBS Collect any optional libraries , So that you can link to the executable later . Again , Variable EXTRA_INCLUDES For optional header files . When dealing with many optional components , This is a classic method , We will introduce modern methods in the next step .

Use libraries in source code

The corresponding changes to the source code are quite simple . First ,tutorial.cxx It includes MathFunctions.h The header file :

#ifdef USE_MYMATH
  include "MathFunctions.h"
#endif

then , In the same file , Use USE_MYMATH Controls which square root function to use :

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

Because the source code now needs USE_MYMATH, We can add it to TutorialConfig.h.in:

#cmakedefine USE_MYMATH

Tests and exercises

Final Step2/CMakeLists.txt The contents are as follows

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(Tutorial VERSION 1.0)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 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(TutorialConfig.h.in TutorialConfig.h)

# add the MathFunctions library
if(USE_MYMATH)
  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)

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

tutorial.cxx The contents are as follows

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include "tutorial_config.h"
#ifdef USE_MYMATH
#include "math_functions.h"
#endif

int main(int argc, char *argv[])
{
    
    // if(argc<2){
    
    // fprintf(stdout, "Uage: %s number\n", argv[0]);
    // return 1;
    // }
    if (argc < 2)
    {
    
        // report version
        std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                  << Tutorial_VERSION_MINOR << std::endl;
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }
    // double inputValue = atof(argv[1]);
    const double inputValue = std::stod(argv[1]);
#ifdef USE_MYMATH
    const double outputValue = mysqrt(inputValue);
#else
    const double outputValue = sqrt(inputValue);
#endif
    fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue);
    return 0;
}

practice

1、Why is it important that we configure tutorial_config.h.in after the option for USE_MYMATH?
2、What would happen if we inverted the two?
function cmake Executable or cmake-gui To configure the project , Then build it using the build tool of your choice . Then run the built Tutorial Executable file .

test

Now let's update USE_MYMATH Value .
The simplest way is to use it in the terminal cmake-gui or ccmake.
You can also modify this option from the command line , as follows

cmake …/Step2 -DUSE_MYMATH=ON

image.png

cmake …/Step2 -DUSE_MYMATH=OFF

image.png
Rebuild and run this tutorial again .

Which function gives a better result ,sqrt still mysqrt?

原网站

版权声明
本文为[It's beginning to boil]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207051636053590.html