Makefile 将目标作为两个列表的叉积

hue*_*ose 4 makefile gnu-make

我花了一天的大部分时间试图弄清楚这一点。我想使用 make 来构建一个具有不同操作系统目标和多个二进制文件的 golang 项目。我想我想使用 gnu make

我精简的 Makefile 看起来像:

main= mailworker websocket worker init
os= linux freebsd darwin

all: $(main)

$(main): ensure_build_path
    @echo "Build $@ Version: $(GIT_REV)"
    @rm -rf $(BUILD_PREFIX)/$@
    GO111MODULE=on GOARCH=amd64 $(GO) build  -o $(BUILD_PREFIX)/$@ ./bin/$@/$@.go
Run Code Online (Sandbox Code Playgroud)

现在我想添加GOOS=$(os)到构建命令/为每个主要的 X os 组合生成一个目标。我的测试/ lern Makefile 看起来像:

os=linux freebsd darwin
main=mailworker websocket worker init

define build_template =
t:=$(addprefix $(1), $(2))
$(info $(t))
$(t):
    @echo $(1) $(2) $$@
endef

$(foreach P, $(main), $(foreach O, $(os), $(eval $$(call build_template, $O, $P))) )
Run Code Online (Sandbox Code Playgroud)

我尝试过至少有十几种变体。我认为我的主要问题是如何t在模板中声明。我尝试了很多关于 make 的“concat”方法。也:==为 t。我认为:=是正确的。但我不再确定任何事情;)

明确地说,我想“生成”如下所示的目标:

mailworker_linux:
    GO111MODULE=on GOOS=linux GOARCH=amd64 $(GO) build mailworker

mailworker_darwin:
    GO111MODULE=on GOOS=darwin GOARCH=amd64 $(GO) build mailworker
Run Code Online (Sandbox Code Playgroud)

这是这样做的好方法吗?如果是这样,我的误解在哪里。

非常感谢

Mad*_*ist 6

你在这里有一些问题。首先,您的调用call是不正确的:您正在转义它,这意味着它在被赋予 eval 之前不会被扩展;这是不正确的,它必须首先扩展。你要:

..., $(eval $(call build_template,$P,$O))..
Run Code Online (Sandbox Code Playgroud)

$之前只有一个call

其次,您定义的与 eval/call 对一起使用的变量的规则是,您希望 eval 看到的该变量内的每个宏扩展都必须进行转义。在您的情况下,您确实将$@as转义了,$$@这很好,但是您需要转义的另一件事是使用 of $(t),因为在eval设置它之前不会设置该变量。所以你需要像这样写你的变量:

define build_template =
t := $(addprefix $(1)_,$(2))
$$(info $$(t))
$$(t):
        @echo $(1) $(2) $$@
endef
Run Code Online (Sandbox Code Playgroud)

(我在_您的缺失中添加了addprefix)。无论你使用=还是:=这里,都没有关系;它们的工作方式相同,因为您总是在立即扩展上下文中使用此变量。

顺便说一句,似乎每个人都直接运行 eval 和 call,它们非常强大,但也很难使用和理解。使用更直接的 make 构造的替代方法可能是这样的:

getmain = $(word 1,$(subst _, ,$@))
getos = $(word 2,$(subst _, ,$@))

TARGETS := $(foreach P,$(main),$(addprefix $P_,$(os)))

all: $(TARGETS)

$(TARGETS): %:
        @echo $(getmain) $(getos) $@
Run Code Online (Sandbox Code Playgroud)