我尝试使用Make提供的string functions在Makefile中进行一些字符串操作。我想对我的字符串进行两次转换,我有一个列出类似于:
的源文件的变量C_SRCS += \
./src/foo.c \
./src/bar.c \
...
我想获取此字符串并将其转换为包含所有目标文件的新变量。对象将存储在不同的目录中,显而易见的是.o
扩展名而不是.c
。实际上,他们应该改变:
./src/<file>.c
到
./artifacts/src/<file>.o
我可以用两个规则来做到这一点:
OBJS1 := $(C_SRCS:%.c=%.o)
OBJS = $(subst ./,./artifacts/,$(OBJS1))
这将工作正常,但我希望结合这两个规则并删除中间变量。我试过了:
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文档,但是我找不到有关嵌套字符串函数的任何信息。是否可以在Makefile中嵌套字符串函数?如果是这样我在这里做错了什么?
答案 0 :(得分:3)
是的,你可以嵌套字符串函数。
您不能在函数的结果上使用简写: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)))
没有&#39}的简写。工作(否则$(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)
答案 1 :(得分:1)
你做错了。只是&#34;扩展宏&#34;并替换$(OBJS1)
中的$(OBJS)
:
OBJS1 := $(C_SRCS:%.c=%.o)
OBJS = $(subst ./,./artifacts/,$(OBJS1))
变为:
OBJS = $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o))