- 使用系统提供的包(find_package)
- 将第三方库放在工程中(Vendoring code)
- 将${CMAKE_SOURCE_DIR}/cmake/modules路径添加到CMAKE_MODULE_PATH中
- 方法二
- 指定VTK的路径
- 指定Qt的路径
- list(APPEND CMAKE_PREFIX_PATH ${Qt5_DIR}) #如果CMAKE_PREFIX_PATH有多个,可以使用这个添加
- Prepare “Catch2” library for other executables
- .\CMakeLists.txt
- add the CMakeFile that defines catch2
- Add an library for the example classes
- Unit tests
- enable CTest testing
- Add a testing executable
- 将项目目录下的cmake文件夹加入到CMAKE_MODULE_PATH中,让find_pakcage能够找到我们自定义的函数库
- .\3rd_party\google-test\CMakeLists.txt.in
- Version bfc0ffc8a698072c794ae7299db9cb6866f4c0bc happens to be master when I set this up.
- To prevent an issue with accidentally installing GTest / GMock with your project you should use a
- commit after 9469fb687d040b60c8749b7617fee4e77c7f6409
- Note: This is after the release of v1.8
- # .\3rd_party\google-test\CMakeLists.txt
- Download and unpack googletest at configure time
- http://crascit.com/2015/07/25/cmake-gtest/">See: http://crascit.com/2015/07/25/cmake-gtest/
- Call CMake to download and Google Test
- Build the downloaded google test
- Prevent overriding the parent project’s compiler/linker
- settings on Windows
- Prevent installation of GTest with your project
- Add googletest directly to our build. This defines
- the gtest and gtest_main targets.
- This is a bit of a hack that can be used to get gtest libraries to build in C++11 if you aren’t using CMAKE_CXX_STANDARD
- set(CXX11_FEATURES
- cxx_nullptr
- cxx_auto_type
- cxx_delegating_constructors
- )
- target_compile_features(gtest
- PRIVATE
- ${CXX11_FEATURES}
- )
- target_compile_features(gmock_main
- PRIVATE
- ${CXX11_FEATURES}
- )
- target_compile_features(gmock
- PRIVATE
- ${CXX11_FEATURES}
- )
- target_compile_features(gmock_main
- PRIVATE
- ${CXX11_FEATURES}
- )
- Add aliases for GTest and GMock libraries
对于C++和CMake,目前还没有被普遍接受的管理、打包依赖库的方法。然而,近几年出现了一些新的有趣的包管理系统。
虽然这些系统,对于CMake而言,是一个独立的系统,但它们大多数都被集成到了CMake的构建系统中。
相关链接
- https://github.com/ttroy50/cmake-examples.git中的示例7(07-package-management)
- find_package
使用系统提供的包(find_package)
使用系统提供的包是最古老、最常见的包管理解决方案之一。
使用步骤:
- 您可以使用系统包安装程序(例如apt、yum)将库和头文件安装到最常见的位置
- 然后可以使用
find_package
函数来搜索这些内容
附:CMake官方为我们预定义了许多寻找依赖包的Module
- 它们存储在
<path_to_your_cmake>/share/cmake-<version>/Modules
目录下,以Find<LibraryName>.cmake
命名的文件都可以帮我们找到对应的包 - 查看官方为我们定义了哪些包(官方文档:Find Modules)
将第三方库放在工程中(Vendoring code)
Vendoring code意味着将第三方库存储在仓库中,并将其作为项目的一部分进行构建。
添加CMake已经安装好的包(find_package)
经过CMake安装过的包,它们会自带Find<LibraryName>.cmake
文件,这些文件能够让CMake找到对应的包
而我们要做的就是
- 手动指定
Find<LibraryName>.cmake
所在目录 - 使用
find_package
即可
附:在CMake脚本中指定模块目录(即CMAKE_MODULE_PATH
目录)
- CMake会去
CMAKE_MODULE_PATH
下搜索Find<LibraryName>.cmake
文件 ```将${CMAKE_SOURCE_DIR}/cmake/modules路径添加到CMAKE_MODULE_PATH中
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules${CMAKE_MODULE_PATH})
方法二
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
<a name="nqLHp"></a>
#### 例子:指定VTK的路径
指定VTK的路径
set(VTK_DIR D:\3rdparty\vtk-9.0.1\lib\cmake\vtk-9.0) SET(CMAKE_INCLUDE_CURRENT_DIR ON) #启用当前目录
<a name="TRRxK"></a>
#### 例子:指定Qt的路径
指定Qt的路径
set(Qt5_DIR C:\Qt\Qt5.15.2msvc2017_64) SET(CMAKE_PREFIX_PATH ${Qt5_DIR}) #Qt路径
list(APPEND CMAKE_PREFIX_PATH ${Qt5_DIR}) #如果CMAKE_PREFIX_PATH有多个,可以使用这个添加
SET(CMAKE_INCLUDE_CURRENT_DIR ON) #启用当前目录
<a name="S2Oj5"></a>
### 第三方库不支持CMake,自己编写CMake文件
有一些第三方库本身不支持CMake,或者是你编译时,忘记install了<br />此时,我们可以手动编写CMake文件,让我们的CMake能够发现它
<a name="a3cFK"></a>
#### 例:编写CMakeLists.txt(catch2)
> 例子链接:[https://github.com/ttroy50/cmake-examples.git](https://github.com/ttroy50/cmake-examples.git)中,05-unit-testing\catch2-vendored
将catch2放到仓库中
. ├── 3rd_party │ └── catch2 │ ├── catch2 │ │ └── catch.hpp │ └── CMakeLists.txt ├── CMakeLists.txt └── src ├── … └── example.cpp
实际上catch2的源代码只有一个头文件catch2.hpp,这种情况下,我们可以自己编写CMakeLists.txt
.\3rd_party\catch2\CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(catch2)
Prepare “Catch2” library for other executables
add_library(Catch2 INTERFACE) add_library(Catch2::Test ALIAS Catch2) target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
然后在顶部的CMake文件中加入此模块
.\CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project (catch2_unit_test)
set(CMAKE_CXX_STANDARD 11)
add the CMakeFile that defines catch2
add_subdirectory(3rd_party/catch2)
Add an library for the example classes
add_library(example_unit_test example.cpp )
#
Unit tests
enable CTest testing
enable_testing()
Add a testing executable
add_executable(unit_tests unit_tests.cpp)
target_link_libraries(unit_tests example_unit_test Catch2::Test )
add_test(test_all unit_tests)
<a name="QoVsh"></a>
#### 例:自己编写Find<PackageName>.cmake
假设我们编写了一个新的函数库,我们希望别的项目可以通过find_package对它进行引用我们应该怎么办呢。
1. FindAdd.cmake
```powershell
# 定义Add模块的Include_Dir
find_path(ADD_INCLUDE_DIR
libadd.h #文件名
#多个搜索路径
/usr/include/
/usr/local/include
${CMAKE_SOURCE_DIR}/ModuleMode
)
#搜索包含某个文件的路径
# 定义Add模块的Lib目录
find_library(ADD_LIBRARY #Add库的Lib目录
NAMES #lib文件名称
add
PATHS #搜索路径
/usr/lib/add
/usr/local/lib/add
${CMAKE_SOURCE_DIR}/ModuleMode
)
- 使用
```powershell
将项目目录下的cmake文件夹加入到CMAKE_MODULE_PATH中,让find_pakcage能够找到我们自定义的函数库
set(CMAKE_MODULE_PATH “${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}”)
add_executable(addtest addtest.cc)
find_package(ADD) if(ADD_FOUND) target_include_directories(addtest PRIVATE ${ADD_INCLUDE_DIR}) target_link_libraries(addtest ${ADD_LIBRARY}) else(ADD_FOUND) message(FATAL_ERROR “ADD library not found”) endif(ADD_FOUND)
<a name="GreEN"></a>
## 外部工程
CMake支持使用[External Project](https://cmake.org/cmake/help/latest/module/ExternalProject.html)命令下载和构建一个外部项目
- 通过ExternalProject_Add命令,让CMake自动从HTTP或源代码控制系统(如Git)中下载一个源文件
- 一旦配置好,外部项目将生成一个自定义目标,该目标可用于控制外部项目的下载、更新、构建、测试和安装阶段
<a name="JaNLd"></a>
##### 例:使用Google Test
> 例子完整链接:[https://github.com/ttroy50/cmake-examples.git](https://github.com/ttroy50/cmake-examples.git)中,05-unit-testing\google-test-download
. ├── 3rd_party │ └── google-test │ ├── CMakeLists.txt │ └── CMakeLists.txt.in ├── CMakeLists.txt ├── Reverse.h ├── Reverse.cpp ├── Palindrome.h ├── Palindrome.cpp ├── unit_tests.cpp
.\3rd_party\google-test\CMakeLists.txt.in
cmake_minimum_required(VERSION 3.0)
project(googletest-download NONE)
include(ExternalProject)
Version bfc0ffc8a698072c794ae7299db9cb6866f4c0bc happens to be master when I set this up.
To prevent an issue with accidentally installing GTest / GMock with your project you should use a
commit after 9469fb687d040b60c8749b7617fee4e77c7f6409
Note: This is after the release of v1.8
ExternalProject_Add(googletest URL https://github.com/google/googletest/archive/bfc0ffc8a698072c794ae7299db9cb6866f4c0bc.tar.gz SOURCE_DIR “${CMAKE_CURRENT_BINARY_DIR}/googletest-src” BINARY_DIR “${CMAKE_CURRENT_BINARY_DIR}/googletest-build” CONFIGURE_COMMAND “” BUILD_COMMAND “” INSTALL_COMMAND “” TEST_COMMAND “” )
# .\3rd_party\google-test\CMakeLists.txt
Download and unpack googletest at configure time
See: http://crascit.com/2015/07/25/cmake-gtest/
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
Call CMake to download and Google Test
execute_process(COMMAND ${CMAKE_COMMAND} -G “${CMAKE_GENERATOR}” . RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR “CMake step for googletest failed: ${result}”) endif()
Build the downloaded google test
execute_process(COMMAND ${CMAKE_COMMAND} —build . RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR “Build step for googletest failed: ${result}”) endif()
Prevent overriding the parent project’s compiler/linker
settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL “” FORCE)
Prevent installation of GTest with your project
set(INSTALL_GTEST OFF CACHE BOOL “” FORCE) set(INSTALL_GMOCK OFF CACHE BOOL “” FORCE)
Add googletest directly to our build. This defines
the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build)
This is a bit of a hack that can be used to get gtest libraries to build in C++11 if you aren’t using CMAKE_CXX_STANDARD
#
set(CXX11_FEATURES
cxx_nullptr
cxx_auto_type
cxx_delegating_constructors
)
target_compile_features(gtest
PRIVATE
${CXX11_FEATURES}
)
#
target_compile_features(gmock_main
PRIVATE
${CXX11_FEATURES}
)
#
target_compile_features(gmock
PRIVATE
${CXX11_FEATURES}
)
#
target_compile_features(gmock_main
PRIVATE
${CXX11_FEATURES}
)
Add aliases for GTest and GMock libraries
if(NOT TARGET GTest::GTest) add_library(GTest::GTest ALIAS gtest) add_library(GTest::Main ALIAS gtest_main) endif()
if(NOT TARGET GTest::GMock) add_library(GMock::GMock ALIAS gmock) add_library(GMock::Main ALIAS gmock_main) endif() ```
Conan
Conan是一个开源、去中心化、多平台的包管理器