String Makefile字符串函数可以嵌套吗?

String Makefile字符串函数可以嵌套吗?,string,function,makefile,nested,String,Function,Makefile,Nested,我正在尝试使用Make提供的函数在Makefile中执行一些字符串操作。我想对我的字符串进行两次转换,我有一个变量,该变量列出的源文件类似于: C_SRCS += \ ./src/foo.c \ ./src/bar.c \ ... 我想把这个字符串转换成一个新的变量来保存所有的对象文件。这些对象将存储在不同的目录中,并且显然将有一个.o扩展名,而不是.c。实际上,它们应该从: ./src/<file>.c 这将很好,但我希望结合这两个规则并删除中间变量。我试过: OBJS = $

我正在尝试使用Make提供的函数在Makefile中执行一些字符串操作。我想对我的字符串进行两次转换,我有一个变量,该变量列出的源文件类似于:

C_SRCS += \
./src/foo.c \
./src/bar.c \
...
我想把这个字符串转换成一个新的变量来保存所有的对象文件。这些对象将存储在不同的目录中,并且显然将有一个
.o
扩展名,而不是
.c
。实际上,它们应该从:

./src/<file>.c
这将很好,但我希望结合这两个规则并删除中间变量。我试过:

OBJS = $($(subst ./,./artifacts/,$(C_SRCS)):%.c=%.o)
这使得
OBJS
为空,我想如果我使用两个完全相同的函数类型可能会更好,所以我尝试:

OBJS = $(subst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
并且只执行嵌套规则,
OBJS
被设置为
/artifacts/src/foo.c./artifacts/src/bar.c…


我开始阅读一些Make文档,但找不到任何关于嵌套字符串函数的内容。是否可以在Makefiles中嵌套字符串函数?如果是这样的话,我做错了什么?

你做错了。只需“展开宏”并在
$(OBJS)
中替换
$(OBJS1)

变成:

OBJS = $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o))

是的,您可以嵌套字符串函数

但是,不能在函数结果上使用速记法
:X=Y

因此,当您将
OBJS1:=$(C_SRCS:%.C=%.o)
OBJS=$(subst./,/artifacts/,$(OBJS1))
组合在一起时,您没有正确地(或以明显的方式)完成其他操作。您编写了
OBJS=$($(subst./,./artifacts/,$(C_SRCS)):%.C=%.o)
当明显的(正确的)嵌套是
OBJS=$(subst./,./artifacts/,$(C_SRCS:%.C=%.o))
时。(我不确定那可能是个打字错误)

:X=Y
速记是
patsubst
(一种自动的
%
前缀速记)而不是
subst
的速记,这就是为什么您的行
OBJS=$(subst%.c,%.o,$(subst./,/artifacts/,$(c_SRCS))
不起作用的原因将发生在更多的地方,而不仅仅是值的末尾)

请参阅下面的工作版本

C_SRCS += \
          ./src/foo.c \
          ./src/bar.c

pv = $(warning $1: $($1))
$(call pv,C_SRCS)

$(warning RAW: $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o)))

OBJS = $(patsubst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
$(call pv,OBJS)
OBJS1 := $(C_SRCS:%.c=%.o)
OBJS = $(subst ./,./artifacts/,$(OBJS1))
OBJS = $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o))
C_SRCS += \
          ./src/foo.c \
          ./src/bar.c

pv = $(warning $1: $($1))
$(call pv,C_SRCS)

$(warning RAW: $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o)))

OBJS = $(patsubst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
$(call pv,OBJS)