Mesonの使い方メモ
Mesonの使い方メモ
Mesonの情報無さすぎるということでメモ。 触ってみた所感としてcmakeより楽なんだろうけど、どのbuitinオプションがどの引数を制御してるかなどがわかりにくい.. (ver0.61なので今後変わりそうですが)
mesonではビルド方法を2種類に分けている
- native build: build machineとhost/target machineが同じ
- cross build: build machineとhost/target machineが別
今回はnative buildを中心にまとめる。
環境・事前準備
今回はDocker上にMesonをインストールした状況を想定してる。 Mesonはpipからインストールできる。
$ pip3 install meson
- Windows10 64bit
- WSL2
- DockerDesktop 4.5.1 (74721)
- base image: Debian 11
- Meson 0.61.2
- base image: Debian 11
Mesonって何?
Autotools(automake)やCMakeのようなビルディングツール。 python製。
ビルドツールの歴史として以下を三大巨頭とすると
- 1990年頃:Autotools(automake)
- 1999年頃:Cmake
- 2013年頃:Meson
その中でも、Mesonは特にユーザーフレンドリーを意識して開発されている。 (ドキュメントの解説が機能別になりすぎていたり、サンプルも少ないので、わかりにくいことも多いが)
ただし実際にMesonはfrontend側の処理をしておりビルド処理を担当してるのはNinjaになる。 まとめると、
- frontend: Meson: autoconfやautomake側に近い
- backend: Ninja: ビルド処理を担当、make側に近い
(正直、Ninjaだけでは駄目なのかよくわかってない)
設定ファイルの関係をまとめると
tool | ビルドの設定ファイル |
---|---|
make/automake | Makefile |
Cmake | CMakeLists.txt |
Meson | meson.build |
Mesonを使う流れ
主な流れをまとめる。
開発者側:プロジェクト用ディレクトリ作成からビルドまで
$ mkdir <project dir> $ cd <project dir> $ meson init # meson.buildファイルが作成される
meson init
にオプションをつけることで使う言語など指定できる。
IDEやらエディタやらでソースコードをプロジェクトフォルダ内に作成または追加して,
meson.build
にビルド用の設定を追加する。
$ meson setup <build dir> $ cd <build dir> $ meson compile # or ninja build
これでソースコードの変更があればmeson compile
だけで済むようになる。
Release版などをインストールするユーザ側:基本的にautotoolsの流れに近い
$ cd <project dir> # meson.buildのある場所に移動 $ meson setup <build dir> # ./configure に相当 $ cd <build dir> $ meson compile # make に相当 $ meson install # make install に相当
meson install
について:
Installing
meson.build(設定ファイル)の書き方
mesonを使うにはmeson.build
ファイルが必須になる。
ディレクトリ内に存在しないとエラーになる。
公式Tutorialに最低限の書き方がある。
最低限必要なのは以下2行になる。
project('project name', 'language') executable('実行ファイル名', ['source code path'])
if文やforreach文なんかも使える。 if文が使えるので指定のコンパイラだったら特定の引数を追加するような書き方もできる。 (あまり複雑な条件設定にするとカオスになりそうだが)
他に使える構文: Syntax
※pythonライクに書けて変数設定もできるが、予約された識別子と自分が設定した変数なのかがわかりにくくなるので注意。
また、built-in optionや変数の値を確認するにはmessage
関数が使える。built-in optionはget_option
関数でアクセスできる。
project('project name', 'language') flag=false executable('実行ファイル名', ['source code path']) message(flag) message('b_asneeded: ', get_option('b_asneeded'))
これらのmessage
はmeson setup
したときに表示される。
引数設定のススメ
ビルドツールを使うということは、コンパイラやリンカの引数設定をするはずなのでその方法についてまとめる。
引数指定方法は主に3つある。
- nativeファイル内で指定してmesonコマンドのときに上書きする
meson.build
ファイル内で指定- meson側で読み込む環境変数を使う
おすすめは一番上のカスタム用のnativeファイルを作成してそこで指定しておくやり方である。
これだと元のmeson.build
ファイルを基本いじらずにnativeファイルから上書きして設定できる。
実際にコンパイラやリンカにどの引数が指定されてビルドされているかを確認するには
$ meson compile --verbose
nativeファイルの書き方・使い方
nativeファイルの書き方: Cross and Native File reference
※ただし、 meson側のbuilt-in optionにより勝手に設定されるコンパイラやリンカへの引数がわかりにくい(特に明示がない)ので注意。 built-in optionの一覧は Built-in optionsで確認できる。
毎度検索するのは大変なのでtemplateファイルを残す。
native_template.ini
## native file ## "constants" that can be used on .ini files ### 🔗 https://mesonbuild.com/Machine-files.html#constants [constants] ## "Properties" that is key value pairs accessed using the meson.get_external_property(), or meson.get_cross_property(). ### 🔗 https://mesonbuild.com/Machine-files.html#properties [properties] # cmake_toolchain_file='' # specifies an absolute path to an already existing CMake toolchain file that will be loaded with include() as the last instruction of the automatically generated CMake toolchain file from Meson. (new in 0.56.0) # cmake_defaults='' # is a boolean that specifies whether Meson should automatically generate default toolchain variables from other sections (binaries, host_machine, etc.) in the machine file. Defaults are always overwritten by variables set in the [cmake] section. The default is true. (new in 0.56.0) # cmake_skip_compiler_test='' # is an enum that specifies when Meson should automatically generate toolchain variables to skip the CMake compiler sanity checks. This only has an effect if cmake_defaults is true. Supported values are always, never, dep_only. The default is dep_only. (new in 0.56.0) # cmake_use_exe_wrapper='' # is a boolean that controls whether to use the exe_wrapper specified in [binaries] to run generated executables in CMake subprojects. This setting has no effect if the exe_wrapper was not specified. The default value is true. (new in 0.56.0) # java_home='' ## Project specific options ### Being able to set project specific options in a cross or native file can be done using the [project options] section of the specific file (if doing a cross build the options from the native file will be ignored) ### ⚠ require to define options in `meson_option.txt` ### able to set -Doption when using `meson` command on terminal ### able to access using `get_option()` in `meson.build`file ### 🔗 https://mesonbuild.com/Machine-files.html#project-specific-options [project options] ## Binaries ### 🔗 https://mesonbuild.com/Machine-files.html#binaries [binaries] # c = 'gcc' # c_ld='ld' # cpp='g++' # cpp_ld='ld' # ar='ar' # sed = 'sed' # llvm-config = '/usr/lib/llvm-11/bin/llvm-config' ## Builtin-options ### 🔗 https://mesonbuild.com/Builtin-options [built-in options] ### Compiler options 🔗 https://mesonbuild.com/Builtin-options.html#compiler-options # c_args=[] # C compile arguments to use # c_link_args=[] # C link arguments to use # c_std='none' # 'none'/'c89'/'c99'/'c11'/'c17'/'c18'/'c2x'/'gnu89'/'gnu99'/'gnu11'/'gnu17'/'gnu18'/'gnu2x' # C language standard to use # c_winlibs=[] # see below free-form comma-separated list # Standard Windows libs to link against # c_thread_count=4 #integer value ≥ 0 # Number of threads to use with emcc when using threads # cpp_args=[] # free-form comma-separated list # C++ compile arguments to use # cpp_link_args=[] # free-form comma-separated list # C++ link arguments to use # cpp_std='none' # none/c++98/c++03/c++11/c++14/c++17/c++20/c++2a/c++1z/gnu++03/gnu++11/gnu++14/gnu++17/gnu++1z/gnu++2a, gnu++20, vc++14, vc++17, vc++latest C++ language standard to use # cpp_debugstl=false # true/false # C++ STL debug mode # cpp_eh='default' # none/default/a/s/sc # C++ exception handling type # cpp_rtti=true # true/false # Whether to enable RTTI (runtime type identification) # cpp_thread_count=4 # integer value ≥ 0 # Number of threads to use with emcc when using threads # cpp_winlibs=[] # see below free-form comma-separated list # Standard Windows libs to link against # fortran_std='none' # [none, legacy, f95, f2003, f2008, f2018] # Fortran language standard to use # cuda_ccbindir='' # filesystem path # CUDA non-default toolchain directory to use (-ccbin) (Added in 0.57.1) ### Universal options 🔗 https://mesonbuild.com/Builtin-options.html#universal-options #### Directories # prefix='/usr/local' # prefix defaults to 'C:/' on Windows, and '/usr/local' otherwise. # Installation prefix # bindir='bin' # Executable directory # datadir='share' # Data file directory # includedir='include' # Header file directory # infodir='share/info' # Info page directory # libdir='' # `libdir` is automatically detected based on your platform, it should be correct when doing "native" (build machine == host machine) compilation. For cross compiles Meson will try to guess the correct libdir, but it may not be accurate, especially on Linux where different distributions have different defaults. Using a cross file, particularly the paths section may be necessary. # Library directory # libexecdir='libexec' # Library executable directory # localedir='share/locale' # Locale data directory # localstatedir='var' # Localstate data directory # mandir='share/man' # Manual page directory # sbindir='sbin' # System executable directory # sharedstatedir='com' # Architecture-independent data directory # sysconfdir='etc' # Sysconf data directory ### Core options 🔗 https://mesonbuild.com/Builtin-options.html#core-options # auto_features='auto' # {enabled, disabled, auto} # Override value of all 'auto' features # backend='ninja' # {ninja, vs, vs2010, vs2012, vs2013, vs2015, vs2017, vs2019, vs2022, xcode} # Backend to use # buildtype='debug' # {plain, debug, debugoptimized, release, minsize, custom} # Build type to use # debug=true # Debug # default_library='shared' # {shared, static, both} # Default library type # errorlogs=true # Whether to print the logs from failing tests. # install_umask='022' # {preserve, 0000-0777} # Default umask to apply on permissions of installed files no no # layout='mirror' {mirror,flat} # Build directory layout # optimization='0' # {0, g, 1, 2, 3, s} # Optimization level # pkg_config_path='' # {OS separated path} # Additional paths for pkg-config to search before builtin paths # cmake_prefix_path=[] # Additional prefixes for cmake to search before builtin paths yes no # stdsplit=true # Split stdout and stderr in test logs # strip=false # Strip targets on install # unity='off' # {on, off, subprojects} # Unity build # unity_size=4 # {>=2} # Unity file block size no no # warning_level=1 # {0, 1, 2, 3} Set the warning level. From 0 = none to 3 = highest no yes # werror=false # Treat warnings as errors # wrap_mode='default' {default, nofallback, nodownload, forcefallback, nopromote} # Wrap mode to use no no # force_fallback_for=[] # Force fallback for those dependencies no no ### Base option 🔗 https://mesonbuild.com/Builtin-options.html#base-options # b_asneeded=true # true/false # Use -Wl,--as-needed when linking # b_bitcode=false # true/false # Embed Apple bitcode, see below # b_colorout='always' # auto/always/never # Use colored output # b_coverage=false # true/false # Enable coverage tracking # b_lundef=true # true/false # Don't allow undefined symbols when linking # b_lto=false # true/false # Use link time optimization # b_lto_threads=0 # Any integer* # Use multiple threads for lto. (Added in 0.57.0) # b_lto_mode='default' # default/thin # Select between lto modes, thin and default. (Added in 0.57.0) # b_ndebug=false # true/false # if-release Disable asserts # b_pch=true # true/false # Use precompiled headers # b_pgo='off' # off/generate/use # Use profile guided optimization # b_sanitize='none' # see below Code sanitizer to use # b_staticpic=true # true/false # Build static libraries as position independent # b_pie=false # true/false # Build position-independent executables (since 0.49.0) # b_vscrt='from_buildtype' #none/md/mdd/mt/mtd/from_buildtype/static_from_buildtype # VS runtime library to use (since 0.48.0) (static_from_buildtype since 0.56.0)
上書き方法は
$ meson setup <build dir> --native-file <native>.ini
例:nativeファイルからコンパイラをclangに変える
graph BT subgraph "--native-file native_clang.ini" c["c: clang"] subgraph "default native" c_d["c: gcc"] end c_d -..-> c end
native_clang.ini
ファイルを作る。
[binaries] c='clang' cpp='clang++'
$ meson setup <build_dir> --native-file native_clang.ini
C compilerがclangになってれば設定できている。
meson.build
ファイル内に書く
project
関数内のdefault_options={}
で指定:- add関数で指定
add_project_arguments()
: コンパイラの引数を指定できるadd_project_link_arguments()
: リンカの引数を指定
executable
関数内のoverride_options={}
で指定
override_options
は実行ファイル生成時にのみ引数が有効になり、mesage
やget_option
でアクセスしたときには有効にならないので使わないほうがいい。
環境変数を使うケース
環境変数を使うやり方はCMakeのように扱える。
meson側が参照する予約されている環境変数一覧:
この一覧の大文字で表されてるのが環境変数になる。各言語のコンパイラやリンカはここの環境変数でも設定できる。
※ただし、mesonでは環境変数の設定がmeson.build
ファイル上でできない?ぽい。つまり設定ファイル上で制御できない。
実用するならsetup用のシェルスクリプトを書いたほうが扱いやすい。
例: 環境変数を使ってgccでなくclangでビルドする場合
なのでこれらにclang
, clang++
を設定すればいい。
command:
$ CC=clang CXX=clang++ meson setup <build dir>
一応事前にset CC=clang
のようにも書いておけるが上のように書けば、
環境変数後のコマンドが子プロセス扱いで環境変数が引き継がれるのでこっちの書き方推奨。