ããã¯ããªã«ãããããŠæžãããã®ïŒ
Goã§ã®ãã«ãããŒã«ã¯ãmakeã䜿ãããšãå€ããšèããã®ã§ã
ããã€ããGoã§æžãããæåãªOSSãèŠãŠã¿ããšã確ãã«Makefileã眮ãããŠããŸãã
https://github.com/prometheus/prometheus/blob/v2.24.1/Makefile
https://github.com/hashicorp/terraform/blob/v0.14.5/Makefile
https://github.com/moby/moby/blob/v20.10.2/Makefile
https://github.com/kubernetes/kubernetes/blob/v1.20.2/build/root/Makefile
Goã®å匷ãå§ããŠããããšã§ããããããæ©ã«å°ãèŠããŠã¿ããããªããšã
makeèªäœã¯äœ¿ã£ãããšããããŸãããã ããã§ã«çšæãããŠããMakefileãšæé ã«åŸããmakeãmake installãšãã
å®è¡ããŠããã ãã§ããã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã§ãã
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.1 LTS Release: 20.04 Codename: focal $ uname -srvmpio Linux 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
makeèªäœã¯ãã€ã³ã¹ããŒã«æžã¿ã§ãã
$ make --version GNU Make 4.2.1 ãã®ããã°ã©ã 㯠x86_64-pc-linux-gnu çšã«ãã«ããããŸãã Copyright (C) 1988-2016 Free Software Foundation, Inc. ã©ã€ã»ã³ã¹ GPLv3+: GNU GPL ããŒãžã§ã³ 3 以é <http://gnu.org/licenses/gpl.html> ããã¯ããªãŒãœãããŠã§ã¢ã§ã: èªç±ã«å€æŽããã³é åžã§ããŸã. æ³åŸã®èš±ãéãããç¡ä¿èšŒãã§ã.
make
makeã«ã€ããŠèŠãŠãããšããããšã§ããŸãã¯äžæ¬¡ãªãœãŒã¹ãããããŸãããã
GNUãããžã§ã¯ããèŠã«è¡ããŸãã
Software - GNU Project - Free Software Foundation
ãã¡ãã«makeã®èª¬æããããŸããã¡ãã£ãšæŠèŠãèŠãŠã¿ãŸããããæ£ç¢ºã«ã¯ãGNU Makeã§ããã
Make - GNU Project - Free Software Foundation
makeã¯ãããã°ã©ã ã®ãœãŒã¹ãã¡ã€ã«ãããå®è¡å¯èœãã¡ã€ã«ããã®ä»ã®éãœãŒã¹ãã¡ã€ã«ã®çæãã³ã³ãããŒã«ããããŒã«ã§ãã
ããã°ã©ã ããã«ãããããã®æ¹æ³ã¯ãmakefileãšåŒã°ãããã¡ã€ã«ã«èšè¿°ããŸãã
makeã®æ©èœã¯ã以äžã«ãªããŸãã
- ããã±ãŒãžã®ãã«ãæ¹æ³ãã€ã³ã¹ããŒã«æ¹æ³ãmakefileã«èšè¿°ãããŠããããããŠãŒã¶ãŒã¯è©³çްãç¥ããªããŠããããã®ã¿ã¹ã¯ãå®è¡ã§ãã
- makeã¯ãã¡ã€ã«ã®æŽæ°ãææ¡ããååã®ãã«ããã倿Žããã£ããã¡ã€ã«ã«åºã¥ããŠåŠçãè¡ããå¿ èŠãªãã¡ã€ã«ãæŽæ°ãã
- èšèªéäŸåã§ãmakefileå ã§æå®ãããã·ã§ã«ã³ãã³ããå®è¡ãã
- makeã¯ããã±ãŒãžã®äœæä»¥å€ã«ããã€ã³ã¹ããŒã«ãã¢ã³ã€ã³ã¹ããŒã«ãªã©ãæ§ã ãªåŠçãè¡ãããããšãã§ãã
makefileã«ã¯ããœãŒã¹ã³ãŒããããã«ãçµæãçæããããã®ãäžé£ã®ã«ãŒã«ãæžããŸãããã®æãã«ãŒã«ã«ã¯äŸåé¢ä¿ãæããã
ããšãã§ããŸãã
以äžã¯ãç°¡åãªã«ãŒã«ã®æ§æã§ãã
target: dependencies ...
commands
...
makefileå ã«ã¯ã«ãŒã«ïŒtargetïŒãæžããmakeã§ã©ã®ã«ãŒã«ãå®è¡ããããæå®ããããšãã§ããŸãã
âŠãšããã®ããåºæ¬çãªè©±ã®ããã§ããã
makeã«ã€ããŠã®è©³çްã¯ãããã¥ã¢ã«ãèŠãŠããããšã«ãªããŸãã
GNU Make Manual - GNU Project - Free Software Foundation
https://www.gnu.org/software/make/manual/make.html
ã§ã¯ãããããèŠãªããç°¡åã«è©ŠããŠãã£ãŠã¿ãŸãããã
If you are new to make, or are looking for a general introduction, read the first few sections of each chapter, skipping the later sections.
ã¯ãã
The exception is the second chapter, An Introduction to Makefiles, all of which is introductory.
ã€ãŸããåããŠã®äººã¯2ç« ãèªã¿ãªãããšããããšã®ããã§ãã
ã¯ãããŠã®Makefile
ãšããããã§ããã¡ããèŠãªããå§ããŠãããŸãã
åçŽãªmakefileã¯ã以äžã®ãããªã·ã³ãã«ãªã«ãŒã«ã§æ§æãããŸãã
target ⊠: prerequisites âŠ
recipe
âŠ
âŠ
ããã§ãã¿ãŒã²ããïŒtargetïŒã«ã¯å®è¡å¯èœãã¡ã€ã«ã®ååããªããžã§ã¯ããã¡ã€ã«ãã¢ã¯ã·ã§ã³ã®ååãæå®ããŸãã
main.oãcleanãinstallãbuildãªã©ã§ããã
åææ¡ä»¶ïŒprerequisitesïŒãšããŠãå¥ã®ã¿ãŒã²ãããæå®ããããšãã§ããŸããããã¯ã¿ãŒã²ããéã®äŸåé¢ä¿ã
衚ããŸãã
ã¬ã·ãïŒrecipeïŒã¯ããã®ã¿ãŒã²ããã§å®éã«è¡ãåŠçïŒã³ãã³ãïŒãèšè¿°ããŸãã
泚æç¹ãšããŠãã¬ã·ãã®å é ã«ã¯ã¿ããé 眮ããå¿ èŠããããŸãã
å®éã«ãmakefileãæžããŠã¿ãŸãããã
Makefile
step1: step2 step4 echo 1 echo one step2: step3 echo 2 step3: echo 3 \ three step4: echo 'four!!'
makefileã¯Makefileãšããååã§makeã³ãã³ãã¯èªèããŸããã-fãªãã·ã§ã³ã§å¥ã®ååãæå®ããããšãã§ããŸãã
step1ã¯step2ãstep4ãåæã«ããŠããŠãstep2ã¯step3ãåæã«ããŠããŸããstep3ã«ã¯åææ¡ä»¶ã¯ãããŸããã
step1ã«ã¯è€æ°ã®ã³ãã³ãïŒã¬ã·ãïŒãæžããŠããŸããstep3ã¯ãã¬ã·ããç¶ç¶è¡ã«ããŠããŸãã
ãã®ç¶æ
ã§ãmakeã³ãã³ããå®è¡ããŠã¿ãŸãã
$ make echo 3 \ three 3 three echo 2 2 echo 'four!!' four!! echo 1 1 echo one one
step3 â step2 â step4 â step1ãšããå®è¡é ã«ãªããŸããã
ãªããšãªããäŸåé¢ä¿ã解決ãã€ã€å®è¡ããŠããã®ãããããšæããŸãã
makeã³ãã³ãã®åŒæ°ãšããŠã¿ãŒã²ãããæå®ããããšã§ãåã¿ãŒã²ããåäœïŒãšäŸåããã¿ãŒã²ããïŒããšã«ãå®è¡ã§ããŸãã
$ make step3 echo 3 \ three 3 three $ make step4 echo 'four!!' four!! $ make step2 echo 3 \ three 3 three echo 2 2
ãšããã§ãåã«makeãšæå®ããæã¯ãstep1ã®ã¿ãŒã²ãããå®è¡ãããããã«æããŸãã
ãã®çç±ã¯ã以äžã«æžããŠãããŸãã
By default, make starts with the first target (not targets whose names start with â.â). This is called the default goal.
ã€ãŸããæåã®ã¿ãŒã²ãããå®è¡ãããããã§ãããããããã©ã«ããŽãŒã«ãšåŒã³ãŸãããšã
ããããªãŒããŒã©ã€ãããæ¹æ³ãšããŠãã³ãã³ãã®åŒæ°ã§æå®ããæ¹æ³ïŒå
ã»ã©äœ¿ã£ãæ¹æ³ïŒãš.DEFAULT_GOALãšããç¹æ®å€æ°ã
äœ¿ãæ¹æ³ãããããã§ãã
You can override this behavior using the command line (see Arguments to Specify the Goals) or with the .DEFAULT_GOAL special variable (see Other Special Variables).
詊ãã«ã.DEFAULT_GOALãæå®ããŠã¿ãŸãããã
Makefile
.DEFAULT_GOAL := step4 step1: step2 step4 echo 1 echo one step2: step3 echo 2 step3: echo 3 \ three step4: echo 'four!!'
確èªã
$ make echo 'four!!' four!!
æç€ºçã«ã¿ãŒã²ãããæå®ããªãå Žåã«ãå®è¡ãããã¿ãŒã²ãããå€ãããŸãããã
ãã«ãã§äœ¿ããããªmakefileã®äŸãèŠãŠã¿ããšãã¿ãŒã²ããã®ååã¯ãã¡ã€ã«åã«ãªã£ãŠãããããŸãã
edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o
makefileã¯ããã®ãã¡ã€ã«åãã¿ãŒã²ããã«ããããšã§äŸåé¢ä¿ã衚çŸããŸãã
ä»åäœæããstep1ã®ãããªã¿ãŒã²ããã¯ããã¡ã€ã«ã§ã¯ãããŸãããäžèšã®äŸã ãšcleanãããã§ããã
ãã®ãããªãã¡ã€ã«ã§ã¯ãªãã¿ãŒã²ãããPhonyã¿ãŒã²ãããšåŒã¶ããã§ãã
Phonyã¿ãŒã²ããã¯ããã¡ã€ã«åã§ã¯ãªãã¿ãŒã²ããã®ããšã§ããããã䜿ãçç±ã¯ãåãååã®ãã¡ã€ã«ãšã®ç«¶åãåé¿ãããããšã
ããã©ãŒãã³ã¹ã®åäžã®ããã§ãã
ã¬ã·ããã¿ãŒã²ãããšãªããã¡ã€ã«ãäœæããªãå Žåãã¿ãŒã²ãããåäœæããã床ã«ã¬ã·ããå®è¡ãããããã§ãã
ãŸããã¿ãŒã²ãããšåãååã®ãã¡ã€ã«ããããšããŸãæ©èœããªããªãããã§ãã
ãšãããšãä»åã®makefileã¯ãã¹ãŠPhonyã¿ãŒã²ãããªã®ã§ã以äžã®ããã«ããã®ãæ£è§£ã§ããããã
Makefile
# .DEFAULT_GOAL := step4 .PHONY: step1 step1: step2 step4 echo 1 echo one .PHONY: step2 step2: step3 echo 2 .PHONY: step3 step3: echo 3 \ three .PHONY: step4 step4: echo 'four!!'
倿°ã䜿ã
makefileå ã§ã¯ã倿°ã䜿ãããšãã§ããŸãã
Variables Make Makefiles Simpler
ãããªæãã§ã=ã§å®çŸ©ããŸããåç
§ã¯$(倿°)ã§ãã
Makefile
ECHO_COMMAND = echo MESSAGE = 'Hello World' .PHONY: hello hello: $(ECHO_COMMAND) $(MESSAGE)
確èªã
$ make echo 'Hello World' Hello World
ã¡ãªã¿ã«ããã®å€æ°ã¯å€éšããäžæžãããããšãã§ããŸãã
$ make MESSAGE=hello echo hello hello
ããã¯ãmakeã³ãã³ãèªèº«ã«äžæžãããŠããã£ãŠããŸãã
ç°å¢å€æ°ã§äžæžãããå Žåã¯ãåçŽã«æå®ããã ãã§ã¯ãã¡ã§ãã
$ MESSAGE=hello make echo 'Hello World' Hello World
-eãªãã·ã§ã³ãä»ããå¿
èŠããããŸãã
$ MESSAGE=hello make -e echo hello hello
Variables from the Environment
倿°ã«ã€ããŠã¯ãããã¥ã¡ã³ãã®ãã®ããããèŠãŸãããã
ãŸããèªåã§å®çŸ©ããã倿°ããããŸãã
倱æããŠãçµäºãããªã
ããã©ã«ãã§ã¯ãã¿ãŒã²ããå
ã®ã³ãã³ãã倱æãããšãã®ã¿ãŒã²ããã¯å€±æããŸãããã®æåã倿Žãã倱æããŠã
ç¶ç¶ããããã«ããã«ã¯å¯Ÿè±¡ã®ã³ãã³ãã®å
é ã«-ãä»äžããŸãã
clean: -rm -f *.o
Goãããžã§ã¯ãã§makefileãæžããŠã¿ã
æåŸã«Goãããžã§ã¯ãã§ç°¡åã«è©ŠããŠã¿ãŸãããã
Goã®ããŒãžã§ã³ã
$ go version go version go1.15.7 linux/amd64
ãããžã§ã¯ãäœæã
$ go mod init app go: creating new go.mod: module app
go.mod
module app go 1.15
ãœãŒã¹ã³ãŒããäœæã
main.go
package main import ( "fmt" ) func main() { fmt.Println(GetMessage()) } func GetMessage() string { return "Hello World!!" }
ãã¹ãã³ãŒããäœæã
main_test.go
package main import ( "testing" ) func TestGetMessage(t *testing.T) { if GetMessage() != "Hello World!!" { t.Error("test failed!") } }
makefileãæžããŸãã
Makefile
EXECUTABLE_FILE = app
.PHONY: build
build: format lint test
go build
.PHONY: run
run: format
go run main.go
.PHONY: format
format:
gofmt -w -d .
.PHONY: lint
lint:
go vet ./...
.PHONY: test
test:
go test ./...
.PHONY: clean-testcache
clean-testcache:
go clean -testcache
.PHONY: clean
clean:
rm $(EXECUTABLE_FILE)
ããã©ã«ãã§ã¯ãbuildã¿ãŒã²ãããå®è¡ããŸããã¿ãŒã²ããã®äŸåé¢ä¿ããããã©ãŒãããããŠgo vetããããŠããã¹ããå®è¡ããŠ
å®è¡å¯èœãã¡ã€ã«ã®çæãŸã§è¡ããŸãã
$ make gofmt -w -d . go vet ./... go test ./... ok app 0.002s go build
ã§ãããã£ããã¡ã€ã«ã®å®è¡ã
$ ./app Hello World!!
cleanããã¡ãã¯åçºã®ã¿ãŒã²ããã§ãã
$ make clean rm app
runããã©ãŒããããšããã°ã©ã ã®å®è¡ãå«ãŸããŸãã
$ make run gofmt -w -d . go run main.go Hello World!!
äŸåããã¿ãŒã²ãããé æ¬¡å®è¡ããŠããéäžã§ãããã¿ãŒã²ããã倱æãããšããã§åæ¢ããŸããããšãã°ãä»åã®ããã©ã«ãã¿ãŒã²ããã
å®è¡ããŠãgo testã倱æããå Žåã¯ãããªæãã«ãªããŸãã
$ make
gofmt -w -d .
go vet ./...
go test ./...
--- FAIL: TestGetMessage (0.00s)
main_test.go:9: test failed!
FAIL
FAIL app 0.002s
FAIL
make: *** [Makefile:21: test] ãšã©ãŒ 1
ãŸãã-nãä»ãããšå®éã«ã¯åŠçãè¡ããã«ã©ã®ãããªã¿ãŒã²ãããå®è¡ããããã衚瀺ããŠãããŸãã
$ make -n gofmt -w -d . go vet ./... go test ./... go build $ make -n test go test ./... $ make -n run gofmt -w -d . go run main.go
ãªããšãªããé°å²æ°ã¯ããã£ãæ°ãããŸãã
ããšã¯OSSã§äœ¿ãããŠããmakefileãçºãããããŠãèŠããŠãããŸãããã