CMake Tutorial (Step2)(Adding a Library)

Step 2: Adding a Library

Now we will add a library to our project. This library will contain our own implementation for computing the square root of a number. The executable can then use this library instead of the standard square root function provided by the compiler.

For this tutorial we will put the library into a subdirectory called MathFunctions. This directory already contains a header file, MathFunctions.h, and a source file mysqrt.cxx. The source file has one function called mysqrt that provides similar functionality to the compiler's sqrt function.

Add the following one line CMakeLists.txt file to the MathFunctions directory:

MathFunctions/CMakeLists.txt

add_library(MathFunctions mysqrt.cxx)

[LEandLA]:add_library — CMake 3.24.0-rc1 Documentation

To make use of the new library we will add an add_subdirectory() call in the top-level CMakeLists.txt file so that the library will get built. We add the new library to the executable, and add MathFunctions as an include directory so that the MathFunctions.h header file can be found. The last few lines of the top-level CMakeLists.txt file should now look like:

CMakeLists.txt

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

[LEandLA]:

add_subdirectory — CMake 3.24.0-rc1 Documentation

target_link_libraries — CMake 3.24.0-rc1 Documentation

target_link_directories — CMake 3.24.0-rc1 Documentation

Now let us make the MathFunctions library optional. While for the tutorial there really isn't any need to do so, for larger projects this is a common occurrence. The first step is to add an option to the top-level CMakeLists.txt file.

CMakeLists.txt

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)

This option will be displayed in the cmake-gui and ccmake with a default value of ON that can be changed by the user. This setting will be stored in the cache so that the user does not need to set the value each time they run CMake on a build directory.

The next change is to make building and linking the MathFunctions library conditional. To do this, we will create an if statement which checks the value of the option. Inside the if block, put the add_subdirectory() command from above with some additional list commands to store information needed to link to the library and add the subdirectory as an include directory in the Tutorial target. The end of the top-level CMakeLists.txt file will now look like the following:

CMakeLists.txt

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

[LEandLA]:

list — CMake 3.24.0-rc1 Documentation

Note the use of the variable EXTRA_LIBS to collect up any optional libraries to later be linked into the executable. The variable EXTRA_INCLUDES is used similarly for optional header files. This is a classic approach when dealing with many optional components, we will cover the modern approach in the next step.

The corresponding changes to the source code are fairly straightforward. First, in tutorial.cxx, include the MathFunctions.h header if we need it:

tutorial.cxx

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif

Then, in the same file, make USE_MYMATH control which square root function is used:

tutorial.cxx

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

Since the source code now requires USE_MYMATH we can add it to TutorialConfig.h.in with the following line:

TutorialConfig.h.in

#cmakedefine USE_MYMATH

[LEandLA]:同样在TutorialConfig.h文件下会自动生成如下:

#define USE_MYMATH

Exercise: Why is it important that we configure TutorialConfig.h.in after the option for USE_MYMATH? What would happen if we inverted the two?

Run the cmake executable or the cmake-gui to configure the project and then build it with your chosen build tool. Then run the built Tutorial executable.

Now let's update the value of USE_MYMATH.[LEandLA]:有哪些方法?

The easiest way is to use the cmake-gui or ccmake if you're in the terminal. Or, alternatively, if you want to change the option from the command-line, try:

cmake ../Step2 -DUSE_MYMATH=OFF

Rebuild and run the tutorial again.

Which function gives better results, sqrt or mysqrt?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值