LoginSignup
4
3

More than 5 years have passed since last update.

Perl製ビルドツール "Daiku" 入門編

Last updated at Posted at 2015-03-14

はじめに

以前の投稿1で紹介した Perl 製ビルドツールの Daiku ですが、2015年3月現在のところ、GitHub で "Daikufile" と検索してみてもヒット数は多くありません。
昨年5月に version 1.0 がリリース2されて1年近くが経ちますが、まだまだ認知度が低い印象です。

そこで、いくつかサンプルを書いてみながら Daiku の機能を試してみました。

なお、今回作成した Daikufile やソース一式は GitHub の progrhyme/perl5-Daiku-examples というリポジトリにアップしています。

Daiku を使う準備

インストール

cpanm3 を使っている場合、シェルから cpanm Daiku を実行してインストールして下さい。
Daiku パッケージには daiku コマンドが付属しています。
perl を perlbrew4 や plenv5 環境で実行している場合、rehash が必要になります。

cpanm Daiku
plenv rehash # perlbrew なら perlbrew rehash
which daiku
# daiku コマンドのパスが表示されます

daiku コマンドの使い方

最も簡単な使い方は単に daiku と打つだけです。
この場合、カレントディレクトリの Daikufile に従ってビルドを実行します。
-f オプションで、任意の Daikufile を指定することもできます。

また、daiku タスク名 で、Daikufile に記述された任意のタスクを実行することもできます。

% daiku                      # Daikufile のビルドを実行
% daiku deploy               # タスク名を指定して実行
% daiku -f Daikufile.another # Daikufile.another のビルドを実行

また、daiku -T で Daikufile に記されたビルドタスクを一覧できます。

% daiku -T
daiku default  # run
daiku install  # install necessary modules
daiku run      # run app
daiku test     # run test

その他、詳しい使い方は daiku --help で確認して下さい。

Daikufile とは

Daikufile は GNU make6 の Makefile に相当し、ビルドで実行するタスクを Daiku 独自の DSL (Domain Specific Language=ドメイン特化言語)で記述したものになります。

Daikufile の記法については、GitHub の README.md がドキュメントとなっています。

本稿でも、以降の例で詳しく見ていきます。

Daiku で "Hello, world!"

最もシンプルな例として、Daiku で "Hello, world!" を出力する簡単なビルドを実行してみます。

Daikufile

Daikufile は次のようになります。

desc 'hello'; # (1.1)
task default => sub { # (1.2)
    sh "echo 'Hello, world!'"; # (1.3)
};

以下、この Daikufile の中身を見ていきます。

(1.1) desc <Str> の構文で、下行に続くタスクの説明を表します。
省略することも可能ですが、書いておくと daiku -T で表示できるので、その方が親切でしょう。

(1.2) task <Str> => <CodeRef> の構文で、タスクの定義になります。
<Str> という名前のタスクで <CodeRef> のコードが実行されます。

この task 関数を使った構文は、ドキュメントに記載されている通り、他にもいくつか種類があります。

(1.3) sh 関数は Perl の system 関数と同義です。即ち、シェルコマンドを実行します。

実行結果

ビルドを実行すると、以下のように出力されます。

% daiku
[LOG] Building Task: default
Hello, world!

ここで、タスク名である default は既定値であるため、省略することができます。
上は daiku default と実行しても同じ結果になります。

C言語のコードをビルドしてみる

わざわざ Daiku でやる必要はないかと思いますが、本家サンプルにもある C言語プログラムのビルドをやってみます。

ここでは、ソースファイル hello.c からオブジェクトファイル hello.o を経由して実行ファイル hello を生成します。

Daikufile

desc 'build hello binary';
task 'default' => 'hello';

file 'hello' => 'hello.o' => sub { # (2.1)
    my $file = shift; # (2.2)
    sh sprintf('gcc -o %s %s', $file->dst, $file->deps->[0]); # (2.3)
};

rule '.o' => '.c' => sub { # (2.4)
    my ($rule, $dst, @srcs) = @_; # (2.5)
    sh sprintf('gcc -o %s -c %s', $dst, $srcs[0]); # (2.6)
};

desc 'clean up';
task 'clean' => sub {
    unlink $_ for ('hello', 'hello.o');
};

以下、この Daikufile の内容を解説します。

(2.1) file <Str1> => <Str2> => <CodeRef> という構文が登場しました。
<Str1> のファイルを生成するタスクの一種と見なすことができます。
このタスクでは <CodeRef> のコードが実行されます。<CodeRef> の実行によって、<Str1> のファイルが生成されることが期待されます。

また、このタスクは <Str2> のタスクに依存しています。即ち、<Str1> を生成するこのタスクよりも先に、依存関係によって <Str2> のビルドが実行されます。

(2.2) $file には Daiku::File オブジェクトが渡されます。

(2.3) $file->dst は生成ファイル、$file->deps は依存タスクのリストです。
実行されるコマンドは gcc -o hello hello.o となります。

さて、ここで hello タスクが依存している hello.o という名前のタスクはこの Daikufile には明記されていません。
hello.o のタスクは続く rule 構文で表される Suffix Rules によって、解決されています。

(2.4) rule <Str1> => <Str2> => <CodeRef> 構文は (2.1) と似ていますが、<Str1>, <Str2> にはファイル拡張子が入ります。
この構文は GNU make の Suffix Rules7 と同様な働きをします。
Daiku はこの文によって foo.o を生成するには foo.c が必要で、<CodeRef> のコードを実行すればよいことを知ります。

(2.5) $rule, $dst, @srcs にはそれぞれ Daiku::SuffixRule オブジェクト、出力ファイル名、ソースファイルリスト(この場合1つ)が格納されます。

(2.6) 実行されるコマンドは gcc -o hello.o -c hello.c となります。

実行結果

ビルドを実行すると、次のようになります。

% daiku
[LOG] Building Task: default
[LOG] Processing file: hello
[LOG] Building SuffixRule: hello.o
[LOG] Processing file: hello.c
[LOG]   Building file: hello(0)
% ls -l
-rw-r--r--  1 key-amb  key-amb   376  3 14 03:28 Daikufile
-rwxr-xr-x  1 key-amb  key-amb  8496  3 14 04:06 hello
-rw-r--r--  1 key-amb  key-amb    73  3 14 01:41 hello.c
-rw-r--r--  1 key-amb  key-amb   836  3 14 04:06 hello.o
% ./hello
Hello, world!

daiku clean を実行すると、実行ファイル hello とオブジェクトファイル hello.o を削除できます。

% daiku clean
[LOG] Building Task: clean
% ls -l
-rw-r--r--  1 key-amb  key-amb   376  3 14 03:28 Daikufile
-rw-r--r--  1 key-amb  key-amb    73  3 14 01:41 hello.c

まとめ

以上、簡単な例でしたが、Daiku の基本的な機能を解説しました。
他にも、Ruby rake 相当の namespace 分割機能もあるようです。

プロジェクトにおいて定形作業が煩雑になっている場合や、一連のジョブ実行を定型化したいような場合、Daiku の導入を検討する価値はあると思います。

補遺

".PHONY task" について

task 構文について、README.md には .PHONY task という記載があります。
これは、GNU make 由来8の表現で、「ビルドによってファイルを生成せず、指定された際に必ず実行されるタスク」のことです。

make に慣れている人はわかると思いますが、慣れてないと「何のこっちゃ」と思う人もいるかな、ということで触れておきました。

脚注

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3