MesonでXを行うにはどうすればよいですか?

このページでは、一般的なタスクのコードスニペットをリストします。これらは主にCコンパイラーを使用して記述されていますが、ほとんどすべての他のコンパイラーでも同じアプローチで動作するはずです。

コンパイラーの設定

Mesonを最初に実行するときは、環境変数で設定します。

$ CC=mycc meson <options>

CCのような環境変数は、クロスビルドではホストプラットフォームのみを参照することに注意してください。つまり、CCは、最終的にプロジェクトをインストールするマシンで実行されるプログラムをコンパイルするために使用されるコンパイラーを参照します。ビルドを行うマシンで実行されるものをビルドするために使用されるコンパイラーは、CC_FOR_BUILDで指定できます。クロスビルドで使用できます。

ただし、環境変数はMesonで何かを行うための慣用的な方法ではありません。ネイティブファイルとクロスファイルを使用する方が優れています。また、クロスビルドのホストプラットフォームのツールは、クロスファイルでのみ指定できます。

サポートされているすべての環境変数の表がここにあります。

リンカーの設定

0.53.0で新規

コンパイラーと同様に、リンカーは<コンパイラー変数>_LD環境変数、またはネイティブファイルまたはクロスファイルの<コンパイラーエントリ>_ldエントリを介して選択されます。リンカー自体を呼び出すコンパイラー (GCCやClangを含むほとんどのコンパイラー) を使用しているか、直接呼び出されるリンカー (MSVCまたはそれに類似するコンパイラー (Clang-Clを含む) を使用している場合) を使用しているかを認識する必要があります。前者では、c_ldまたはCC_LDはコンパイラーの特殊な引数(clangとgccでの-fuse-ldなど)に渡す値である必要があり、後者ではlld-link.exeなどの実行可能ファイルである必要があります。

Meson 0.53.0では、クロスファイル/ネイティブファイルのldエントリとLD環境変数が使用されていましたが、これにより多くの回帰が発生し、0.53.1で<lang>_ld<comp variable>_LDに変更されました。

$ CC=clang CC_LD=lld meson <options>

または

$ CC=clang-cl CC_LD=link meson <options>

または、クロスファイルまたはネイティブファイルで

[binaries]
c = 'clang'
c_ld = 'lld'

サポートされているすべての環境変数の表がここにあります。

デフォルトのC/C++言語バージョンの設定

project('myproj', 'c', 'cpp',
        default_options : ['c_std=c11', 'cpp_std=c++11'])

言語バージョンは、ターゲットごとに設定することもできます。

executable(..., override_options : ['c_std=c11'])

スレッドの有効化

多くの人がcc.find_library('pthread')または同様のもので手動で行っているようです。そうしないでください。移植性がないです。代わりに、これを行います。

thread_dep = dependency('threads')
executable(..., dependencies : thread_dep)

外部からコンパイラーとリンカーの追加フラグを設定します (例: ディストリビューションパッケージをビルドするとき)

動作は他のビルドシステムと同じで、最初の呼び出し時に環境変数を使用します。ソースをリビルドする必要がある場合は、これらを使用しないでください

$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options>

特定のコンパイラーでのみ引数を使用する

最初に、どの引数を使用するかを確認します。

if meson.get_compiler('c').get_id() == 'clang'
  extra_args = ['-fclang-flag']
else
  extra_args = []
endif

次に、ターゲットで使用します。

executable(..., c_args : extra_args)

すべてのターゲットで引数を使用する場合は、これを行います。

if meson.get_compiler('c').get_id() == 'clang'
  add_global_arguments('-fclang-flag', language : 'c')
endif

コマンドの出力を構成に設定する

txt = run_command('script', 'argument', check: true).stdout().strip()
cdata = configuration_data()
cdata.set('SOMETHING', txt)
configure_file(...)

ファイルから構成データを生成する

fsモジュールは、構成データに任意のファイルの内容を追加できるread関数を提供します (他の用途の中で)

fs = import('fs')
cdata = configuration_data()
copyright = fs.read('LICENSE')
cdata.set('COPYRIGHT', copyright)
if build_machine.system() == 'linux'
    os_release = fs.read('/etc/os-release')
    cdata.set('LINUX_BUILDER', os_release)
endif
configure_file(...)

configure_fileで実行可能なスクリプトを生成する

configure_fileはメタデータを保持するため、テンプレートファイルに実行権限がある場合、生成されたファイルにも実行権限が付与されます。

カバレッジレポートの生成

最初に、このコマンドでビルドディレクトリを初期化します。

$ meson setup <other flags> -Db_coverage=true

次に、次のコマンドを発行します。

$ meson compile
$ meson test
$ ninja coverage-html (or coverage-xml)

カバレッジレポートは、meson-logsサブディレクトリにあります。

0.55.0で新規 clangで使用するためのllvm-covサポート

デバッグビルドにいくつかの最適化を追加する

デフォルトでは、デバッグビルドでは最適化は使用されません。これはほとんどの場合望ましいアプローチです。ただし、一部のプロジェクトでは、いくつかの小さな最適化を有効にすることから恩恵を受けることができます。GCCには、これのための特定のコンパイラーフラグ-Ogさえあります。その使用を有効にするには、次のコマンドを発行するだけです。

$ meson configure -Dc_args=-Og

これにより、後続のすべてのビルドでこのコマンドライン引数が使用されます。

アドレスサニタイザーの使用

Clangとgccには、アドレスサニタイザーなどの分析ツールの選択肢が付属しています。Mesonは、b_sanitizeオプションを使用してこれらをネイティブにサポートしています。

$ meson setup <other options> -Db_sanitize=address

この後、コードをコンパイルしてテストスイートを実行するだけです。アドレスサニタイザーはバグのある実行可能ファイルを中断するため、テストの失敗として表示されます。

Clang静的アナライザーの使用

scan-buildプログラムをインストールし、次にこれを行います

$ meson setup builddir
$ ninja -C builddir scan-build

SCANBUILD環境変数を使用して、scan-build実行可能ファイルを選択できます。

$ SCANBUILD=<your exe> ninja -C builddir scan-build

スクリプトを作成することにより、scan-buildプログラムに引数を渡すために使用できます。例:

#!/bin/sh
scan-build -v --status-bugs "$@"

次に、変数を通じて渡します (絶対パスを使用することを忘れないでください)

$ SCANBUILD=$(pwd)/my-scan-build.sh ninja -C builddir scan-build

プロファイルガイド最適化の使用

GCCでプロファイルガイド最適化を使用するには、2段階の操作が必要です。まず、プロファイル測定が有効になっている状態でプロジェクトを設定し、コンパイルします。

$ meson setup <Meson options, such as --buildtype=debugoptimized> -Db_pgo=generate
$ meson compile -C builddir

次に、いくつかの代表的な入力でプログラムを実行する必要があります。この手順は、プロジェクトによって異なります。

それが完了したら、生成された情報を使用するようにコンパイラーフラグを変更して、リビルドします。

$ meson configure -Db_pgo=use
$ meson compile

これらの手順の後、結果のバイナリは完全に最適化されます。

数学ライブラリ(-lm)を移植可能に追加する

一部のプラットフォーム (例: Linux) には、スタンドアロンの数学ライブラリがあります。他のプラットフォーム (ほぼすべて) はありません。必要な場合にのみmを使用することを指定する方法は?

cc = meson.get_compiler('c')
m_dep = cc.find_library('m', required : false)
executable(..., dependencies : m_dep)

実行可能ファイルをlibexecdirにインストールする

executable(..., install : true, install_dir : get_option('libexecdir'))

既存のFind<name>.cmakeファイルを使用する

Mesonは、CMakeがインストールされている場合、CMake find_package()エコシステムを使用できます。カスタムのFind<name>.cmakeで依存関係を見つけるには、プロジェクトでCMakeスクリプトが保存されているパスにcmake_module_pathプロパティを設定します。

cmakeサブディレクトリにあるFindCmakeOnlyDep.cmakeの例

cm_dep = dependency('CmakeOnlyDep', cmake_module_path : 'cmake')

cmake_module_pathプロパティは、カスタムのCMakeスクリプトにのみ必要です。システム全体のCMakeスクリプトは自動的に検索されます。

詳細については、こちらをご覧ください。

デフォルトで見つからない依存関係を取得しますか?

null_dep = dependency('', required : false)

これは、デフォルト値が必要だが、後で上書きする可能性がある場合に使用できます。

# Not needed on Windows!
my_dep = dependency('', required : false)
if host_machine.system() in ['freebsd', 'netbsd', 'openbsd', 'dragonfly']
  my_dep = dependency('some dep', required : false)
elif host_machine.system() == 'linux'
  my_dep = dependency('some other dep', required : false)
endif

executable(
  'myexe',
  my_sources,
  deps : [my_dep]
)

ユニティビルドからファイルを除外する

プロジェクトがユニティビルドをサポートしている場合は、ソースファイルが連結されたときに発生するバグを修正する必要があります。ただし、ソースファイルが生成されている場合など、これが不可能な場合があります。

この場合、それらを個別の静的ライブラリビルドターゲットに入れ、ユニティ設定をオーバーライドできます。

generated_files = ...
unityproof_lib = static_library('unityproof', generated_files,
  override_options : ['unity=off'])

main_exe = executable('main', main_sources, link_with : unityproof_lib)

静的ライブラリを別のライブラリターゲットにリンクするには、link_withの代わりにlink_wholeを使用する必要がある場合があります。

検索の結果は