前言: 自己在使用cmake进行编译工程的时候不太了解cmake的基本使用方法,有时候出现找不到第三方库的问题也不知如何排查,因此相对cmake有个稍微系统的认识,希望能用这个强大的工具来更好的为自己的工程服务,因此总结为了几篇博客,主要参考的是官网的Tutorial,加入了自己的认识,另外,其实cmake本质上是一个工具,工具的作用就是用来帮助我们更好的构建项目的,所以对于工具能够满足使用要求就好,不必细枝末节的完全掌握,如有错误请斧正.
测试cmake版本:3.20.4
测试平台:ubuntu16.04
Tutorial源代码:https://github.com/FreddyName/cmake_tutorialshttps://github.com/FreddyName/cmake_tutorials
系列博客目录:
cmake学习1: 基本的CMakeLists.txt的编写https://blog.csdn.net/Heart_M/article/details/120626697
cmake学习2: 如何将源代码编译成库并使用https://blog.csdn.net/Heart_M/article/details/120632708
cmake学习3: 如何安装自己的工程在本地https://blog.csdn.net/Heart_M/article/details/120640741
cmake学习4: 如何将自己的工程打包给别人https://blog.csdn.net/Heart_M/article/details/120641933
cmake学习5: 如何将自己的库作为第三方库给别人使用https://blog.csdn.net/Heart_M/article/details/120643023
我们在编写自己的程序的时候,经常会遇到需要引用第三方库的情况,而引用第三方库的本质就是包含其头文件和配置文件以及链接编译好的库,而作为库的作者,我们需要提供一些文件来让库的引用者能够很方便的找到库,这就是这一节的目的:如何让其他人方便的找到并使用我们的库!
其实使用前面的安装方式也可以找到第三方库,但是这一节要解决的问题场景是假如第三方库的头文件和库特别多,我们在进行target_link_libraries的时候总不能一个库一个库的添加, 所以cmake使用的方法是库的作者提供.cmake文件说明库的路径变量,然后使用者在CMakeLists.txt中使用find_package()命令先找到.cmake文件再找到头文件和库
在总结之前,我们需要了解一下find_package的工作原理和.cmake文件的作用,其实find_package就是根据路径搜索到.cmake文件然后根据.cmake文件的内容得到第三方库的位置,这一部分下面的博客讲述的很好:“轻松搞定CMake”系列之find_package用法详解_zhanghm1995的博客-CSDN博客
我们可以先回忆一下opencv是如何被利用的:
find_package(OpenCV 3 REQUIRED)
message(STATUS "OpenCV_DIR = ${OpenCV_DIR}")
message(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}")
include_directories(${OPENCV_INCLUDE_DIRS})
add_executable(opencv_test opencv_test.cpp)
target_link_libraries(opencv_test ${OpenCV_LIBS})
可以看到cmake使用find_package()命令找到Opencv库,然后opencv的头文件路径就别保存到OPENCV_INCLUDE_DIRS和OpenCV_LIBS 变量中, 而我们接下来就是实现.cmake文件,使得使用者能通过find_package()命令找到我们的库.
开始操作
之前我们通过install命令将MathFunctions库安装到了指定的位置,现在为了生成.cmake文件,我们需要在MathFunctions/CMakeLitsts.txt中将install命令更改如下:
install(TARGETS MathFunctions
DESTINATION lib
EXPORT MathFunctionsTargets)
这个命令的意思是:将MathFunctions安装在/usr/local/lib下,然后将有关库的信息export为MathFunctionsTargets
既然得到了MathFunctionsTargets,那么我们就利用其生成.cmake文件并安装,在 CMakeLists.txt中增加如下命令:
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions
)
这时,如果我们去运行cmake的时候,会报出如下错误:
这个错误的意思是:当export的时候会包含一个与本地机器绑定的一个路径,而这个路径与其他的机器并不匹配,而解决这个的方法就是在为MathFunctions库进行target_include_directories的时候让他知道当从build路径下被使用或者从package安装的位置被使用的时候需要不同的接口位置,因此更改此命令为:
target_include_directories(MathFunctions
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
现在我们已经打包了MathFunctions的信息,但是我们仍然需要一个MathFunctionsConfig.cmake文件来让find_package()命令能够找到我们的工程,这里我理解是find_package()只能找到固定命名类型的.cmake文件(参考上面的链接),这里生成 MathFunctionsConfig.cmake文件的目的是让find_package通过配置文件找到真正所需要的MathFunctionsTargets.cmake文件.
所以我们需要新建一个Config.cmake.in文件,然后使用cmake命令将其转为MathFunctionsConfig.cmake文件,Config.cmake.in文件的内容如下:
@PACKAGE_INIT@
include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
之后我们在CMakeLists.txt中添加以下命令
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
INSTALL_DESTINATION "lib/cmake/example"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
DESTINATION lib/cmake/MathFunctions
)
- include的作用是包含构造Config相关的工具
- configure_package_config_file是将Config.cmake.in配置成我们需要的MathFunctionsConfig.cmake文件
- write_basic_package_version_file是生成工程版本信息的.cmake文件
- install是将MathFunctionsConfig.cmake文件安装到指定位置
然后执行操作测验
mkdir build_Step5
cd build_Step5
cmake ../Step5
cmake --build .
cmake --install .
可以看到相关的文件被安装到:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)