gmake: 将变量中的所有 %.c 和 %.cxx 转为 lib%.a lib%.so

gmake: turn all %.c and %.cxx in variable to lib%.a lib%.so

我的 makefile 从单个 .c.cxx 文件中以 .a.so 的形式创建了许多小型库。例如,如果 SmallLibSrc 包含 foo.c,我希望 SmallLibs 包含 libfoo.a libfoo.so。同样,如果 SmallLibSrc 包含 bar.cxx 我希望 SmallLibs 包含 libbar.a libbar.so.

我可以通过使用一个虚拟变量分两步让它工作,例如:

SmallLibsDummyA  = $(SmallLibSrc:%.c=lib%.a)
SmallLibsDummySO = $(SmallLibSrc:%.c=lib%.so)
SmallLibs        = $(SmallLibsDummyA:%.cxx=lib%.a) $(SmallLibsDummySO:%.cxx=lib%.so)

但出于某种原因,在一个变量中执行此操作失败了。我想我不了解这些替换的语法。还有另一种有效的单线方法吗?请注意,部分原因是我要求更简洁的解决方案,但主要是为了了解更多有关 $().

的信息
SmallLibs = $($(SmallLibSrc:%.cxx=lib%.a):%.c=lib%.a) $($(SmallLibSrc:%.cxx=lib%.so):%.c=lib%.so)

这行不通:

SmallLibSrc = foo.cxx bar.c

$($(SmallLibSrc:%.cxx=lib%.a):%.c=lib%.a)

因为替换变量的格式是 $(NAME:...) 其中 NAME 是变量 name。在您的示例中,首先扩展了内部变量,您得到:

SmallLibSrc = foo.cxx bar.c

$(libfoo.a bar.c:%.c=lib%.a)

它将尝试扩展名为 libfoo.a bar.c 的 make 变量,这显然不存在。

您不能使用此表格;你必须使用更通用的函数,像这样:

$(foreach base,$(basename $(SmallLibSrc)),lib$(base).a lib$(base).so)