Makefile 在patsubst中使用%2次

Makefile 在patsubst中使用%2次,makefile,gnu-make,Makefile,Gnu Make,我想为每个输入字生成两个连续的输出字,并对它们应用patsubst 我想要的非工作原型: $(patsubst %.o,%.a.o %.so.o,$(OBJ)) 未替换%的第二个值,而是出现一个普通的% 未给出所需顺序的工作版本: $(patsubst %.o,%.a.o,$(OBJ)) $(patsubst %.o,%.so.o,$(OBJ)) 例如: 输入: foo.o bar.o 期望输出: foo.a.o foo.so.o bar.a.o bar.so.o 如何获得所需的输出?两

我想为每个输入字生成两个连续的输出字,并对它们应用
patsubst

我想要的非工作原型:

$(patsubst %.o,%.a.o %.so.o,$(OBJ))
未替换%的第二个值,而是出现一个普通的
%

未给出所需顺序的工作版本:

$(patsubst %.o,%.a.o,$(OBJ)) $(patsubst %.o,%.so.o,$(OBJ))
例如:

输入:

foo.o bar.o
期望输出:

foo.a.o foo.so.o bar.a.o bar.so.o

如何获得所需的输出?

两个嵌套的foreach循环可以解决您的问题。一个用于文件,另一个用于扩展名。下面的代码应该可以解决您的问题

OBJS = foo.o bar.o
EXTS = a.o so.o

OUT  = $(foreach file, ${OBJS}, \
         $(foreach ext, ${EXTS}, \
           $(patsubst %.o, %.${ext}, ${file})))

join
make函数获取两个单词列表并逐字连接它们。这不完全是您想要的,因为
foo.a.o
foo.so.o
之间没有空格,但离它不远

假设您确信某些字符串永远不会成为文件名的一部分(例如,
!!!
),您可以组合替换引用(或等效的
patsubst
)、
join
subst

$(subst !!!, ,$(join $(OBJ:o=a.o!!!),$(OBJ:o=so.o)))
或者,更简单的是,如果您确信
.a.o
不能成为文件的基本名称的一部分:

$(subst .a.o,.a.o ,$(join $(OBJ:o=a.o),$(OBJ:o=so.o)))

谢谢如果是
$(OBJ:.o=.a.o)
,不是更安全吗?如果没有,它可以替换出现在基名称中的任何
o
,不是吗?@cacahuetebrito无风险,替换引用在单词末尾没有
%
通配符替换。