Makefile 定义与多个管道函数等效的自定义gmake函数

Makefile 定义与多个管道函数等效的自定义gmake函数,makefile,gnu-make,Makefile,Gnu Make,我正在尝试定义一个函数,该函数将与$(patsubst%,$(OBJDIR)/%.o,$(basename$(ARG1)))的工作相关。 有点像 define getobj $(1): $(patsubst %,$(OBJDIR)/%.o,$(basename $(1))) endef 我试图改善的环境是: OBJDIR = objects TESTHNF_CPPS = testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryL

我正在尝试定义一个函数,该函数将与
$(patsubst%,$(OBJDIR)/%.o,$(basename$(ARG1)))的工作相关。

有点像

define getobj
    $(1): $(patsubst %,$(OBJDIR)/%.o,$(basename $(1)))
endef
我试图改善的环境是:

OBJDIR = objects
TESTHNF_CPPS = testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS = mt19937int.c lip.c
TESTHNF_OBJS = $(patsubst %,$(OBJDIR)/%.o,$(basename $(TESTHNF_CPPS) $(TESTHNF_CS)))
TESTHNF_OBJS2 = $(getobj $(TESTHNF_CPPS) $(TESTHNF_CS))

这里,
$(TESTHNF_OBJS2)
保持为空。如何编写函数?

您的
getobj
宏看起来像是要声明规则(
目标:先决条件
)。但是,您试图使用它看起来就像您试图将其展开的结果分配给一个变量,这实际上没有意义

因此,让我们忽略规则外观,专注于您的目标(据我所知):定义一个宏,该宏获取传递的每个单词的
basename
,并将其替换为
$(OBJDIR)/.o
。你就快到了:

getobj = $(patsubst %,$(OBJDIR)/%.o,$(basename $(1)))
应该是这样的,其中
$(1)
是宏的参数,是一个空格分隔的单词列表。你把它叫做:

调用
make函数将
$(1)
替换
$(TESTHNF\u CPPS)$(TESTHNF\u CS)
参数,该参数位于
getobj
的定义中,并返回结果。在您的情况下,它相当于:

TESTHNF_OBJS2 = $(patsubst %,$(OBJDIR)/%.o,$(basename $(TESTHNF_CPPS) $(TESTHNF_CS)))
TESTHNF_OBJS2
展开时,结果将为:

objects/testhnf.o objects/timings.o ... objects/lip.o
回到规则上来看看。如果您想要的是实例化生成规则:

<basename>: $(OBJDIR)/<basename>.o
由于所有这些都相当复杂,而且好处也很低,因此最好坚持使用更简单、更易于理解和维护的构造:

OBJDIR       := objects
TESTHNF_CPPS := testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS   := mt19937int.c lip.c
BASENAMES    := $(basename $(TESTHNF_CPPS) $(TESTHNF_CS))
TESTHNF_OBJS := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(BASENAMES)))

$(BASENAMES): %: $(OBJDIR)/%.o

clean:
    rm -f $(TESTHNF_OBJS)

除了Renaud一如既往的优秀答案外,这条规则是一个。

对于构建配置,您可能需要查看GNUmake函数集合。
OBJDIR = objects
TESTHNF_CPPS = testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS = mt19937int.c lip.c
TESTHNF_OBJS :=

# $(1): basename of one source file
define getobj
    $(1): $(OBJDIR)/$(1).o

    TESTHNF_OBJS += $(OBJDIR)/$(1).o
endef
$(foreach b,$(basename $(TESTHNF_CPPS) $(TESTHNF_CS)),$(eval $(call $(b))))

clean:
    rm -f $(TESTHNF_OBJS)
OBJDIR       := objects
TESTHNF_CPPS := testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS   := mt19937int.c lip.c
BASENAMES    := $(basename $(TESTHNF_CPPS) $(TESTHNF_CS))
TESTHNF_OBJS := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(BASENAMES)))

$(BASENAMES): %: $(OBJDIR)/%.o

clean:
    rm -f $(TESTHNF_OBJS)