Working with Makefiles
Introduction
make is a build automation tool that I had honestly never used until working with Go. Not to say I had not heard of it or seen a makefile floating around in repositories before, but I just really did not understand the “why” behind it. Chalk it up to my time in tech being in the JavaScript ecosystem where we use scripts in the package.json to run build tools, test suites, etc via npm, yarn, pnpm, or now bun. So let’s explore how a makefile works and what we can do with it.
What is a Makefile?
A makefile is simply put a file that contains the rules and dependencies that specify how the project should be built.
target: dependencies
commands- target: is the file or action that needs to be created.
- dependencies: are the files or conditions that the target depends on.
- commands: are the shell commands or other build tools to execute in order to create the target.
Below would be a simple example of how to use a makefile in a Go project:
build:
# Build the binary program and output it to bin/api
go build -o bin/api
# With the prerequisite of "build" `make` will determine if there
# has been changes to the "build" target before executing the command
# If there has then ./bin/api is new and `make` will run the program.
# If not then there is no reason to recompile the program & execute it.
# Instead `make` will just run the existing binary in ./bin/api
run: build
# Run the program
./bin/api
test:
# Run the test suite in verbose mode
go test -v ./...
# .PHONY will prevent `make` from confusing the target with a file name.
.PHONY clean
clean:
rm -rf ./bin/apiAnd to execute the targets from the makefile we can call make + the target we wish to run.
make build
make run
make test You will notice that upon running our targets we see the underlying command get printed out to the terminal. If you don’t want that to happen you can simply prefix the command with @:
build:
@go build -o bin/api
run: build
@./bin/api
seed:
@go run scripts/seed.go
test:
@go test -v ./...Wrap Up
There is honestly a whole lot more to make and makefiles. This is what I have encountered while working with Go and kind of the basics I have adopted in my projects. If you really want a deep dive into this topic I highly suggest going through this free tutorial or you can read the GNU Make docs.
Until next time,
Cody