すごくシンプル過ぎるビルドシステム書いた

2 日も空いちゃったけど、書いた。
いつしか加わってしまった Emacsmarkdown-mode の末尾の半角スペース 2 つが 2 つのアンダーバーになってしまう クソ現象で markdown-mode が使えないため、text-mode を使っている。
と思ったら、Emacs を再起動したところ、治った。

そんなことはともかく、こういうへろーわーるどな C 言語のソースコードコンパイルしていきたい。

// examples/hello.c
#include <stdio.h>

int main() {
    printf( "Hello, World!" );

    return 0;
}

こういう Build.p6 をソースツリーのトップに置き、このファイルを叩くことで基本的にビルドを行うことができる:

# examples/Build.p6
use v6;

use IO::Glob;
use Build::Simple;

my @sources = glob( './*.c' );

my @objects = gather for @sources -> $source {
    take compile $source;
}

link 'hello', |@objects;

&compile&linkBuild::Simple モジュールに入っている。
お好みで IO::Globuse するととっても便利である。
叩く時は以下のようにする:

% perl6 -I../lib ./Build.p6

-I../lib は perl6 が lib/Build/Simple.pm6 を探しやすくするために必要である。
が、perl6/ecosystem に入った暁には zef install Build::Simple すれば必要なくなる。

ということで、lib/Build/Simple.pm6 は以下の通り。
今回は is export と書くことで Build::Simple::compile と書かなくて良くなるということがわかった。

# lib/Build/Simple.pm6
use v6;

unit module Build::Simple;
    
sub compile($dependency) is export {
    my $target = $dependency.extension: 'o';

    say "compiling {$dependency}";
    shell [ 'gcc', '-c', $dependency, '-o', $target ].join(' ');

    $target;
}

sub link($target, *@objects) is export {
    say "linking {$target}";
    shell [ 'gcc', |@objects, '-o', $target ];
}

%*ENV<CC> とかでコンパイラのコマンドを環境変数からとってきたりしたいなーなどと思っている。
ということで、また次回。