Dalam tutorial ini, kita akan melihat bagaimana pengembang Go dapat menggunakan Makefile untuk mengembangkan aplikasi mereka sendiri.
Apa itu Makefile?
Makefile adalah alat otomatisasi yang sangat berguna yang dapat Anda gunakan untuk menjalankan dan membangun aplikasi tidak hanya di Go, tetapi juga di sebagian besar bahasa pemrograman lainnya.
Ini sering terlihat di direktori root dari banyak aplikasi Go di Github dan Gitlab. Ini banyak digunakan sebagai alat untuk mengotomatisasi tugas-tugas yang sering menyertai pengembang.
Jika Anda menggunakan Go untuk membuat layanan web, maka Makefile akan membantu menyelesaikan tugas-tugas berikut:
- Otomatis permintaan perintah sederhana, seperti: kompilasi, mulai, berhenti, tonton, dll.
- Kelola variabel lingkungan spesifik proyek. Itu harus menyertakan file .env.
- Mode pengembangan yang secara otomatis dikompilasi pada perubahan.
- Mode pengembangan yang menunjukkan kesalahan kompilasi.
- Menentukan GOPATH untuk proyek tertentu sehingga kami dapat menyimpan dependensi di folder vendor.
- Pemantauan file yang disederhanakan, misalnya, membuat watch run = "go test. / ... "
Berikut adalah struktur direktori khas untuk suatu proyek:
.env Makefile main.go bin/ src/ vendor/
Jika kita memanggil perintah make dalam direktori ini, kita mendapatkan output berikut:
$ make Choose a command run in my-web-server: install Install missing dependencies. Runs `go get` internally. start Start in development mode. Auto-starts when code changes. stop Stop development mode. compile Compile the binary. watch Run given command when code changes. eg; make watch run="go test ./..." exec Run given command, wrapped with custom GOPATH. eg; make exec run="go test ./..." clean Clean build files. Runs `go clean` internally.
Variabel lingkungan
Hal pertama yang kita inginkan dari Makefile adalah memasukkan variabel lingkungan yang kita definisikan untuk proyek. Oleh karena itu, baris pertama akan terlihat seperti ini:
include .env
Selanjutnya, kita tentukan nama proyek, Go folder / file, path ke pid ...
PROJECTNAME=$(shell basename "$(PWD)")
Di sisa Makefile, kita akan sering menggunakan variabel GOPATH. Semua tim kami harus dikaitkan dengan GOPATH dari proyek tertentu, jika tidak mereka tidak akan bekerja. Ini memberikan isolasi bersih dari proyek kami, tetapi pada saat yang sama menyulitkan pekerjaan. Untuk menyederhanakan tugas, kita dapat menambahkan perintah exec yang akan mengeksekusi perintah apa pun dengan GOPATH kita.
Namun, perlu diingat bahwa Anda perlu menggunakan exec hanya jika Anda ingin melakukan sesuatu yang tidak dapat ditulis dalam makefile.
Mode pengembangan
Mode pengembangan harus:
- Bersihkan cache yang dibangun
- Kompilasi kode
- Jalankan layanan di latar belakang
- Ulangi langkah ini ketika kode berubah.
Kedengarannya mudah. Namun, kesulitannya terletak pada kenyataan bahwa kami menjalankan layanan dan pengamat file secara bersamaan. Sebelum memulai proses baru, kita harus memastikan bahwa itu berhenti dengan benar dan bahwa kita tidak melanggar perilaku baris perintah yang biasa ketika menekan Control-C atau Control-D.
start: bash -c "trap 'make stop' EXIT; $(MAKE) compile start-server watch run='make compile start-server'" stop: stop-server
Kode yang dijelaskan di atas menyelesaikan tugas-tugas berikut:
- Mengkompilasi dan menjalankan layanan di latar belakang.
- Proses utama tidak berjalan di latar belakang, jadi kita bisa menghentikannya menggunakan Control-C.
- Menghentikan proses latar belakang saat proses utama terganggu. perangkap dibutuhkan hanya untuk ini.
- Mengkompilasi ulang dan me-restart server ketika kode berubah.
Di bagian berikut, saya akan menjelaskan perintah-perintah ini secara lebih rinci.
Kompilasi
Perintah kompilasi tidak hanya memanggil kompilasi go di latar belakang - itu menghapus output kesalahan dan mencetak versi yang disederhanakan.
Ini adalah apa yang tampak seperti output baris perintah ketika kami melakukan penyuntingan:

compile: @-touch $(STDERR) @-rm $(STDERR) @-$(MAKE) -s go-compile 2> $(STDERR) @cat $(STDERR) | sed -e '1s/.*/\nError:\n/' | sed 's/make\[.*/ /' | sed "/^/s/^/ /" 1>&2
Server mulai / berhenti
start-server memulai biner yang dikompilasi di latar belakang, menyimpan PID-nya ke file sementara. stop-server membaca PID dan membunuh proses jika perlu.
start-server: @echo " > $(PROJECTNAME) is available at $(ADDR)" @-$(GOBIN)/$(PROJECTNAME) 2>&1 & echo $$! > $(PID) @cat $(PID) | sed "/^/s/^/ \> PID: /" stop-server: @-touch $(PID) @-kill `cat $(PID)` 2> /dev/null || true @-rm $(PID) restart-server: stop-server start-server
Ubah pemantauan
Kami membutuhkan file pengamat untuk melacak perubahan. Saya mencoba banyak, tetapi tidak dapat menemukan yang cocok, jadi saya menulis alat pemantauan file saya sendiri -
yolo . Instal menggunakan perintah:
$ go get github.com/azer/yolo
Setelah instalasi, kami dapat mengamati perubahan dalam direktori proyek, tidak termasuk folder vendor dan bin.
Kami sekarang memiliki perintah arloji yang secara rekursif melacak perubahan ke direktori proyek, dengan pengecualian dari direktori vendor. Kita bisa melewatkan perintah apa saja untuk dijalankan.
Misalnya, mulai panggilan make-start-server ketika kode berubah:
make watch run="make compile start-server"
Kita dapat menggunakannya untuk menjalankan tes atau memeriksa kondisi lomba secara otomatis. Variabel lingkungan akan ditetapkan pada saat runtime, sehingga Anda tidak perlu khawatir tentang GOPATH:
make watch run="go test ./..."
Fitur bagus
Yolo adalah antarmuka webnya. Jika Anda mengaktifkannya, Anda dapat langsung melihat output dari perintah Anda di antarmuka web. Yang perlu Anda lakukan adalah memberikan opsi -a:
yolo -i . -e vendor -e bin -c "go run foobar.go" -a localhost:9001
Buka localhost: 9001 di browser dan segera lihat hasil pekerjaan:

Instalasi Ketergantungan
Ketika kami membuat perubahan pada kode, kami ingin dependensi yang hilang dimuat sebelum kompilasi. Perintah instal akan melakukan pekerjaan untuk kita:
install: go-get
Kami akan mengotomatiskan panggilan instal ketika file berubah sebelum kompilasi, sehingga dependensi akan diinstal secara otomatis. Jika Anda ingin menginstal dependensi secara manual, Anda dapat menjalankan:
make install get="github.com/foo/bar"
Secara internal, perintah ini akan dikonversi ke:
$ GOPATH=~/my-web-server GOBIN=~/my-web-server/bin go get github.com/foo/bar
Bagaimana cara kerjanya? Lihat bagian selanjutnya di mana kami menambahkan perintah Go biasa untuk mengimplementasikan perintah tingkat yang lebih tinggi.
Pergi Perintah
Karena kita ingin menginstal GOPATH di direktori proyek untuk menyederhanakan manajemen dependensi, yang belum secara resmi diputuskan dalam ekosistem Go, kita perlu membungkus semua perintah Go di Makefile.
go-compile: go-clean go-get go-build go-build: @echo " > Building binary..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go build -o $(GOBIN)/$(PROJECTNAME) $(GOFILES) go-generate: @echo " > Generating dependency files..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go generate $(generate) go-get: @echo " > Checking if there is any missing dependencies..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go get $(get) go-install: @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go install $(GOFILES) go-clean: @echo " > Cleaning build cache" @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go clean
Bantuan
Akhirnya, kita memerlukan perintah bantuan untuk melihat daftar perintah yang tersedia. Kami dapat secara otomatis menghasilkan output bantuan yang diformat dengan indah menggunakan perintah sed dan kolom:
help: Makefile @echo " Choose a command run in "$(PROJECTNAME)":" @sed -n 's/^
Perintah berikut memindai Makefile untuk baris yang dimulai dengan ## dan menampilkannya. Dengan begitu, Anda cukup mengomentari perintah tertentu, dan komentar akan ditampilkan dengan perintah bantuan.
Jika kami menambahkan beberapa komentar:
Kami akan mendapatkan:
$ make help Choose a command run in my-web-server: install Install missing dependencies. Runs `go get` internally. start Start in development mode. Auto-starts when code changes. stop Stop development mode.
Versi final
include .env PROJECTNAME=$(shell basename "$(PWD)")