aarbor
aarbor

Reputation: 1534

Makefile for GoLang Cross Compilation

I'm trying to create a Makefile for cross compiling a go binary. As you can see below, there's a lot of repetition. I also don't like that I have to re-invoke make with the arguments, rather than it matching an existing target already. Is there a more idiomatic way of achieving what I am trying to do?

I tried using wildcard targets to deduplicate some logic, for example

windows-%: app.config
    make os=windows arch=$*

but whenever I try and run it with this (i.e. make windows-arm64), I get back

make: Nothing to be done for `windows-arm64'.

EDIT: updated makefile after @norbert's suggestions. I think the only remaining complication is having to re-invoke make from within the target

tags =
executable_base = app
executable_ext =

# go version prints, i.e.: go version go1.18.5 darwin/arm64
# so we can use that as an os-independent way to figure out our current os and arch
os_arch = $(word 4, $(shell go version))
os = $(word 1,$(subst /, ,$(os_arch)))
arch = $(word 2,$(subst /, ,$(os_arch)))


ifeq (${os}, windows)
    executable_ext = .exe
endif


supported_distributions := $(shell go tool dist list | grep -E 'linux|windows|darwin' | grep -E 'amd64|arm64|386')


.PHONY: build all $(supported_distributions)

$(supported_distributions): output_dir = dist/${os}/${arch}
$(supported_distributions):
    make build os=$(word 1,$(subst /, ,$@)) arch=$(word 2,$(subst /, ,$@)) output_dir=${output_dir}

build: output_dir = dist/${os}/${arch}
build: app.config
    GOOS=${os} GOARCH=${arch} go build -tags "${tags}" -o ${output_dir}/${executable_base}${executable_ext} main.go
ifneq (${output_dir},.)
    cp -n ocrunner.config ${output_dir}/ || true
endif

all: $(supported_distributions)

app.config:
    go run cli/main.go create_config

Upvotes: 0

Views: 921

Answers (1)

Norbert
Norbert

Reputation: 6084

Not an idiomatic way. Shorter might be possible

go tool dist list

Gets you all builds.

By now just looking for the first 2 lowercase characters of the OS in the list against the ${os}, look for the arch as indicated, and at least it becomes responsive to the changes in golang capabilities.

As for Darwin 386: That is probably your only exception (Don't know where you would hit that one though)

Upvotes: 1

Related Questions