Upload
emasaka
View
764
Download
1
Embed Size (px)
DESCRIPTION
Citation preview
GNU make 4.0に何かいる
@emasaka
GNU make 4.0登場
● 10/8リリース● 主な新機能
– --output-sync:並列実行で出力が混ざるのを防ぐ
– --trace:実行するコマンドを出力
– Guileを組み込める
Guile?
● GNUのSchemeインタープリタ● アプリ組み込みが主な目的
– TclとかLuaとかmrubyとかと同類
ブログにも書いた
やってみる1
● Guileをインストールしておく– $ sudo apt-get install guile-2.0 guile-2.0-devs
● 「guile-2.0」パッケージはなくてもいいと思うけど、Schemeコードの動作確認のため
やってみる2
● GNU make 4.0のソースをもってきて展開
● ./configure– このときにGuile(ライブラリ)が入っていると、makeの
Guileサポートが有効になる● おそらくLinuxディストロでは無効になるのでは?
– --with-guile=noで明示的に無効に
やってみる3
● $ make● $ ldd ./make | grep guile
libguile-2.0.so.22 => /usr/lib/libguile-2.0.so.22 (0x00007f6482291000)
確認
● .FEATURES変数に“guile”が入っていればOK
$ cat features.mkall: @echo $(.FEATURES)$ ./make f features.mktargetspecific orderonly secondexpansion elseif shorteststem undefine oneshell archives jobserver outputsync checksymlink guile load
使いかた
● $(guile 〜)関数
● ようは$(shell 〜)関数でシェルを呼ぶのといっしょ
例1:とりあえず出力
all:echo $(guile '("Hello, World!"))
例2:なんかSchemeっぽいの
sexp = (map (lambda (x) (+ x 3)) (iota 10))
all:@echo $(guile $(sexp))
例3:FizzBuzz(shell版)
all: $(shell seq 1 1 100)
$(shell seq 3 3 100):@echo Fizz
$(shell seq 5 5 100):@echo Buzz
$(shell seq 15 15 100):@echo FizzBuzz
.DEFAULT:@echo $@
http://d.hatena.ne.jp/eel3/20110924/1316791928 より
例3:FizzBuzz(guile版)
all: $(guile (usemodules (srfi srfi1))) $(guile (iota 100 1 1))
$(guile (iota 100 3 3)):@echo Fizz
$(guile (iota 100 5 5)):@echo Buzz
$(guile (iota 100 15 15)):@echo FizzBuzz
.DEFAULT:@echo $@
例3:FizzBuzz(実行時間)
$ time ./make f fbscm.mk >& /dev/null./make f fbscm.mk >&/dev/null 0.10s user 0.06s system 47% cpu 0.337 total$ time ./make f fbsh.mk >& /dev/null./make f fbsh.mk >&/dev/null 0.05s user 0.04s system 35% cpu 0.258 total
shell版のほうが速い!
例4:SchemeでmakeのDSLdefine dsl(usemodules (srfi srfi1))
(define targets '())
(define (showtargets) (stringjoin (reverse targets) "\n") )
(definemacro (push! place item) `(set! ,place (cons ,item ,place)) )
(define (mklist>str lst) (stringjoin (map symbol>string lst)) )
(definemacro (deftarget tgt dep . cmds) (push! targets
(format #f "~a:~a~a" tgt (mklist>str dep) (fold (lambda (x r)
(stringappend r "\n\t" (mklist>str x))) "" cmds )) ))
(deftarget all (foo) (@./foo))
(deftarget foo (foo.c) (cc foo.c o foo) )endef
dummy := $(guile $(dsl))$(guile (gmkeval (showtargets)))