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
です。サポートされているメソッド
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_opt
はauto
に設定された機能オプション)は、次の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_opt
をauto
ではなくenabled
に設定した場合にのみフォールバックします。Since 0.58.0 上記のようなオプションの依存関係は、wrap_mode
がforcefallback
に設定されているか、force_fallback_for
にサブプロジェクトが含まれている場合に、wrapファイルで定義されたサブプロジェクトにフォールバックします。
オプションの依存関係にフォールバックしたい場合は、fallback
または allow_fallback
キーワード引数を明示的に渡す必要があります。0.56.0以降、dependency('foo-1.0', required: get_option('foo_opt'), allow_fallback: true)
は、foo_opt
が auto
に設定されている場合でもフォールバックを使用します。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.0
、gobject-2.0
、gio-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.txt
に add_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_name
はCargo.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の使用」を参照してください)。
検索結果は次のとおりです