IDE 整合

Meson 有 Visual Studio 和 XCode 的輸出器,但是為每個 IDE 撰寫自訂後端並非一個可擴展的方法。為了解決這個問題,Meson 提供了一個 API,讓任何 IDE 或建置工具都能輕鬆整合 Meson 建置,並提供與 IDE 原生解決方案相當的體驗。

IDE 整合所需的所有資源都可以在建置目錄中的 meson-info 目錄中找到。

在 IDE 中設定 Meson 專案時,第一件事是選擇原始碼和建置目錄。在此範例中,我們假設原始碼位於類似 Eclipse 的目錄中,稱為 workspace/project,而建置樹則嵌套在其中,如 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 kwarg 指定的所有檔案。請參閱 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

對於 combo 類型,也會顯示金鑰 choices。這裡儲存了選項的所有有效值。

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 命令完成。JSON 格式的結果記錄可以在 workspace/project/builddir/meson-logs/testlog.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:布林值
IdNode value:字串
NumberNode value:整數
StringNode value:字串
ContinueNode
BreakNode
ArgumentNode positional:節點清單;kwargs:接受 kwargs
ArrayNode args:節點
DictNode args:節點
EmptyNode
OrNode left:節點;right:節點
AndNode left:節點;right:節點
ComparisonNode left:節點;right:節點;ctype:字串
ArithmeticNode left:節點;right:節點;op:字串
NotNode right:節點
CodeBlockNode lines:節點清單
索引節點 (IndexNode) object: 節點;index: 節點
方法節點 (MethodNode) object: 節點;args: 節點;name: 字串
函式節點 (FunctionNode) args: 節點;name: 字串
賦值節點 (AssignmentNode) value: 節點;var_name: 字串
加法賦值節點 (PlusAssignmentNode) value: 節點;var_name: 字串
迴圈子句節點 (ForeachClauseNode) items: 節點;block: 節點;varnames: 列表
If 子句節點 (IfClauseNode) ifs: 節點列表;else: 節點
If 節點 (IfNode) condition: 節點;block: 節點
負號節點 (UMinusNode) right:節點
三元節點 (TernaryNode) condition: 節點;true: 節點;false: 節點

由於此格式與 Meson 內部 AST 密切相關,我們不保證其穩定性。然而,重大變更(例如移除節點類型或移除鍵)不太可能發生,並且將會在發行說明中公告。

JSON 參考手冊

除了線上參考手冊之外,Meson 也提供 JSON 格式的手冊。此檔案的內容與線上文件的來源相同。因此,這兩個版本的内容是相同的。

此 JSON 文件自 *0.60.0* 版本起附加於每個 Meson 發行版中。JSON Schema 由 jsonschema.py 中給定的類別結構定義。

現有整合

搜尋結果為