IDE 集成

Meson 为 Visual Studio 和 XCode 提供了导出器,但为每个 IDE 都编写自定义后端不是一种可扩展的方法。为了解决这个问题,Meson 提供了一个 API,使任何 IDE 或构建工具都可以轻松地集成 Meson 构建,并提供与 IDE 原生解决方案相当的体验。

在构建目录的 meson-info 目录中可以找到 IDE 集成所需的所有资源。

在 IDE 中设置 Meson 项目时,首先要做的是选择源目录和构建目录。对于此示例,我们假设源代码位于名为 workspace/project 的类似 Eclipse 的目录中,构建树嵌套在其中,例如 workspace/project/build。首先,我们通过在源目录中运行以下命令来初始化 Meson。

meson setup builddir

使用此命令,Meson 将配置项目,还会生成存储在 meson-info 目录中的 intro-*.json 文件中的自省信息。在 (重新) 配置 Meson 或构建选项发生更改时,自省转储将自动更新。因此,IDE 可以监视此目录中的更改以了解何时发生了更改。请注意,meson-info.json 保证是最后一个写入的文件。

meson-info 目录应包含以下文件

文件 描述
intro-benchmarks.json 列出所有基准测试
intro-buildoptions.json 包含项目的 Meson 配置选项的完整列表
intro-buildsystem_files.json 所有 Meson 构建文件的完整列表
intro-dependencies.json 列出项目中使用的所有依赖项
intro-installed.json 包含文件与其安装位置的映射
intro-install_plan.json 包含数据类型的字典,以及源文件及其安装详细信息
intro-projectinfo.json 存储有关项目的基本信息(名称、版本等)
intro-targets.json 所有构建目标的完整列表
intro-tests.json 列出所有测试,以及如何运行它们的说明

JSON 文件的内容将在本文档的其余部分中进一步说明。

targets 部分

对于 IDE 来说,最重要的文件可能是 intro-targets.json。这里指定了每个目标及其源代码和编译器参数。一个目标的 JSON 格式定义如下

{
    "name": "Name of the target",
    "id": "The internal ID meson uses",
    "type": "<TYPE>",
    "defined_in": "/Path/to/the/targets/meson.build",
    "subproject": null,
    "filename": ["list", "of", "generated", "files"],
    "build_by_default": true / false,
    "target_sources": [],
    "extra_files": ["/path/to/file1.hpp", "/path/to/file2.hpp"],
    "installed": true / false,
}

如果 installed 键设置为 true,则 install_filename 键也将存在。它存储 filename 中每个文件的安装位置。如果 filename 中的一个文件未安装,则其对应的安装位置将设置为 null

subproject 键指定定义此目标的子项目的名称,如果目标在顶级项目中定义,则为 null

(0.56.0 中新增) extra_files 键列出通过构建目标的 extra_files 关键字参数指定的所有文件。参见 executable().

一个目标通常只生成一个文件。但是,自定义目标可能具有多个输出。

目标源代码

intro-targets.json 文件还存储 target_sources 中目标所有源对象列表。使用此信息,IDE 可以为所有源文件提供代码补全功能。

{
    "language": "language ID",
    "compiler": ["The", "compiler", "command"],
    "parameters": ["list", "of", "compiler", "parameters"],
    "sources": ["list", "of", "all", "source", "files", "for", "this", "language"],
    "generated_sources": ["list", "of", "all", "source", "files", "that", "where", "generated", "somewhere", "else"]
}

应该注意的是,存储在 parameters 中的编译器参数与用于编译文件的实际参数不同。这是因为参数针对 IDE 中的用法进行了优化,以提供自动完成支持等。因此,不建议使用此自省信息进行实际编译。

type 的可能值

下表显示了目标的所有有效类型。

type 的值 描述
executable 此目标将生成一个可执行文件
static library 静态库的目标
shared library 共享库的目标
shared module 一个共享库,旨在与 dlopen 一起使用,而不是链接到其他内容
custom 一个自定义目标
run 一个 Meson 运行目标
jar 一个 Java JAR 目标

安装计划

intro-install_plan.json 文件包含一个将要安装到系统上的文件的列表。

数据包含按数据类型分组的文件列表。每个文件映射到一个字典,其中包含 destinationtag 键,键是构建时的文件位置。destination 是使用基本目录占位符的目的地路径。将来可能会添加新键。

{
    "targets": {
        "/path/to/project/builddir/some_executable": {
            "destination": "{bindir}/some_executable",
            "tag": "runtime"
        },
        "/path/to/project/builddir/libsomelib.so": {
            "destination": "{libdir_shared}/libsomelib.so",
            "tag": "runtime"
        }
    },
    "data": {
        "/path/to/project/some_data": {
            "destination": "{datadir}/some_data",
            "tag": null
        }
    },
    "headers": {
        "/path/to/project/some_header.h": {
            "destination": "{includedir}/some_header.h",
            "tag": "devel"
        }
    }
}

此外,intro-installed.json 文件包含构建时文件路径到绝对系统位置的映射。

{
    "/path/to/project/builddir/some_executable": "/usr/bin/some_executable",
    "/path/to/project/builddir/libsomelib.so": "/user/lib/libsomelib.so",
    "/path/to/project/some_data": "/usr/share/some_data",
    "/path/to/project/some_header.h": "/usr/include/some_header.h"
}

使用 --targets 但不使用构建目录

也可以在没有构建目录的情况下获取大多数目标。这可以通过运行 meson introspect --targets /path/to/meson.build 来完成。

生成的输出类似于使用构建目录运行自省或读取 intro-targets.json。但是,有一些关键差异

  • filename 中的路径现在相对于将来的构建目录
  • install_filename 键完全丢失
  • target_sources 中只有一个条目
    • 语言设置为 unknown
    • compilerparameters 以及 generated_sources 的空列表
    • sources 列表应该包含目标的所有源代码

不能保证 target_sources 中的源代码列表是正确的。由于内部限制,可能存在差异。也不能保证所有目标都将列在输出中。甚至可能存在目标,在正常运行 Meson 时这些目标不存在。如果在 if 语句中定义了一个目标,就会发生这种情况。谨慎使用此功能。

构建选项

所有构建选项(构建类型、警告级别等)的列表存储在 intro-buildoptions.json 文件中。以下是每个选项的 JSON 格式。

{
    "name": "name of the option",
    "description": "the description",
    "type": "type ID",
    "value": "value depends on type",
    "section": "section ID",
    "machine": "machine ID"
}

支持的类型为

  • string
  • boolean
  • combo
  • integer
  • array

对于类型 combochoices 键也存在。这里存储了选项的所有有效值。

section 的可能值为

  • core
  • backend
  • base
  • compiler
  • directory
  • user
  • test

machine 键指定选项的机器配置。可能的值为

  • any
  • host
  • build

要设置选项,请使用 meson configure 命令。

从 Meson 0.50.0 开始,也可以通过将根 meson.build 而不是构建目录提供给 meson introspect --buildoptions 来获取默认的构建选项,而无需构建目录。

在没有构建目录的情况下运行 --buildoptions 会产生与使用新配置的构建目录运行它相同的输出。

但是,如果存在子项目,则此行为不能保证。由于内部限制,即使在实际的 Meson 运行中从未使用过,也会处理所有子项目。因此,子项目的选项可能会有所不同。

依赖项部分

所有已找到依赖项的列表可以从 intro-dependencies.json 中获取。这里列出了依赖项的名称、版本、编译器和链接器参数。

使用 --scan-dependencies 扫描依赖项

也可以在没有构建目录的情况下获取大多数使用的依赖项。这可以通过运行 meson introspect --scan-dependencies /path/to/meson.build 来完成。

输出格式如下

[
  {
    "name": "The name of the dependency",
    "required": true,
    "version": [">=1.2.3"],
    "conditional": false,
    "has_fallback": false
  }
]

required 关键字指定依赖项是否在 meson.build 中标记为必需(默认情况下,所有依赖项都是必需的)。conditional 键指示 dependency() 函数是否在条件块内调用。在实际的 Meson 运行中,这些依赖项可能不会被使用,因此即使设置了 required 键,它们可能不是必需的。has_fallback 键只是指示是否在 dependency() 函数中直接设置了回退。version 键始终包含来自 meson.build 的版本要求列表,而不是磁盘上依赖项的实际版本。如果 meson.build 中没有指定任何版本,则版本列表为空。

测试

编译和单元测试通过运行 meson compilemeson test 命令来完成。可以在 workspace/project/builddir/meson-logs/testlog.json 中找到 JSON 格式的结果日志。

当这些测试失败时,用户可能希望在调试器中运行失败的测试。为了尽可能地集成,请从 intro-tests.jsonintro-benchmarks.json 文件中提取测试。这将为您提供运行测试所需的所有信息:要执行的命令、命令行参数、环境变量设置以及如何处理输出。

{
    "name": "name of the test",
    "workdir": "the working directory (can be null)",
    "timeout": "the test timeout",
    "suite": ["list", "of", "test", "suites"],
    "is_parallel": true / false,
    "protocol": "exitcode" / "tap",
    "cmd": ["command", "to", "run"],
    "depends": ["target1-id", "target2-id"],
    "env": {
        "VARIABLE1": "value 1",
        "VARIABLE2": "value 2"
    }
}

depends 条目(自 0.56.0 起) 包含目标 ID;它们可以在目标自省数据中查找。cmd 指向的可执行文件也包含在条目中,以及任何作为构建产品的测试参数。

构建系统文件

也可以获取当前项目中使用的 Meson 构建文件。这可以通过运行 meson introspect --buildsystem-files /path/to/builddir 来完成。

输出格式如下

[
    "/Path/to/the/targets/meson.build",
    "/Path/to/the/targets/meson.options",
    "/Path/to/the/targets/subdir/meson.build"
]

编程接口

Meson 还通过命令行提供了用于项目自省的 meson introspect。使用 meson introspect -h 查看所有可用选项。

此 API 也可以在没有构建目录的情况下使用 --projectinfo 命令。

meson.build 的 AST

从 Meson 0.55.0 开始,可以将 meson.build 的 AST 作为 JSON 对象转储。此接口为 meson introspect --ast /path/to/meson.build

AST 的每个节点至少包含以下条目

描述
node 节点的类型(见下表)
lineno 节点在文件中的行号
colno 节点在文件中的列号
end_lineno 标记节点的结尾(可能与 lineno 相同)
end_colno 标记节点的结尾(可能与 colno 相同)

node 的可能值,以及其他键

节点类型 其他键
BooleanNode value: bool
IdNode value: str
NumberNode value: int
StringNode value: str
ContinueNode
BreakNode
ArgumentNode positional: 节点列表;kwargs: accept_kwargs
ArrayNode args: 节点
DictNode args: 节点
EmptyNode
OrNode left: 节点;right: 节点
AndNode left: 节点;right: 节点
ComparisonNode left: 节点;right: 节点;ctype: str
ArithmeticNode left: 节点;right: 节点;op: str
NotNode right: 节点
CodeBlockNode lines: 节点列表
IndexNode object: 节点;index: 节点
MethodNode object: 节点;args: 节点;name: str
FunctionNode args: 节点;name: str
AssignmentNode value: 节点; var_name: 字符串
PlusAssignmentNode value: 节点; var_name: 字符串
ForeachClauseNode items: 节点; block: 节点; varnames: 列表
IfClauseNode ifs: 节点列表; else: 节点
IfNode condition: 节点; block: 节点
UMinusNode right: 节点
TernaryNode condition: 节点; true: 节点; false: 节点

我们不保证此格式的稳定性,因为它与 Meson 内部 AST 密切相关。但是,重大更改(删除节点类型或删除键)不太可能发生,并且将在发布说明中宣布。

JSON 参考手册

除了在线 参考手册 外,Meson 还提供 JSON 文件形式的手册。此文件的内容来自与在线文档相同的来源。因此,这两个版本在内容上是相同的。

此 JSON 文档自 0.60.0 版本开始附带在每个 Meson 版本中。JSON 模式由 jsonschema.py 中给出的类结构定义。

现有集成

搜索结果是