gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 02:55:36 25 4
gpt4 key购买 nike

我花了一天的大部分时间试图弄清楚这一点。我想使用 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

现在我想添加 GOOS=$(os)到构建命令/为每个主要的 X 操作系统组合生成一个目标。我的测试/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))) )

我尝试过至少有十几种变体。我想我的主要问题是如何申报 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

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

非常感谢

最佳答案

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

..., $(eval $(call build_template,$P,$O))..

(只有一个 $ 之前 call

其次,您定义的与 eval/call 对一起使用的变量的规则是,您希望 eval 看到的该变量内的每个宏扩展都必须进行转义。在您的情况下,您确实逃脱了 $@$$@这很好,但你需要逃避的另一件事是使用 $(t) ,因为该变量直到 eval 才被设置设置它。所以你需要像这样写你的变量:
define build_template =
t := $(addprefix $(1)_,$(2))
$$(info $$(t))
$$(t):
@echo $(1) $(2) $$@
endef

(我将缺失的 _ 添加到您的 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) $@

关于Makefile 将目标作为两个列表的叉积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53225617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com