Super Unicorn Inkmi Logo

Build Tools for Go

Comparing make, XC, bazel, mage and taskfile

Inkmi is Dream Jobs for CTOs and written as a decoupled monolith in Go, HTMX, Alpinejs, NATS.io and Postgres. I document my adventures and challenges in writing the application here on this blog, tune in again.

Programming languages have their build tools. Java has Maven, Scala has SBT, and Javascript has NPM beside many web build tools. Newcomers to Golang wonder about the build tool for Go. Starting is easy, the go compiler is easier to use than comparable alternatives, to start no build tool is necessary.

All of these

go build
go run
go install

do the job.

When you have more than Go code to build, but tests to run, code to lint etc. the newcomer to Golang asks what now?

At inkmi I’ve started with go build, added bash scripts for linting and deployment and for now I’ve settled with Makefile and make—replacing all bash scripts with make targets.

build:  git-hash
  templ generate ./...
  go build -o bin/ ./...

Here we a have a build target, that depends on another git-hash target. The target needs to generate a-h/templ templates and then build the application. For most people Makefile is enough, it’s easy to use for basic tasks and available on many systems.

Asking around r/Golang, more options popped up:

bazel

bazel was built by Google for large monorepos with many different languages. But works for small projects just fine, and the Go integration seems to be the best language integration in bazel.

goreleaser

Not a build tool for all the project tasks you might have used Makefile for, but a build tool to build Go for many different platforms and operating system targets. It can cross compile, build for Linux packaging like deb and release to GitHub, beside many more targets.

just

just is inspired by make but tries to make it easier and better.

Taskfile

Another one for a better make: “Task is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make.”

It is different because it is using YAML:

version: '3'
tasks:
  hello:
    cmds:
      - echo 'Hello World from Task!'
      silent: true

mage

mage uses Go to define build files

//go:build mage
package main

import (
  "github.com/magefile/mage/sh"
)

// Runs go mod download and then installs the binary.
func Build() error {
  if err := sh.Run("go", "mod", "download"); err != nil {
    return err
  }
  return sh.Run("go", "install", "./...")
}

XC

“The problem xc is intended to solve is scripts maintained separately from their documentation.” So with XC the build file contains its own documentation in Markdown

## tag

Deploys a new tag for the repo.

Requires: test

'''
export VERSION=`git rev-list --count HEAD`
echo Adding git tag with version v0.0.${VERSION}
git tag v0.0.${VERSION}
git push origin v0.0.${VERSION}
'''

script

"script is a Go library for doing the kind of tasks that shell scripts are good at: reading files, executing subprocesses, counting lines, matching strings, and so on."

Can be used together with mage

So here are many different options for build tools with Go. Start with go build, then use the one that suits you best—might be plain old make.

About Inkmi

Inkmi is a website with Dream Jobs for CTOs. We're on a mission to transform the industry to create more dream jobs for CTOs. If you're a seasoned CTO looking for a new job, or a senior developer ready for your first CTO calling, head over to https://www.inkmi.com and tell us what your dream job looks like!

Other Articles

©️2024 Inkmi - Dream ❤️ Jobs for CTOs | Impressum