https://cmake.org/cmake/help/latest/guide/tutorial/index.html
添加库(步骤2)
现在,我们将向我们的项目添加一个库。 该库将包含我们自己的实现,用于计算数字的平方根。 然后可执行文件可以使用此库而不是编译器提供的标准平方根函数。
在本教程中,我们将库放入名为MathFunctions的子目录中。 该目录已包含头文件MathFunctions.h和源文件mysqrt.cxx。 源文件具有一个称为mysqrt的函数,该函数提供与编译器的sqrt函数类似的功能。
将以下一行CMakeLists.txt文件添加到MathFunctions目录中:
add_library(MathFunctions mysqrt.cxx)
为了利用新库,我们将在顶层CMakeLists.txt文件中添加add_subdirectory()调用,以便构建该库。 我们将新库添加到可执行文件,并将MathFunctions添加为包含目录,以便可以找到mqsqrt.h头文件。 现在,顶层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"
)
现在让我们将MathFunctions库设为可选。 虽然对于本教程而言确实不需要这样做,但对于大型项目来说,这是很常见的。 第一步是向顶级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)
此选项将显示在cmake-gui和ccmake中,默认值ON可由用户更改。 此设置将存储在缓存中,因此用户无需在每次在构建目录上运行CMake时都设置该值。
下一个更改是使建立和链接MathFunctions库成为条件。 为此,我们将顶级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}
)
请注意,使用变量EXTRA_LIBS来收集所有可选库,以供以后链接到可执行文件中。 变量EXTRA_INCLUDES类似地用于可选的头文件。 当处理许多可选组件时,这是一种经典方法,我们将在下一步中介绍现代方法。
对源代码的相应更改非常简单。 首先,如果需要,请在tutorial.cxx中包含MathFunctions.h标头:
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
然后,在同一文件中,使USE_MYMATH控制使用哪个平方根函数:
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
由于源代码现在需要USE_MYMATH,因此可以使用以下行将其添加到TutorialConfig.h.in中:
#cmakedefine USE_MYMATH
练习:为什么在USE_MYMATH选项之后配置TutorialConfig.h.in如此重要? 如果我们将两者倒置会怎样?
运行cmake可执行文件或cmake-gui来配置项目,然后使用所选的构建工具对其进行构建。 然后运行构建的Tutorial可执行文件。
使用ccmake可执行文件或cmake-gui更新USE_MYMATH的值。 重新生成并再次运行本教程。 sqrt或mysqrt哪个函数可提供更好的结果?