タスクランナーというと 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 ... のように動かします。
以上。たいしたことない( ..)φメモメモでした。