0

我无法让路径替换正常工作。我有一堆源文件SOURCES

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

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

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

我正在尝试构建OBJECTSwith的列表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 时如何执行简单的扩展替换?

4

3 回答 3

3

汤姆的回答是正确的。Etan 的也可以。一个更短的解决方案是:

$(addsuffix .o,$(basename $(SOURCES))
于 2013-10-31T14:31:51.970 回答
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 完全没有修改。

于 2013-10-31T13:25:14.960 回答
1

首先,我不认为 patsubst 是可移植的。这是一个 GNU make 特性。

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

$(patsubst %c,%.o,$(patsubst %.cc,%.o,$(patsubst .....)))
于 2013-10-31T13:26:59.580 回答