Wrap 依存関係システム マニュアル

マルチプラットフォーム開発における大きな問題の1つは、すべての依存関係を管理することです。多くのプラットフォーム、特に組み込みのパッケージマネージャーがないプラットフォームでは、これは扱いにくいです。後者の問題は、サードパーティのパッケージマネージャーを持つことで回避されてきました。エンドユーザーの展開にとっては実際には解決策になりません。アプリを使用するためだけにパッケージマネージャーをインストールするように指示することはできないからです。これらのプラットフォームでは、自己完結型のアプリケーションを作成する必要があります。宛先プラットフォームにアプリケーションの依存関係(最新バージョン)がない場合も同様です。

このための従来のアプローチは、依存関係を自分のプロジェクト内にバンドルすることでした。事前に構築されたライブラリとヘッダーとして、またはソースコードを自分のソースツリー内に埋め込み、プロジェクトの一部としてそれらを構築するようにビルドシステムを書き換えることでバンドルしていました。

これは、常に手作業で行われるため、面倒でエラーが発生しやすいです。MesonのWrap依存関係システムは、これを自動化する方法を提供することを目的としています。

仕組み

Mesonにはサブプロジェクトの概念があります。これらは、あるMesonプロジェクトを別のプロジェクトの中にネストする方法です。Mesonでビルドするプロジェクトは、それがサブプロジェクトとしてビルドされていることを検出し、使いやすい方法で(通常は静的ライブラリとして)ビルドできます。

この種のプロジェクトを依存関係として使用するには、プロジェクトのsubprojectsディレクトリ内にコピーして展開するだけです。

ただし、より簡単な方法があります。Mesonがダウンロードする方法を指示するWrapファイルを指定できます。ビルドでこのサブプロジェクトを使用すると、Mesonはビルド中に自動的にダウンロードして展開します。これにより、サブプロジェクトの埋め込みが非常に簡単になります。

すべてのwrapファイルは<project_name>.wrapという形式の名前を持ち、subprojectsディレクトリにある必要があります。

現在、Mesonには4種類のwrapがあります。

  • wrap-file
  • wrap-git
  • wrap-hg
  • wrap-svn

wrap形式

Wrapファイルはini形式で記述され、wrapのタイプを含む単一のヘッダーと、ソースを取得する方法、検証する方法、および必要に応じて変更する方法を記述するプロパティが続きます。名前がlibfoobarのwrapのwrap-fileの例には、libfoobar.wrapというファイル名が付けられ、次のようになります。

[wrap-file]
directory = libfoobar-1.0

source_url = https://example.com/foobar-1.0.tar.gz
source_filename = foobar-1.0.tar.gz
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663

wrap-gitの例は次のようになります。

[wrap-git]
url = https://github.com/libfoobar/libfoobar.git
revision = head
depth = 1

wrapに受け入れられる設定プロパティ

  • directory - サブプロジェクトのルートディレクトリの名前。デフォルトではwrapの名前になります。

0.55.0以降、これらはすべてのwrapタイプで使用できるようになりました。以前はwrap-fileに予約されていました。

  • patch_url - オプションのオーバーレイアーカイブを取得するためのダウンロードURL
  • patch_fallback_url - patch_urlからのダウンロードが失敗した場合に使用するフォールバックURL Since: 0.55.0
  • patch_filename - ダウンロードしたオーバーレイアーカイブのファイル名
  • patch_hash - ダウンロードしたオーバーレイアーカイブのsha256チェックサム
  • patch_directory - Since 0.55.0 オーバーレイディレクトリ。ダウンロードしたアーカイブの代わりにファイルがローカルにある場合のpatch_filenameの代替。ディレクトリはsubprojects/packagefilesに配置する必要があります。
  • diff_files - Since 0.63.0 ローカルdiffファイルのコンマ区切りリスト(以下のDiffファイルを参照)。
  • method - Since 1.3.0 このサブプロジェクトで使用されるビルドシステム。デフォルトはmesonです。サポートされているメソッド
    • mesonにはmeson.buildファイルが必要です。
    • cmakeにはCMakeLists.txtファイルが必要です。詳細を参照
    • cargoにはCargo.tomlファイルが必要です。詳細を参照

wrap-fileに固有

  • source_url - wrap-fileソースアーカイブを取得するためのダウンロードURL
  • source_fallback_url - source_urlからのダウンロードが失敗した場合に使用するフォールバックURL Since: 0.55.0
  • source_filename - ダウンロードしたソースアーカイブのファイル名
  • source_hash - ダウンロードしたソースアーカイブのsha256チェックサム
  • lead_directory_missing - wrap-fileの場合、先頭のディレクトリ名を作成します。ソースファイルに先頭のディレクトリがない場合に必要です。

0.55.0以降、.wrapファイルで(source_urlおよびpatch_urlなしで)source_filenameおよびpatch_filenameの値のみを使用し、subprojects/packagefilesディレクトリ内のローカルアーカイブを指定することができます。この方法を使用する場合、*_hashエントリはオプションです。この方法は、以下に説明する古いpackagecacheアプローチよりも優先する必要があります。

0.49.0以降、プロジェクトのsubprojects/packagecacheディレクトリにsource_filenameまたはpatch_filenameが見つかった場合、--wrap-modeオプションがnodownloadに設定されていても、ファイルをダウンロードする代わりにそれが使用されます。ファイルのハッシュがチェックされます。

1.3.0以降、MESON_PACKAGE_CACHE_DIR環境変数が設定されている場合、プロジェクトのsubprojects/packagecacheの代わりに使用されます。これにより、複数のプロジェクトでキャッシュを共有できます。さらに、wrapファイルのdirectoryフィールドと同じディレクトリ名を持つ限り、既に展開されたソースツリーを含めることができます。その場合、ディレクトリはパッチを適用する前にsubprojects/にコピーされます。

VCSベースのwrapに固有

  • url - クローンするwrap-gitリポジトリの名前。必須。
  • revision - チェックアウトするリビジョンの名前。VCSのcheckoutコマンドの有効な値(gitタグなど)、または(gitの場合)上流のデフォルトブランチを追跡するためのheadのいずれかである必要があります。必須。

wrap-gitに固有

  • depth - リポジトリをX個のコミットに浅くクローンします。これにより、帯域幅とディスク容量が節約され、コミット履歴が必要な場合を除いて、通常は常に指定する必要があります。gitは常にブランチの浅いクローンを許可しますが、コミットIDを浅くクローンするには、サーバーがuploadpack.allowReachableSHA1InWant=trueをサポートする必要があることに注意してください。(since 0.52.0)
  • push-url - gitプッシュURLとして構成する代替URL。サブプロジェクトが開発され、変更が上流にプッシュされる場合に役立ちます。(since 0.37.0)
  • clone-recursive - リポジトリのサブモジュールもクローンします (since 0.48.0)

Mesonビルドパッチ付きのwrap-file

残念ながら、世界のほとんどのソフトウェアプロジェクトはMesonでビルドしません。このため、MesonではパッチURLを指定できます。

歴史的な理由から、これは「パッチ」と呼ばれますが、ファイルを変更するのではなく、ファイルを追加または置換するためのオーバーレイとして機能します。ファイルはアーカイブである必要があります。ダウンロードされ、サブプロジェクトに自動的に展開されます。展開されたファイルには、指定されたサブプロジェクトのMesonビルド定義が含まれます。

このアプローチにより、ビルドシステムの変更が必要な依存関係を非常に簡単に埋め込むことができます。依存関係のMesonビルド定義を完全に分離して作成できます。これは、特に数十万行のコードが含まれている場合に、自分のソースツリー内で行うよりもはるかに優れています。作業用のビルド定義を作成したら、Mesonビルドファイル(および変更したその他のファイル)をzipで圧縮して、ダウンロードできる場所に配置します。

0.55.0より前は、Mesonビルドパッチはwrap-fileモードでのみサポートされていました。wrap-gitを使用する場合、リポジトリにはすべてのMesonビルド定義を含める必要があります。0.55.0以降、Mesonビルドパッチは、wrap-gitを含むすべてのwrapモードでサポートされています。

Diffファイル

Since: 0.63.0

diff形式でローカルパッチファイルを提供することもできます。歴史的な理由から、「パッチ」という名前がすでにオーバーレイアーカイブに使用されているため、これらは「diffファイル」と呼ばれます。

diffファイルは、diff_filesプロパティ(コンマ区切りリスト)で記述され、subprojects/packagefilesディレクトリでローカルに利用できる必要があります。

Mesonは、プロジェクトの展開またはクローンの後、およびオーバーレイアーカイブ(patch_*)の適用後にdiffファイルを適用します。この機能には、patchまたはgitコマンドラインツールが利用可能である必要があります。

diffファイルは-p1で適用されます。つまり、最初のパスコンポーネントを削除されるプレフィックスとして扱います。これは、Gitによって生成されたdiffのデフォルトです。

[wrap-file]
directory = libfoobar-1.0

source_url = https://example.com/foobar-1.0.tar.gz
source_filename = foobar-1.0.tar.gz
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663

diff_files = libfoobar-1.0/0001.patch, libfoobar-1.0/0002.patch

provideセクション

*Since 0.55.0

Wrapファイルは、[provide]セクションで提供する依存関係を定義できます。

[provide]
dependency_names = foo-1.0

上記のように、wrapファイルが依存関係foo-1.0を提供する場合、dependency('foo-1.0')の呼び出しは、fallbackキーワード引数が指定されていない場合でも、自動的にそのサブプロジェクトにフォールバックします。[provide]セクションがない場合でも、foo.wrapという名前のwrapファイルは、依存関係名fooを暗黙的に提供します。

dependency('foo-1.0', required: get_option('foo_opt'))のようなオプションの依存関係(ここでfoo_optautoに設定された機能オプション)は、次の2つの理由でwrapファイルで定義されたサブプロジェクトにフォールバックしません。

  • まず、cc.find_library('foo')を使用するなど、他の方法で依存関係を検索し、それが失敗した場合にのみフォールバックできるようにします
# this won't use fallback defined in foo.wrap
foo_dep = dependency('foo-1.0', required: false)
if not foo_dep.found()
  foo_dep = cc.find_library('foo', has_headers: 'foo.h', required: false)
  if not foo_dep.found()
    # This will use the fallback
    foo_dep = dependency('foo-1.0')
    # or
    foo_dep = dependency('foo-1.0', required: false, fallback: 'foo')
  endif
endif
  • ユーザーが明示的に要求していない場合、フォールバックよりも依存関係が見つからない方が望ましい場合があります。その場合、dependency('foo-1.0', required: get_option('foo_opt'))は、ユーザーがfoo_optautoではなくenabledに設定した場合にのみフォールバックします。Since 0.58.0 上記のようなオプションの依存関係は、wrap_modeforcefallbackに設定されているか、force_fallback_forにサブプロジェクトが含まれている場合に、wrapファイルで定義されたサブプロジェクトにフォールバックします。

オプションの依存関係にフォールバックしたい場合は、fallback または allow_fallback キーワード引数を明示的に渡す必要があります。0.56.0以降dependency('foo-1.0', required: get_option('foo_opt'), allow_fallback: true) は、foo_optauto に設定されている場合でもフォールバックを使用します。0.55.0 では、同じ効果を dependency('foo-1.0', required: get_option('foo_opt'), fallback: 'foo') で実現できました。

このメカニズムは、サブプロジェクトが meson.override_dependency('foo-1.0', foo_dep) を呼び出すことを前提としており、Meson はどの依存関係オブジェクトをフォールバックとして使用すべきかを知ることができます。このメソッドはバージョン 0.54.0 で導入されたため、まだこのメソッドを利用していないプロジェクトのための一時的な支援として、ラップファイルに foo-1.0 = foo_dep の形式で変数名を指定することができます。

例えば、glib-2.0gobject-2.0gio-2.0 をオーバーライドするために meson.override_dependency() を使用する、十分に新しいバージョンの glib を使用する場合、ラップファイルは次のようになります。

[wrap-git]
url=https://gitlab.gnome.org/GNOME/glib.git
revision=glib-2-62
depth=1

[provide]
dependency_names = glib-2.0, gobject-2.0, gio-2.0

古いバージョンの glib では、依存関係の変数名を指定する必要があります。

[wrap-git]
url=https://gitlab.gnome.org/GNOME/glib.git
revision=glib-2-62
depth=1

[provide]
glib-2.0=glib_dep
gobject-2.0=gobject_dep
gio-2.0=gio_dep

プログラムは program_names キーを使ってラップファイルで提供することもできます。

[provide]
program_names = myprog, otherprog

このようなラップファイルがあれば、find_program('myprog') は、サブプロジェクトが meson.override_find_program('myprog') を使用していると仮定して、自動的にサブプロジェクトの使用にフォールバックします。

CMake ラップ

注意: これは実験的な機能であり、後方互換性や前方互換性の保証はありません。「ビルドシステムの混在に関するMesonのルール」を参照してください。

CMake モジュールは提供された依存関係の公開名を知らないため、CMake の .wrap ファイルは dependency_names = foo という構文を使用できません。代わりに、dep_name = <target_name>_dep という構文を使用する必要があります。ここで、<target_name> は、すべての英数字以外の文字がアンダースコア _ に置き換えられた CMake ライブラリの名前です。

例えば、CMakeList.txtadd_library(foo-bar ...) を含み、アプリケーションが通常 foo-bar-1.0 という依存関係名(例えば pkg-config を介して)を使って見つけるような CMake プロジェクトは、次のようなラップファイルを持つことになります。

[wrap-file]
...
method = cmake
[provide]
foo-bar-1.0 = foo_bar_dep

Cargo ラップ

注意: これは実験的な機能であり、後方互換性や前方互換性の保証はありません。「ビルドシステムの混在に関するMesonのルール」を参照してください。

Cargo サブプロジェクトは、<package_name>-<version>-rs という依存関係名を自動的にオーバーライドします。

  • package_nameCargo.toml[package] name = ... セクションで定義されています。
  • version は、[package] version = ... から次のように推測される API バージョンです。
    • x.y.z -> 'x'
    • 0.x.y -> '0.x'
    • 0.0.x -> '0' これにより、同じクレートの互換性のないバージョンに対して異なる依存関係を作ることができます。
  • -rs サフィックスは、通常のシステム依存関係と区別するために追加されます。例えば、gstreamer-1.0 はシステムの pkg-config 依存関係であり、gstreamer-0.22-rs は Cargo 依存関係です。

つまり、Cargo.toml のパッケージ名が foo でバージョンが 1.2 の場合、.wrap ファイルの [provide] セクションには dependency_names = foo-1-rs が必要になります。

バージョンコンポーネントは Meson 1.4 で追加されました。以前のバージョンでは <package_name>-rs 形式を使用していたことに注意してください。

Cargo サブプロジェクトには、toml パーサーが必要です。Python >= 3.11 には組み込みのパーサーがありますが、それより古い Python バージョンでは、外部の tomli モジュールまたは toml2json プログラムが必要です。

例えば、パッケージ名が foo-bar の Cargo プロジェクトは、次のようなラップファイルを持つことになります。

[wrap-file]
...
method = cargo
[provide]
dependency_names = foo-bar-0.1-rs

さらに、meson/meson.build ファイルが存在する場合、Meson は subdir('meson') を呼び出します。ここで、プロジェクトは通常 build.rs の一部である手動ロジックを追加できます。いくつかの命名規則に従う必要があります。

  • extra_args 変数は事前に定義されており、Rust の引数を追加するために使用できます。これは通常 extra_args += ['--cfg', 'foo'] のように使用されます。
  • extra_deps 変数は事前に定義されており、追加の依存関係を追加するために使用できます。これは通常 extra_deps += dependency('foo') のように使用されます。

1.5.0 以降、Cargo ラップは、(サブ)プロジェクトのソースツリーのルートにある Cargo.lock ファイルでも提供できます。Meson はそのファイルを自動的にロードし、一連のラップ定義に変換します。

ラップされたプロジェクトの使用

ラップは、プロジェクトをサブプロジェクトディレクトリに取り込むための便利な方法を提供します。その後、通常のサブプロジェクトとして使用します(「サブプロジェクト」を参照してください)。

ラップの取得

通常、ラップを手動で記述する必要はありません。

WrapDB」というオンラインリポジトリがあり、多くの依存関係がすぐに使用できるようになっています。WrapDBの詳細については、「WrapDBの使用」を参照してください。

ラップを取得および管理するためのMesonサブコマンドもあります(「wraptoolの使用」を参照してください)。

検索結果は次のとおりです