Table of Contents
1 はじめに
Meson というビルドシステムをご存知でしょうか? Jussi Pakkanen が作成したビルドシステムで、最近 GNOME 界隈で人気です。 Meson 自体は、 GNU Make の様に実際に build せず、 ビルド自体は Chrome Project で作られた Ninja を使います。 つまり Meson は GYP や CMake と同じ立ち位置です。
GYP → Make から GYP → Ninja 、Meson → Ninja と感じでしょうか。
Ninja は、 build system の高速 assembler を目指して作られただけあって、いろいろな Generator が生まれました。 その1つが Meson です。
2 Hello World
まず最初は、C の Hello World でどのように Mesonを記述するのか見てみましょう。
C のコードはいたってふつうの Hello World です。
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
このコードをコンパイルできるようにする Meson のコードは、次の2行です。これを meson.build
というファイルに記載します。
project('helloworld', 'c') executable('hello', 'hello.c')
project() でプロジェクト名と言語を、 executable() で実行ファイル名とソースファイル名を記述します。
Meson は In-Tree ビルドに対応していません。かならず Out-of-Tree ビルドになります。 Meson を実行するには、
meson [source dir] [build dir]
と、します。hello.c が置いてあるディレクトリで実行するなら、次のようになります。
$ ls hello.c meson.build
$ meson . build The Meson build system Version: 0.36.0 Source dir: /tmp/meson Build dir: /tmp/meson/build Build type: native build Project name: helloworld Native c compiler: ccache cc (gcc 6.2.1) Build machine cpu family: x86_64 Build machine cpu: x86_64 Build targets in project: 1
Meson がファイルを生成し終ったら Ninja を使ってビルドします。
$ ninja -C build ninja: Entering directory `build' [2/2] Linking target hello
無事、 build/hello
が生成されました。
$ build/hello Hello, World!
3 Build Application against GStreamer with Meson
ということで、次は GStreamer を使ったアプリを Meson でビルドしてみます。こちらもとてもシンプルなコード で試してみます。
#include <gst/gst.h> int main(int argc, char *argv[]) { GMainLoop *mainloop; GstElement *pipeline; GError *error = NULL; gst_init(&argc, &argv); mainloop = g_main_loop_new(NULL, FALSE); pipeline = gst_parse_launch("videotestsrc ! autovideosink", &error); gst_element_set_state(pipeline, GST_STATE_PLAYING); g_main_loop_run(mainloop); return 0; }
このコードを、先程と同じ meson.build
を使ってビルドすると
[1/2] Compiling c object 'hellogst@exe/hellogst.c.o' FAILED: hellogst@exe/hellogst.c.o ccache cc '-Ihellogst@exe' '-fdiagnostics-color=always' '-I.' '-I..' '-pipe' '-Wall' '-Winvalid-pch' '-O0' '-g' '-MMD' '-MQ' 'hellogst@exe/hellogst.c.o' '-MF' 'hellogst@exe/hellogst.c.o.d' -o 'hellogst@exe/hellogst.c.o' -c ../hellogst.c ../hellogst.c:1:21: fatal error: gst/gst.h: No such file or directory #include <gst/gst.h> ^ compilation terminated. ninja: build stopped: subcommand failed.
と、 gst/gst.h
が見つからないと怒られてしまいます。それもそのはずで、ビルドシステムは GStreamer のヘッダーに関してなにも知りません。そこで、このアプリは GStreamer 1.0 に依存していることを教えてあげます。
project('hello-gst', 'c') gst_dep = dependency('gstreamer-1.0', version : '>=1.0') executable('hellogst', 'hellogst.c', dependencies : gst_dep)
dependency() が、依存関係の記述です。 gstreamer-1.0
に依存し、バージョンは 1.0以上
という風に指定しました。この記述、実は pkg-config のモジュールの書き方と一緒です。 Meson は実行されているシステムでどのように依存関係を解決すべきか知っています。 Linux 上では pkg-config を使って解決してくれます。 もちろん Meson は Multi Platform 対応なので Windows 上でも MacOS 上でも、同じ書き方で GStreamer の依存関係を解決してくれます。
依存関係を追記したら、 build
ディレクトリを消して試してみましょう。 (正確には Meson は一度実行された後は、自動で設定が変った後に自分自身を再度実行します。そのため削除する必要はありません。ここでは、あえて GStreamer 1.0 を見つけるログを表示するために削除しています。)
$ rm -r build $ meson . build The Meson build system Version: 0.36.0 Source dir: /tmp/hello-gst Build dir: /tmp/hello-gst/build Build type: native build Project name: hello-gst Native c compiler: ccache cc (gcc 6.2.1) Build machine cpu family: x86_64 Build machine cpu: x86_64 Found pkg-config: /usr/bin/pkg-config (0.29) Native dependency gstreamer-1.0 found: YES 1.10.2 ← GStreamer を見つけました Build targets in project: 1
続いて ninja でビルドします。
$ ninja -C build [0/1] Regenerating build files The Meson build system Version: 0.36.0 Source dir: /tmp/hello-gst Build dir: /tmp/hello-gst/build Build type: native build Project name: hello-gst Native c compiler: ccache cc (gcc 6.2.1) Build machine cpu family: x86_64 Build machine cpu: x86_64 Build targets in project: 1 [2/2] Linking target hellogst
$ cd build $ ls build.ninja hellogst meson-logs compile_commands.json hellogst@exe meson-private
hellogst
が生成されました。
他にも、いろいろな中間ファイルが生成されています。
$ tree . ├── build.ninja ├── compile_commands.json ├── hellogst ├── hellogst@exe │ └── hellogst.c.o ├── meson-logs │ └── meson-log.txt └── meson-private ├── build.dat ├── coredata.dat ├── install.dat ├── meson_benchmark_setup.dat ├── meson_test_setup.dat ├── sanitycheckc.c └── sanitycheckc.exe 3 directories, 12 files
4 Build GStreamer Plugin with Meson
さて、やっと本題です。 GStreamer の Plugin を Meson でビルドしてみます。次の空っぽの Plugin をビルドします。
#include <gst/gst.h> #include "config.h" static gboolean plugin_init (GstPlugin * plugin) { return TRUE; } GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, gsttext, "Text Plugins for GStreamer", plugin_init, PACKAGE_VERSION, "LGPL", "GStreamer Text Package", "https://github/yashi/gst-plugins-text")
Meson.build
は次のようになります。
project('gst-plugins-text', 'c', version : '0.1.0') src = ['src/gsttext.c'] gst_dep = dependency('gstreamer-1.0', version : '>1.0') cdata = configuration_data() cdata.set_quoted('PACKAGE', meson.project_name()) cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) configure_file(output : 'config.h', configuration : cdata) gsttext = library('gsttext', src, dependencies : gst_dep)
- project()
- 新しく
version
を追加しています。それ以外は、名前が異なるだけで同じ内容です - src
executable()
に直接指定していたソースコードを変数に外出ししました。ファイルのリストなので[
]
で括っています- configuration_data()
設定を記載するためのデーターを作成します。最初はからっぽ。言語で C を選択していると
#define
が記述されたファイルが生成されます/* * Autogenerated by the Meson build system. * Do not edit, your changes will be lost. */ #pragma once #define PACKAGE "gst-plugins-text" #define PACKAGE_VERSION "0.1.0"
- cdata.set_quoted()
- 設定を追加します。設定値を
"
"
で括りたいので_quoted
を使っています。括らないならset()
が使えます - configure_file()
- 設定ができあがったら、ファイルに書き出します。ここでは autotools の名残りで
config.h
にしてみました - library()
- 実行ファイルではなくライブラリを作成したいので、
executable()
ではなくlibrary()
を使います。ファイル名と、ソースコード、そして依存を記載します
$ meson . build The Meson build system Version: 0.36.0 Source dir: /home/yashi/src/gst/gst-plugins-text Build dir: /home/yashi/src/gst/gst-plugins-text/build Build type: native build Project name: gst-plugins-text Native c compiler: ccache cc (gcc 6.2.1) Build machine cpu family: x86_64 Build machine cpu: x86_64 Found pkg-config: /usr/bin/pkg-config (0.29) Native dependency gstreamer-1.0 found: YES 1.10.2 Build targets in project: 1
ninja -C build ninja: Entering directory `build' [2/2] Linking target libgsttext.so
GST_PLUGIN_PATH=`pwd`/build gst-inspect-1.0 gsttext Plugin Details: Name gsttext Description Text Plugins for GStreamer Filename /home/yashi/src/gst/gst-plugins-text/build/libgsttext.so Version 0.1.0 License LGPL Source module gst-plugins-text Binary package GStreamer Text Package Origin URL https://github/yashi/gst-plugins-text 0 features:
5 おわりに
いかがだったでしょうか? ビルドスクリプトは頻繁に更新するものではないので、Autotools の書き方を毎回忘れてしまうという人でも Meson だったら簡単じゃないでしょうか? Linux でも Windows でも MacOS でも使えるという利点や、依存関係が Python と ninja だけになるという点も嬉しいです。しかし、プログラマーにとって一番嬉しいのは、ビルド時間が劇的に早くなることによって、コンパイルによって集中が途切れず、開発効率が改善されることじゃないでしょうか。え? コンパイル中に休憩 できなくなって困るなんてことはないですよね?
6 prio work
7 ref
- http://mesonbuild.com/
- https://www.youtube.com/watch?v=ae9_rNuFaQM
- https://lists.freedesktop.org/archives/wayland-devel/2016-November/031984.html
- https://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=b2f9808722a0254acba17ef98a612a2792184e12
- https://lists.freedesktop.org/archives/gstreamer-devel/2016-September/060231.html
- https://ninja-build.org/
- https://www.youtube.com/watch?v=KPi0AuVpxLI
- https://git.kernel.org/cgit/linux/kernel/git/kay/libabc.git/plain/README
- https://www.xkcd.com/303/
No comments:
Post a Comment