替代问题

时间:2013-10-31 13:10:20

标签: makefile gnu-make

我无法正确使用路径替换。我在SOURCES中有一堆源文件:

@echo $(SOURCES)
foo.c bar.cpp bah.cxx

我想要一个目标文件列表:

# Imaginary only because nothing works
@echo $(OBJECTS)
foo.o bar.o bah.o

我正在尝试使用OBJECTS构建patsubst列表。首先,这会生成源文件和目标文件的列表。除了错误之外,它会导致_main的副本无法链接。

OBJECTS = $(patsubst %.c, %.o, ${SOURCES}) $(patsubst %.cc, %.o, ${SOURCES}) \
          $(patsubst %.cpp, %.o, ${SOURCES}) $(patsubst %.cxx, %.o, ${SOURCES}) 

其次,这不会进行替换。不仅错了,我还回到SOURCES中的原始列表。

OBJECTS = $(patsubst %.c %.cc %.cpp %.cxx, %.o, ${SOURCES})

第三,这会产生原始的源文件列表:

OBJECTS = $(patsubst %.*, %.o, ${SOURCES})

我也试过使用以下内容,这似乎会增加像兔子这样的文件:

OBJECTS = $(SOURCES:.c=.o) $(SOURCES:.cc=.o) \
          $(SOURCES:.cpp=.o) $(SOURCES:.cxx=.o)

在使用便携式make时如何执行简单的扩展替换?

3 个答案:

答案 0 :(得分:3)

汤姆的回答是正确的。 Etan也会奏效。一个较短的解决方案是:

$(addsuffix .o,$(basename $(SOURCES))

答案 1 :(得分:1)

如果你有类似过滤器的功能,你可以使用它。否则你可以分阶段完成:

SOURCES := foo.c bar.cpp bah.cxx

O := $(SOURCES)
$(info $(O))
O := $(patsubst %.c,%.o,$(O))
$(info $(O))
O := $(patsubst %.cpp,%.o,$(O))
$(info $(O))
O := $(patsubst %.cxx,%.o,$(O))
$(info $(O))

你的第一个(以及第三个,因为它实际上是相同的)尝试的问题是,patsubst不会触及输入中与模式不匹配的任何单词。因此,当您从多次调用patsubst构建OBJECTS时,您正在复制(在每个部分中)与该模式不匹配的所有SOURCSE条目。

第二个问题是patsubst不采用多种模式,因此没有任何东西与错误的模式相匹配,因此您可以完全不修改SOURCES。

答案 2 :(得分:1)

首先,我认为patsubst不是便携式的。这是一个GNU make功能。

我认为你的问题的一个答案是嵌套的替换,例如:

$(patsubst %c,%.o,$(patsubst %.cc,%.o,$(patsubst .....)))