タスクランナーというと gulp
とかなんかそこらへんを使う人が増えているが、やっぱり古きよき make
コマンドが手軽だ。しかし、make
にも問題がある。
- ひとつの
Makefile
を異なるOS上でもきちんと動作させるのがめんどくさい - ただのタスクランナーにしては文法がめんどくさい
2.はどうにもならないので(どうにもならないんかい!)、前者の1.で「WindowsでもUNIX系OSでも安心して動く Makefile
の書き方」をメモしておく。といっても「すげーでっけープロジェクト用の make
」の話ではないのですごく浅いです。
make
は、
$ make -v
GNU Make 4.1
Built for x86_64-unknown-cygwin
を例にしているが、GNU Make ならだいたいOKというゆるふわな感じで。
とりあえず例
# UTF-8, LF
FILES_TO_CLEAN = key.cgi
CPANM = cpanm
RM = rm -f
ifeq ($(OS),Windows_NT)
CPANM = cpanm.bat
RM = cmd.exe /C del
endif
.PHONY:
all installdeps clean
all: installdeps clean
installdeps:
$(CPANM) --installdeps .
clean:
-$(RM) $(FILES_TO_CLEAN)
- Perlスクリプトの配布用
-
installdeps
ターゲットで必要なCPAN
モジュールをインストールできる -
clean
ターゲットで、動作後に同じディレクトリに作成されるゴミを削除できる
注目ポイント
あ、ちなみにインデントがハードTABだというのは当然です…。
1. 文字コードはUTF-8、改行はLF
文字コードはもちろんだが、改行は「とりあえずWindowsではCR+LFでもオッケーでしょ?」とか思ってるとなぜかハマる。
2. 使用コマンドはラッパ変数に定義しておく
rm
とか cpanm
とか、そういうコマンドはめんどうでも基本的に RM
などの変数にラッパ的に定義しておき $(RM)
で呼び出す。デフォルトでは UNIX 系OS側のコマンドを入れておくといい。だって、だいたいの人は Cygwin か MingW 入れてるじゃろ?
3. OSの判定
ifeq ($(OS),Windows_NT)
~ endif
で「Windowsかどうか」の判定をおこない、条件節内の命令を実行できる。ここで RM
や CPANM
などのラッパ変数をOSに適したコマンドに再定義しておく。
4. Windows では .bat
や .exe
まで指定するとラクになる
この Makefile
では cpanm
を Windows では cpanm.bat
に再定義している。なぜか。
- Cygwin の
make
で実行しつつ Perl はActivePerl
を使っている場合、-
make
->/cygdrive/c/perl/site_perl/bin/cpanm
を呼び出す- Cygwin側の Perl が cpanm スクリプトを実行するとおかしなことになる
- ActivePerl側の Perl が上記パスのスクリプトを読み込もうとしたときも「
/cygdrive
ってなんだよ」とおかしなことになる
-
から。説明めんどくさいね。どっちにしても Windows では Windows の本来の実行ファイルを呼び出そうとしているのか、それとも Cygwin などの実行ファイルを呼び出そうとしているのかを配慮し、前者なら .bat
や .exe
をつけたほうが困らないということですな。
5. Windows コマンドプロンプトのコマンドは cmd.exe
経由で実行
RM = cmd.exe /C del
のような部分。
Windows 標準では当然 rm
コマンドなどないので「RM = del
としておけばいいだろ」と思うのだが、それでは動かない。なぜならば! del
コマンドはコマンドプロント(cmd.exe
)の内部実装コマンドだからです。
あれね。UNIX系OSで言うところの、echo
がシェルの内部コマンドだったり外部プログラムだったりするやつね。
ということで、コマンドプロントの内部実装コマンドは、cmd.exe /C ...
のように動かします。
以上。たいしたことない( ..)φメモメモでした。