Qu’est ce que Makefiles ?

Les Makefiles sont un outil d’automatisation que vous pouvez utiliser pour créer et exécuter différente taches, non seulement vos applications Go, mais aussi pour la plupart des langages de programmation.

Pourquoi Makefiles plutôt que Go Task ?

Il existe des task runner spécifiques à Go, le plus connu doit être Go Task. Je l’ai utilisé à de nombreuses reprises, il fait le travail. Alors pourquoi utiliser Makefiles à la place ?

  • make est disponible par défaut sur tous les systèmes d’exploitation *Nix (Linux, MacOS, BSD,…).
  • connaître les bases des Makefiles vous sera forcement utile un jour ou l’autre. C’est le task runner utilisé par défaut dans de nombreux langages (C et C++ par exemple) .

Exemple basique de Makefile

Pour l’exemple on va utiliser ce petit bout code Go

package main
import "fmt"
func main() {  
    fmt.Println("Hello Make!")   
}

Pour le compiler on doit exécuter la commande:

go build -o dist/hello

(je compile toujours mes exécutables dans un répertoire dist , ce qui me permet un déploiement plus simple - voir plus bas )

Si je veux l’exécuter:

./dist/hello

Si je veux le compiler et l’exécuter :

go build -o dist/hello && ./dist/hello

Créons un fichier Makefiles pour gérer ces deux taches

build: 
   go build -o dist/hello

run:
   ./dist/hello

Pour compiler en utilisant notre Makefiles la commande sera:

make build

Pour exécuter notre programme:

make run

Combiner les commandes

Vous allez me dire, si c’est juste ça ce n’est pas très utile, et vous aurez raison. Il n’est pas rare par exemple, que dans votre cycle de développement vous soyez amené à souvent compiler et exécuter. Et bien créons une tache pour ça:

dev: build run

En exécutant la commande make dev les deux taches build et run vont être lancées à la suite. SI la premiere échoue, la seconde ne sera pas lancée.

Utilisation de variables

Imaginons par exemple que nous souhaitions compiler pour différents OS

NAME=monprog
VERSION=1.0.0

build:
 GOARCH=amd64 GOOS=darwin go build -o dist/${NAME}-${VERSION}-darwin
 GOARCH=amd64 GOOS=linux go build -o dist/${NAME}${VERSION}-linux
 GOARCH=amd64 GOOS=window go build -o -o dist/${NAME}${VERSION}-window

Exemple complet de fichier Makefiles pour Go

NAME=monprog
VERSION=1.0.0

build:
	GOARCH=amd64 GOOS=darwin go build -o dist/${NAME}-${VERSION}-darwin
	GOARCH=amd64 GOOS=linux go build -o dist/${NAME}-${VERSION}-linux
	GOARCH=amd64 GOOS=window go build -o -o dist/${NAME}-${VERSION}-window

run:
	./dist/${NAME}-${VERSION}-linux

dev:
	go build -o dist/${NAME}
	dist/${NAME}
		
test:
	go test ./...

cover:  
	go test -coverprofile cp.out  
	go tool cover -html=cp.out

lint:  
	golangci-lint run --enable-all

deploy: build
	rsync -vz dist/${NAME}-${VERSION}-linux user@IP:/var/www/${NAME}
	ssh user@IP systemctl restart ${NAME}.service