英文:
Makefile for GoLang Cross Compilation
问题
我正在尝试为交叉编译Go二进制文件创建一个Makefile
。如下所示,有很多重复的部分。我也不喜欢我必须重新使用带参数的make
命令,而不是匹配一个已存在的目标。有没有更符合惯用方式的方法来实现我想做的事情?
我尝试使用通配符目标来消除一些逻辑重复,例如:
windows-%: app.config
make os=windows arch=$*
但是每当我尝试以这种方式运行它(即make windows-arm64
),我会得到以下结果:
make: Nothing to be done for `windows-arm64'.
编辑:根据@norbert的建议更新了makefile
。我认为唯一剩下的复杂之处是在目标内部重新调用make
。
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
英文:
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
答案1
得分: 1
不是一个惯用的方式。可能有更简短的方法。
go tool dist list
可以获取所有的构建。
现在只需要在列表中查找${os}的前两个小写字符,查找指定的架构,至少它能够对golang能力的变化做出响应。
至于Darwin 386:那可能是你唯一的例外(不知道你会在哪里遇到这个问题)。
英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论