Makefile和计算变量名

Makefile和计算变量名,makefile,cross-compiling,gnu-make,Makefile,Cross Compiling,Gnu Make,我用几个编译器获得了以下Makefile,我想通过变量cc在循环中调用它们: cc_x64=x86_64-linux-gnu-gcc cc_mips=mips-linux-gnu-gcc all: for arch in "x64" "mips" ; do\ cc="cc_$$arch";\ $($(cc)) some_file -o some_bin 通过$($(cc)),我试图用cc_xxx替换$(cc),然后用我试图执行的实际命令替换它。这在GNU Make的文

我用几个编译器获得了以下Makefile,我想通过变量cc在循环中调用它们:

cc_x64=x86_64-linux-gnu-gcc
cc_mips=mips-linux-gnu-gcc

all:
    for arch in "x64" "mips" ; do\
    cc="cc_$$arch";\
    $($(cc)) some_file -o some_bin
通过$($(cc)),我试图用cc_xxx替换$(cc),然后用我试图执行的实际命令替换它。这在GNU Make的文档中称为计算变量名:


由于某种原因,我无法让它工作。我错过了什么?

你不能像那样跨越外壳/制造边界。您正在尝试在shell上下文中动态创建和计算make变量。那不行

您需要在make或shell中完成所有工作。将这些make变量导出到shell,然后类似的操作应该可以工作:

all:
    for arch in x64 mips; do\
     cc=cc_$$arch;\
     ${!cc} some_file -o some_bin.$$arch;\
    done
但最好是用更地道的方式来做

哪个看起来更像这样(未经测试):


如果我觉得必须使用循环,我会这样做:

COMPS = x86_64-linux-gnu-gcc mips-linux-gnu-gcc

all:
    for comp in $(COMPS); do\
  $$comp some_file -o some_bin; \
  done
您的问题是“我遗漏了什么?”答案是,您没有意识到,Makefile的工作方式与shell脚本不同。您正在尝试将shell脚本放在生成文件上。这就像你试图给牛套上马鞍。你和母牛都会对结果不满意

你尝试这样做的方式,你不需要做。只需使用“all:”下的shell脚本,忘记Make。为什么要给牛套上马鞍

如果您确实想学习如何使用Make,请更仔细地阅读Make手册,特别是学习其中给出的示例。然后,您将了解shell脚本和makefile之间的区别,一切都将变得更加清晰

我将向您展示如何按照Makefiles设计的正确方式做您想做的事情。但请仔细阅读手册

RESULTS := $(addprefix some_bin., x86_64 mips)

.PHONY: all
all: $(RESULTS)
$(RESULTS): some_file Makefile
    $(patsubst .%,%-linux-gnu-gcc,$(suffix $@)) $< -o $@
RESULTS:=$(addprefix some_bin.,x86_64 mips)
冒牌货:全部
全部:$(结果)
$(结果):一些_文件Makefile
$(patsubst.%,%-linux-gnu-gcc,$(后缀$@))$<-o$@

这里也有同样的问题:
$(cc_$(*))
被替换为空字符串,尽管
cc_$(*)
实际计算结果为,例如,cc_x86。make的哪个版本?在快速测试中,
$(cc_$(*))
在这里用于模式规则。另外,
x86
不在您的示例体系结构列表中,因此如果没有
cc_x86
make变量显然无法正常工作(或者更准确地说,它将正常工作,并为您提供一个空字符串)。(x86只是一个示例)。你是对的,在反复检查模式规则后,我在上一次测试中搞砸了,我的坏。非常感谢。好的,这是另一种方法,但在这里我有兴趣理解为什么计算变量名在这种特定情况下不起作用,我不寻求替代解决方案。谢谢你的建议。
RESULTS := $(addprefix some_bin., x86_64 mips)

.PHONY: all
all: $(RESULTS)
$(RESULTS): some_file Makefile
    $(patsubst .%,%-linux-gnu-gcc,$(suffix $@)) $< -o $@