227
168

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

2016年だけどMakefileを使ってみる

Last updated at Posted at 2016-10-19
1 / 16

この資料はなに?

Makeの良さを伝えるものです

  • CとかC++の持ち物じゃない
  • 普段使うコマンドのショートカットみたいな
  • 2016年でもMakefileは便利

 2016-10-19 19.11.07.png

頑張らないでScala 〜VOYAGE GROUPにおけるアドネットワーク開発の戦略〜 // Speaker Deck


Makeってなに?Makefile???

make(メイク)は、プログラムのビルド作業を自動化するツール。コンパイル、リンク、インストール等のルールを記述したテキストファイル (makefile) に従って、これらの作業を自動的に行う。
出典:https://ja.wikipedia.org/wiki/Make

つまり、自動化のためのツール。


make が生成するのはふつう C のプログラムだが、べつに C のプログラムに限らず、Makefile に書く生成コマンドの書きように よっては、TeX のファイルだろうが、Java のプログラムだろうが 何でも make を利用して作業を軽減することができる。
出典:http://www.unixuser.org/~euske/doc/makefile/

なので、CだろうがC++だろうがScalaだろうが関係ない。


ぐぐるとこんなの出てきて難しそう...

PROGRAM = main
OBJS = main.o
CC = gcc
CFLAGS = -Wall -O2
.SUFFIXES: .c .o

.PHONY: all
all: depend $(PROGRAM)

$(PROGRAM): $(OBJS)
	$(CC) -o $(PROGRAM) $^

.c.o:
	$(CC) $(CFLAGS) -c $<

.PHONY: clean
clean:
	$(RM) $(PROGRAM) $(OBJS) depend.inc

.PHONY: depend
depend: $(OBJS:.o=.c)
	-@ $(RM) depend.inc
	-@ for i in $^; do cpp -MM $$i | sed "s/\ [_a-zA-Z0-9][_a-zA-Z0-9]*\.c//g" >> depend.inc; done

-include depend.inc


何が良いの?

ぼくがおもうMakeのいいところ

  • わざわざインストールしなくていい(はず)
    • デフォルトで入ってる(/usr/bin/make)
  • タブ補完が効く
  • よく使うコマンドを保存出来る
    • .bashrcにaliasはるのとは違う
      • ディレクトリ(プロジェクト)毎にコマンドを用意できるので環境は汚れない
  • よく使うコマンドを共有できる
    • 「配信サーバに対するリクエストってどうやって送ればいいですか?」に応える

サンプル

Makefileはこんな感じ。

show-ip:
        ipconfig getifaddr en0

これを使ってみる。

$ make show-ip
ipconfig getifaddr en0
192.168.0.27

これはshow-ipというタスクでipconfig getifaddr en0というコマンドを実行している。
難しいコマンドをおぼえなくていいし、Makefileの文法も簡単なので学習コストは低い。


書き方

ざっくりとはこれだけ。

<変数宣言>

<タスク名>:
  <実行したいshell>
  
<タスク名>:<必要ファイル名>
  <実行したいshell>

インデントはタブ文字なので注意。
ほんとは変数じゃなくてマクロと呼ばれる。


実行するシェルを標準出力に表示しない方法

実行すると実行するシェルが出力されてしまうので、鬱陶しい場合は@を先頭につける。

show-files:
        ls -lh

show-files-suppress:
        @ls -lh

実行するときは何も変わらない

$ make show-files
ls -lh
total 8
-rw-r--r--  1 petitviolet  staff    51B Oct 15 15:10 Makefile
$ make show-files-suppress
total 8
-rw-r--r--  1 petitviolet  staff    51B Oct 15 15:10 Makefile

変数宣言

Makefileの中では変数を使用することが出来る。

$ cat Makefile
MESSAGE := "HELLO"

hello:
        @echo $(MESSAGE)
$ make hello
HELLO

タスクで使用する際に上書き出来る。

$ make hello MESSAGE=こんにちは
こんにちは

タスク実行に必要なファイルを指定できる

activatorというファイルが存在していれば...みたいなタスクを定義する。

compile: activator
  @echo "Yey!"

ファイルが無いと失敗し、ファイルがあれば成功する。

$ ls
Makefile
$ make compile
make: *** No rule to make target 'activator', needed by 'compile'.  Stop.
$ touch activator
$ make compile
Yey!

順番にタスクを実行するような場合、ファイルの作成を持って成否判定を出来たりして便利!


タスクからタスクを呼ぶ

あるタスクの中から別のタスクを実行することも出来る。

task-a:
	@echo "A"
	@touch a.txt
	@make task-b

task-b: a.txt
	@echo "B"
	@touch b.txt
	@make task-c

task-c: b.txt
	@echo "C"
	@touch c.txt

clean: a.txt b.txt
	@rm a.txt b.txt c.txt
	@echo 'complete!!!'

doit:
	@make task-a
	@make clean

実行するとこんな感じになる。

$ make doit
A
B
C
complete!!!

複数行にわたるコマンドを実行したい時

一行ごとに別のshellとして実行される点に注意。

$ ls
Makefile
$ cat Makefile
make-tmp-file-home:
        @cd ~
        @touch hogehoge
$ make make-tmp-file-home
$ ls
Makefile  hogehoge

これはサブシェルの中でcdして、別のサブシェルの中でtouchしているので、カレントディレクトリでの操作となる。


&&\でつないで1つのシェルとして実行すれば良い。

$ ll $HOME | grep 'hogehoge' | wc -l
       0
$ cat Makefile
make-tmp-file-home:
        @cd ~ && \
        touch hogehoge
$ make make-tmp-file-home
$ ll $HOME | grep 'hogehoge' | wc -l
       1

シェル変数と制御文

上記の点さえ気をつければfor文も書ける。

LENGTH := 3

show-seq:
	@for i in {1..$(LENGTH)}; do \
		echo $$i; \
	done

ここでシェル変数が$$iとなっている点に注意。

227
168
2

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
227
168

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?