C++ Conan/vcpkg:包管理工具在 C++ 项目中的实践

好的,各位观众老爷们,今天咱们聊聊C++项目里那些让你又爱又恨的包管理工具,Conan和vcpkg。别怕,这俩家伙其实没那么吓人,掌握了它们,你的C++项目开发效率能像火箭一样嗖嗖地往上窜。

开场白:C++的依赖地狱

话说C++这门语言,那是既强大又灵活,但项目一大,依赖关系一复杂,那酸爽,谁用谁知道。想象一下,你的项目要用到几十个第三方库,每个库又有自己的依赖,版本冲突、编译选项不一致……光是解决这些依赖问题,就能让你掉光头发。

所以,包管理工具就应运而生了。它们的作用嘛,简单来说,就是帮你自动管理项目依赖,包括下载、编译、安装、版本控制等等。有了它们,你就可以把更多精力放在编写业务逻辑上,而不是和那些该死的依赖问题死磕。

主角登场:Conan和vcpkg

C++界流行的包管理工具有不少,今天咱们重点聊聊Conan和vcpkg。

  • Conan: 一个去中心化的、开源的C++包管理器。它可以管理任何平台上的C++库,并且支持多种构建系统(CMake、Make、Visual Studio等等)。Conan的特点是灵活性强,可以自定义各种配置,但上手难度也相对较高。

  • vcpkg: 微软开发的开源C++包管理器。它的特点是简单易用,集成性好,尤其是在Windows平台上。vcpkg的库相对较少,但常用的库基本都有。

Conan:灵活的瑞士军刀

咱们先来看看Conan。Conan的设计理念是“定义一切皆代码”,也就是说,你可以用Python代码来定义你的包、依赖关系、构建过程等等。这使得Conan非常灵活,但也增加了一定的学习成本。

1. 安装Conan

首先,你得先安装Conan。如果你已经安装了Python和pip,那么直接在命令行里输入:

pip install conan

搞定!

2. 创建一个简单的Conan项目

接下来,咱们创建一个简单的Conan项目。首先,创建一个目录,比如叫my_conan_project,然后在里面创建一个conanfile.txt文件。这个文件就是Conan项目的核心,它定义了项目的依赖关系、构建选项等等。

[requires]
fmt/8.1.1

[generators]
CMakeDeps
CMakeToolchain

这个conanfile.txt文件表示:

  • [requires]:项目依赖于fmt库,版本为8.1.1fmt是一个流行的C++格式化库,用起来比printf舒服多了。
  • [generators]:生成CMake依赖文件和工具链文件。Conan可以生成各种构建系统的依赖文件,方便你在不同的构建系统中使用。

3. 构建项目

创建好conanfile.txt之后,就可以开始构建项目了。首先,在my_conan_project目录下创建一个CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.15)
project(MyConanProject)

find_package(fmt REQUIRED)

add_executable(my_program main.cpp)
target_link_libraries(my_program fmt::fmt)

这个CMakeLists.txt文件表示:

  • find_package(fmt REQUIRED):查找fmt库。
  • target_link_libraries(my_program fmt::fmt):将fmt库链接到my_program可执行文件。

然后,创建一个main.cpp文件:

#include <iostream>
#include <fmt/format.h>

int main() {
  std::cout << fmt::format("Hello, {}!", "Conan") << std::endl;
  return 0;
}

这个main.cpp文件使用了fmt库来格式化输出。

现在,就可以用Conan来构建项目了。在my_conan_project目录下,执行以下命令:

conan install . --build missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build

这些命令的意思是:

  • conan install . --build missing:安装项目依赖。--build missing表示如果依赖库没有预编译好的二进制包,就从源码编译。
  • cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release:使用CMake配置项目。-DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake指定使用Conan生成的工具链文件。
  • cmake --build build:构建项目。

构建完成后,你就可以在build目录下找到生成的可执行文件my_program。运行它,你就能看到熟悉的“Hello, Conan!”。

4. Conan进阶:conanfile.py

conanfile.txt虽然简单,但功能有限。如果你需要更灵活的配置,可以使用conanfile.py文件。conanfile.py是一个Python脚本,你可以用它来定义更复杂的依赖关系、构建选项等等。

下面是一个conanfile.py的例子:

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps
from conan.tools.files import copy, rmdir
import os

class MyConanProjectConan(ConanFile):
    name = "my_conan_project"
    version = "0.1"
    settings = "os", "compiler", "build_type", "arch"
    requires = "fmt/8.1.1"
    generators = "CMakeDeps", "CMakeToolchain"
    exports_sources = "CMakeLists.txt", "main.cpp"

    def layout(self):
        self.folders.build = "build"
        self.folders.generators = "build/conan"

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["my_conan_project"]

这个conanfile.py文件定义了:

  • name:项目名称。
  • version:项目版本。
  • settings:构建选项,包括操作系统、编译器、构建类型、架构等等。
  • requires:项目依赖。
  • generators:生成器。
  • exports_sources:需要导出的源代码文件。
  • layout:定义构建目录和生成器目录。
  • build:构建项目。
  • package:打包项目。
  • package_info:定义包的信息。

使用conanfile.py构建项目的步骤和使用conanfile.txt类似,只是把conanfile.txt替换成conanfile.py即可。

5. Conan总结

Conan的优点:

  • 灵活: 可以自定义各种配置,满足各种需求。
  • 跨平台: 支持多种平台和构建系统。
  • 去中心化: 可以使用自己的私有仓库。

Conan的缺点:

  • 上手难度高: 需要学习Conan的DSL和Python。
  • 配置复杂: 复杂的项目需要编写大量的配置文件。

vcpkg:简单易用的傻瓜相机

接下来,咱们来看看vcpkg。vcpkg的设计理念是“开箱即用”,也就是说,你只需要简单的几步操作,就可以安装和使用第三方库。

1. 安装vcpkg

首先,你得先安装vcpkg。vcpkg的安装比较简单,只需要从GitHub上克隆仓库,然后运行bootstrap-vcpkg.bat(Windows)或bootstrap-vcpkg.sh(Linux/macOS)脚本即可。

git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh  # 或者 bootstrap-vcpkg.bat

2. 安装第三方库

安装好vcpkg之后,就可以安装第三方库了。比如,要安装fmt库,只需要在命令行里输入:

./vcpkg install fmt

vcpkg会自动下载、编译和安装fmt库。

3. 在CMake项目中使用vcpkg

要在CMake项目中使用vcpkg,需要在CMakeLists.txt文件中添加以下代码:

cmake_minimum_required(VERSION 3.15)
project(MyVcpkgProject)

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file")

find_package(fmt REQUIRED)

add_executable(my_program main.cpp)
target_link_libraries(my_program fmt::fmt)

这段代码的关键是set(CMAKE_TOOLCHAIN_FILE ...),它指定了vcpkg的工具链文件。有了这个工具链文件,CMake就可以找到vcpkg安装的第三方库。

然后,创建一个main.cpp文件:

#include <iostream>
#include <fmt/format.h>

int main() {
  std::cout << fmt::format("Hello, {}!", "vcpkg") << std::endl;
  return 0;
}

接下来,就可以用CMake来构建项目了:

cmake -B build
cmake --build build

构建完成后,你就可以在build目录下找到生成的可执行文件my_program。运行它,你就能看到熟悉的“Hello, vcpkg!”。

4. vcpkg集成Visual Studio

vcpkg和Visual Studio的集成非常方便。只需要运行以下命令:

./vcpkg integrate install

vcpkg会自动配置Visual Studio,使得你可以直接在Visual Studio中使用vcpkg安装的第三方库。

5. vcpkg总结

vcpkg的优点:

  • 简单易用: 只需要简单的几步操作,就可以安装和使用第三方库。
  • 集成性好: 和Visual Studio的集成非常方便。
  • 上手快: 不需要学习复杂的DSL和Python。

vcpkg的缺点:

  • 库相对较少: 和Conan相比,vcpkg的库数量较少。
  • 配置选项有限: 无法自定义复杂的构建选项。
  • 灵活性差: 不如Conan灵活。

Conan vs vcpkg:该选哪个?

Conan和vcpkg各有优缺点,选择哪个取决于你的具体需求。

特性 Conan vcpkg
灵活性 非常高,可以自定义各种配置 较低,配置选项有限
易用性 较难,需要学习Conan的DSL和Python 简单,开箱即用
库的数量 较多 较少
跨平台性 很好,支持多种平台和构建系统 较好,主要针对Windows和Linux
社区支持 活跃,但相对分散 活跃,背后有微软支持
适用场景 复杂项目,需要高度自定义配置的项目 简单项目,快速上手,或者Windows平台项目

总的来说:

  • 如果你需要高度自定义的配置,或者你的项目非常复杂,或者你需要支持多种平台和构建系统,那么Conan可能更适合你。
  • 如果你希望快速上手,或者你的项目比较简单,或者你主要在Windows平台上开发,那么vcpkg可能更适合你。

当然,你也可以同时使用Conan和vcpkg。比如,你可以用Conan来管理一些复杂的依赖,用vcpkg来管理一些常用的依赖。

包管理最佳实践

除了选择合适的包管理工具之外,还有一些包管理最佳实践可以帮助你更好地管理C++项目依赖:

  • 明确依赖关系: 在项目开始之前,就要明确项目的依赖关系,并选择合适的包管理工具。
  • 版本控制: 使用版本控制系统(如Git)来管理项目依赖的版本。
  • 使用私有仓库: 如果你的项目依赖于一些私有库,可以使用Conan的私有仓库功能。
  • 定期更新依赖: 定期更新项目依赖,以修复安全漏洞和bug。
  • 避免循环依赖: 循环依赖会导致构建失败,要尽量避免。
  • 使用语义化版本: 使用语义化版本(Semantic Versioning)来管理项目依赖的版本,可以避免版本冲突。
  • 锁定依赖版本: 在生产环境中,要锁定依赖版本,以保证构建的可重复性。

总结:告别依赖地狱,拥抱美好未来

Conan和vcpkg都是强大的C++包管理工具,掌握它们可以让你告别依赖地狱,提高开发效率。选择哪个工具取决于你的具体需求,但无论选择哪个,都要遵循包管理最佳实践,才能更好地管理C++项目依赖。

好了,今天的讲座就到这里。希望对大家有所帮助。如果大家有什么问题,欢迎在评论区留言。咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注