迭代Makefile中的列表?

Dyl*_*lan 11 linux makefile

我发现我正在编写很多可以使用n -tuple列表清理的Makefile .但是我找不到任何方法(干净利落地)做到这一点.到目前为止,我只能使用$(shell ...)tr,sed或其他非Makefile标准.

例如,我想这样做:

XYZs = \
    dog.c  pull_tail bark  \
    duck.c chase     quack \
    cow.c  tip       moo

all:
    @- $(foreach X Y Z,$(XYZs), \
        $(CC) $X -o bully/$Y ; \
        ln bully/$Y sounds/$Z ; \
    )
Run Code Online (Sandbox Code Playgroud)

有没有一种好方法可以在Makefile中迭代n -tuple列表?谢谢!

小智 12

Makefile本质上是声明性的,所以我认为make本身并不能提供你想要的东西.但是,您似乎想要将某些字符串值与特定目标关联起来,因此GNU make 的Target特定变量值功能可能会很有用.这是手册的摘录:

目标特定变量还有一个特殊功能:当您定义特定于目标的变量时,该变量值对该目标的所有依赖项也有效(除非这些依赖项使用它们自己的特定于目标的变量值覆盖它).所以,例如,这样的声明:

prog : CFLAGS = -g

prog : prog.o foo.o bar.o

将设置CFLAGS-g在命令脚本prog,但它也将设置CFLAGS,以-g在创建prog.o,foo.o的,而文件bar.o的命令脚本,并建立它们的依赖任何命令脚本.

如果您还没有阅读过,那么GNU make手册非常好.

编辑:在评论中执行您的要求:

dog: ANIMAL=dog.c BULLY=pull_tail SOUND=bark
Run Code Online (Sandbox Code Playgroud)

使用:

dog: ANIMAL=dog.c 
dog: BULLY=pull_tail 
dog: SOUND=bark
Run Code Online (Sandbox Code Playgroud)

  • 问题不在于make是声明性的,而是它不为这种经常需要的模式提供声明性语法! (2认同)

Pet*_*ete 9

我会在foreach上查看GNU Make手册.这里有一些随机剪辑,我在一个不同的项目中使用过...这个例子不完整,但也许会给你一些想法?如果我有更多时间,我可能会在以后清理它...

REMAKE_PROGS:= dog duck cow

XYZs = \
    dog.c  pull_tail bark  \
    duck.c chase     quack \
    cow.c  tip       moo

$(foreach src, $(XYZs), $(eval $MAKE $(src))

$(REMAKE_PROGS):
        @echo "\n# === $@ linking\n"
        $(call compile,$@,$(OBJS_$@),$(CXX),$(MPICXX),$(LDFLAGS) $(LIBS) $(SYSLIBS) $(OTHER_LIB) $(EXTRA_LD_FLAGS))
        @echo "\n# --- $@ compiled\n"

define compile
  @mkdir -p $(dir $(1))
  $(if ${ANNOUNCE},@echo "\n# +++ ${MAKECMDGOALS} compiling\n" $(eval ANNOUNCE=))
  $(call compiler,$(1),NOMPI,$(3),$(4))
  $(eval MY_FLAGS=$(FLAGS_$(1)) $(5))
  $(if $(filter %xlf %xlf90,$(COMPILER_$(1))),$(eval MY_FLAGS:=$(MY_FLAGS:-D%=-WF,-D%)))
  $(strip $(COMPILER_$(1)) $(2) $(MY_FLAGS) -o $(1) )
endef
Run Code Online (Sandbox Code Playgroud)


Dyl*_*lan 7

感谢您的提示 - 经过一些黑客攻击后,我认为这更像是我所希望的:

XYZs = \
    dog.c:pull_tail:bark  \
    duck.c:chase:quack \
    cow.c:tip:moo

all:
    @- $(foreach XYZ,$(XYZs), \
        $(eval X = $(word 1,$(subst :, ,$(XYZ)))) \
        $(eval Y = $(word 2,$(subst :, ,$(XYZ)))) \
        $(eval Z = $(word 3,$(subst :, ,$(XYZ)))) \
        \
        $(CC) $X -o bully/$Y ; \
        ln bully/$Y sounds/$Z ; \
    )
Run Code Online (Sandbox Code Playgroud)

谁能做得更好?