我的makefile中有一堆这样的行,但排列不同。我想使用一般规则来自动化它们,因此,如果我键入$ make foo-WHATEVER
,请知道如何从foo.c
和相关的-D标志构建它。
foo-PARAMA.o: foo.c
foo-PARAMA.o: CPPFLAGS += -DPARAMA
foo-PARAMA-PARAMB.o: foo.c
foo-PARAMA-PARAMB.o: CPPFLAGS += -DPARAMA -DPARAMB
foo-PARAMA-PARAMB-PARAMC.o: foo.c
foo-PARAMA-PARAMB-PARAMC.o: CPPFLAGS += -DPARAMA -DPARAMB -DPARAMC
嗯,您可以尝试这样的事情:
foo-%.o : foo.c
$(CC) $(CPPFLAGS) $(addprefix -D,$(subst -, ,$*)) $(CFLAGS) -o $@ -c $<
但是我怀疑您真的要对[任何源文件]都执行此操作,而不仅仅是foo.c
。这要困难得多,因为您不能在单个目标或先决条件中拥有多个模式。
为此,您必须预先知道源文件列表并使用eval
:
SRCS = foo.c bar.c baz.c biz.c
define make-pattern
$1-%.o : $1.c
$$(CC) $$(CPPFLAGS) $$(addprefix -D,$$(subst -, ,$$*)) $$(CFLAGS) -o $$@ -c $$<
endif
$(foreach S,$(SRCS),$(eval $(call make-pattern,$S)))
似乎您想在make
中进行配置管理。问题在于make
本身并没有真正配备这种功能。我的猜测是,在其发明之日,平台的极端多样性是无法预见的,而这一平台每天将运行某种unixoid构建系统,因此,主要用例是轻松定义具有相当小的偏差的同质构建。现在,它的2019年和make
仍然存在,并且据信用户群比以往任何时候都要大。具有不需要其他任何工具的优点的一种可能的补救方法是使用gmtt,它是GNUmake库,正是用于此配置目的。下面我画出一个假设的配置场景:
include gmtt/gmtt.mk
PLATFORM := $(shell uname)
# table of platforms with 2 columns. Don't forget that the leading element of every table must be an integer denoting the number of columns!
define AVAILABLE-PLATFORMS :=
2
CYGWIN?NT-4.? toolX
CYGWIN?NT-10.? toolY
Linux* toolZ
FreeBSD toolXYZ
endef
define ADDITIONAL-FLAGS :=
2
toolX -Dfoo
toolY -Dbar
toolZ -Dbaz
toolXYZ -Dfoo
toolXYZ -Dbar
toolXYZ -Dbaz
endef
# select column 2 from the table line(s) which glob-match the current platform:
USED-TOOL := $(call select,2,$(AVAILABLE-PLATFORMS),$$(call glob-match,$(PLATFORM),$$1))
# now select the right flags for the tool
CFLAGS_OPT := $(call select,2,$(ADDITIONAL-FLAGS),$$(call str-eq,$(USED-TOOL),$$1))
$(info $(USED-TOOL) Options: $(CFLAGS_OPT))
诚然,这是Greenspun's tenth rule上的一个引理,但是其他选项(用少量外部工具组成配置信息)也没有那么吸引人。