使用 Meson 创建你的第一个 Conan 包

创建你的第一个 Conan 包教程 中,CMake 被用作构建系统。如果你还没有阅读该部分,请先阅读它以熟悉 conanfile.pytest_package 的概念,然后再回来阅读关于 Meson 包创建的具体细节。

使用 conan new 命令创建一个 “Hello World” C++ 库示例项目

$ conan new meson_lib -d name=hello -d version=1.0

这将创建一个具有以下结构的 Conan 包项目。

├── conanfile.py
├── meson.build
├── hello.vcxproj
├── src
│   ├── hello.h
│   └── hello.cpp
└── test_package
    ├── conanfile.py
    ├── meson.build
    └── src
        └── example.cpp

该结构和文件与之前的 CMake 示例非常相似

  • conanfile.py: 在根文件夹中,有一个 conanfile.py,它是主要的配方文件,负责定义如何构建和使用包。

  • meson.build: 一个 Meson 构建脚本。此脚本不需要包含任何特定于 Conan 的内容,它完全与 Conan 无关,因为集成是透明的。

  • src 文件夹: 包含简单的 C++ “hello” 库的文件夹。

  • test_package 文件夹: 包含一个 example 应用程序,它将需要并链接到创建的包。在本例中,test_package 也包含一个 meson.build,但如果需要,test_package 也可以使用其他构建系统,如 CMake。test_package 使用与包相同的构建系统不是强制性的。

让我们看一下包配方 conanfile.py (仅限相关新部分)

exports_sources = "meson.build", "src/*"

def layout(self):
    basic_layout(self)

def generate(self):
    tc = MesonToolchain(self)
    tc.generate()

def build(self):
    meson = Meson(self)
    meson.configure()
    meson.build()

def package(self):
    meson = Meson(self)
    meson.install()

让我们简要解释一下配方的不同部分

  • layout() 定义了一个 basic_layout(),它不如 CMake 的灵活,因此不允许任何参数化。

  • generate() 方法调用 MesonToolchain,它可以为交叉构建生成 conan_meson_native.iniconan_meson_cross.ini Meson 工具链文件。如果项目有 Conan requires 依赖项,它也应该添加 PkgConfigDeps

  • build() 方法使用 Meson() 助手来驱动构建

  • package() 方法使用 Meson 安装功能来定义最终工件并将其复制到包文件夹。

test_package 文件夹还包含一个 meson.build 文件,该文件声明了对被测包的依赖,并链接一个应用程序,以验证包是否已正确创建并包含该库

test_package/meson.build
project('Testhello', 'cpp')
hello = dependency('hello', version : '>=0.1')
executable('example', 'src/example.cpp', dependencies: hello)

请注意 test_package/conanfile.py 也包含 generators = "PkgConfigDeps", "MesonToolchain",因为 test_package 将 “hello” 包作为依赖项,并且需要 PkgConfigDeps 来定位它。

注意

此示例假设系统已安装 Meson、Ninja 和 PkgConfig,但情况并非总是如此。如果未安装它们,你可以创建一个包含以下内容的配置文件 myprofile

include(default)

[tool_requires]
meson/[*]
pkgconf/[*]

我们添加了 Mesonpkg-config 作为 配置文件的工具需求。通过执行 conan create . -pr=myprofile,这些工具将被安装并在包的构建过程中可用。

让我们使用当前的默认配置从源代码构建包,然后让 test_package 文件夹测试该包

$ conan create .

...
======== Testing the package: Executing test ========
hello/1.0 (test package): Running test()
hello/1.0 (test package): RUN: .\example
hello/1.0: Hello World Release!
  hello/1.0: _M_X64 defined
  hello/1.0: MSVC runtime: MultiThreadedDLL
  hello/1.0: _MSC_VER1939
  hello/1.0: _MSVC_LANG201402
  hello/1.0: __cplusplus201402
hello/1.0 test_package

我们现在可以验证配方和包二进制文件是否在缓存中

$ conan list "hello/1.0:*"
Local Cache:
  hello
    hello/1.0
      revisions
        856c535669f78da11502a119b7d8a6c9 (2024-03-04 17:52:39 UTC)
          packages
            c13a22a41ecd72caf9e556f68b406569547e0861
              info
                settings
                  arch: x86_64
                  build_type: Release
                  compiler: msvc
                  compiler.cppstd: 14
                  compiler.runtime: dynamic
                  compiler.runtime_type: Release
                  compiler.version: 193
                  os: Windows