一、背景引入

在软件开发中,我们经常会用到各种工具来帮助我们更高效地完成项目。Conan和CMake Presets就是其中两个比较重要的工具。Conan是一个开源的C和C++包管理器,它可以帮助我们管理项目中的依赖项,就好比我们去超市购物,它能帮我们把需要的商品(依赖项)都准备好。而CMake Presets则是CMake的一个功能,它可以让我们更方便地配置项目的构建环境,就像是给我们的项目搭建一个合适的“工作间”。

但是,在实际使用过程中,我们可能会遇到一些问题,比如在CMake Presets中配置Conan依赖不生效。这就好比我们在超市里选好了商品,却发现怎么也带不回“工作间”。接下来,我们就一起看看如何解决这个问题,实现一体化的构建配置。

二、Conan和CMake Presets简介

1. Conan

Conan是一个专门为C和C++开发者设计的包管理器。它可以让我们轻松地管理项目中的依赖项,比如我们的项目需要用到某个开源库,我们只需要在Conan中配置好这个库的信息,Conan就会自动帮我们下载和安装。

示例(C++技术栈):

// 假设我们的项目需要使用OpenCV库
// 首先,我们需要在Conanfile.txt中配置OpenCV的依赖
[requires]
opencv/4.5.5

[generators]
cmake_find_package

在这个示例中,我们通过[requires]指定了需要的OpenCV版本,[generators]指定了生成的文件类型,这里选择了cmake_find_package,方便后续在CMake中使用。

2. CMake Presets

CMake Presets是CMake 3.19及以上版本引入的一个功能,它可以让我们通过JSON文件来配置项目的构建环境。我们可以在这个文件中定义不同的构建配置,比如不同的编译器、不同的构建类型(Debug、Release等)。

示例(C++技术栈):

{
    "version": 3,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 19,
        "patch": 0
    },
    "configurePresets": [
        {
            "name": "default",
            "displayName": "Default Configuration",
            "description": "Default configuration for the project",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        }
    ]
}

在这个示例中,我们定义了一个名为default的配置预设,指定了生成器为Ninja,构建目录为${sourceDir}/build,构建类型为Debug

三、Conan与CMake Presets集成的步骤

1. 安装Conan和CMake

首先,我们需要确保Conan和CMake已经安装在我们的系统中。可以通过以下命令来检查:

conan --version
cmake --version

如果没有安装,可以按照官方文档进行安装。

2. 创建Conanfile.txt

在项目根目录下创建Conanfile.txt文件,配置项目的依赖项。

[requires]
# 这里可以添加项目需要的依赖项,比如Boost库
boost/1.77.0

[generators]
cmake_find_package

3. 创建CMakePresets.json

在项目根目录下创建CMakePresets.json文件,配置项目的构建环境。

{
    "version": 3,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 19,
        "patch": 0
    },
    "configurePresets": [
        {
            "name": "default",
            "displayName": "Default Configuration",
            "description": "Default configuration for the project",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            },
            "environment": {
                "CONAN_REVISIONS_ENABLED": "1"
            }
        }
    ]
}

在这个配置中,我们添加了environment字段,设置了CONAN_REVISIONS_ENABLED1,这有助于Conan更好地管理依赖项的版本。

4. 配置CMakeLists.txt

在项目根目录下创建或修改CMakeLists.txt文件,添加Conan的相关配置。

cmake_minimum_required(VERSION 3.19)
project(MyProject)

# 查找Conan生成的文件
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})

# 包含Conan生成的配置文件
find_package(Boost REQUIRED)

# 添加可执行文件
add_executable(MyProject main.cpp)

# 链接依赖库
target_link_libraries(MyProject PRIVATE Boost::boost)

在这个示例中,我们通过find_package查找Conan生成的Boost库,并将其链接到我们的项目中。

四、解决CMake Presets中Conan依赖配置不生效问题

1. 问题分析

有时候,我们在CMake Presets中配置了Conan依赖,但在构建过程中却发现依赖项没有正确加载。这可能是由于以下原因:

  • Conan生成的文件路径没有正确配置。
  • Conan的环境变量没有正确设置。
  • CMake版本不兼容。

2. 解决方案

  • 检查Conan生成的文件路径:确保CMakeLists.txt中正确包含了Conan生成的文件路径。
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
  • 设置Conan环境变量:在CMakePresets.json中设置Conan的环境变量。
{
    "version": 3,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 19,
        "patch": 0
    },
    "configurePresets": [
        {
            "name": "default",
            "displayName": "Default Configuration",
            "description": "Default configuration for the project",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            },
            "environment": {
                "CONAN_REVISIONS_ENABLED": "1",
                "CONAN_USER_HOME": "/path/to/conan/home"
            }
        }
    ]
}
  • 检查CMake版本:确保使用的CMake版本支持CMake Presets功能,建议使用3.19及以上版本。

五、一体化构建配置示例

1. 完整项目结构

MyProject/
├── CMakeLists.txt
├── CMakePresets.json
├── Conanfile.txt
└── main.cpp

2. 详细代码示例

Conanfile.txt

[requires]
boost/1.77.0

[generators]
cmake_find_package

CMakePresets.json

{
    "version": 3,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 19,
        "patch": 0
    },
    "configurePresets": [
        {
            "name": "default",
            "displayName": "Default Configuration",
            "description": "Default configuration for the project",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            },
            "environment": {
                "CONAN_REVISIONS_ENABLED": "1"
            }
        }
    ]
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(MyProject)

# 查找Conan生成的文件
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})

# 包含Conan生成的配置文件
find_package(Boost REQUIRED)

# 添加可执行文件
add_executable(MyProject main.cpp)

# 链接依赖库
target_link_libraries(MyProject PRIVATE Boost::boost)

main.cpp

#include <iostream>
#include <boost/version.hpp>

int main() {
    std::cout << "Boost version: " << BOOST_VERSION << std::endl;
    return 0;
}

3. 构建步骤

  1. 运行Conan安装依赖项:
conan install . --output-folder=build --build=missing
  1. 使用CMake Presets进行配置和构建:
cmake --preset default
cmake --build build
  1. 运行可执行文件:
./build/MyProject

六、应用场景

1. 大型项目开发

在大型的C++项目中,可能会有大量的依赖项,使用Conan可以方便地管理这些依赖项,而CMake Presets可以帮助我们快速配置不同的构建环境,提高开发效率。

2. 跨平台开发

当我们需要在不同的操作系统上进行开发时,Conan可以确保依赖项在不同平台上的一致性,CMake Presets可以根据不同的平台配置相应的构建环境。

七、技术优缺点

1. 优点

  • 依赖管理方便:Conan可以帮助我们轻松管理项目中的依赖项,避免手动下载和安装的麻烦。
  • 构建配置灵活:CMake Presets可以让我们通过JSON文件来配置不同的构建环境,方便快捷。
  • 跨平台支持:Conan和CMake都支持跨平台开发,可以在不同的操作系统上使用。

2. 缺点

  • 学习成本较高:Conan和CMake Presets都有一定的学习曲线,需要花费一定的时间来掌握。
  • 依赖项版本管理复杂:当项目中的依赖项较多时,管理依赖项的版本可能会比较复杂。

八、注意事项

  • 版本兼容性:确保Conan、CMake和项目中使用的依赖项版本相互兼容。
  • 环境变量设置:正确设置Conan和CMake的环境变量,避免出现依赖配置不生效的问题。
  • 文件路径管理:确保Conan生成的文件路径在CMakeLists.txt中正确配置。

九、文章总结

通过本文,我们了解了Conan和CMake Presets的基本概念和使用方法,以及如何将它们集成在一起。同时,我们也解决了CMake Presets中Conan依赖配置不生效的问题,并给出了一体化构建配置的示例。在实际开发中,我们可以根据项目的需求,灵活运用Conan和CMake Presets,提高开发效率和项目的可维护性。