Gnu Make:切片变量(保留除最后一个元素以外的所有元素)

Gnu Make : Slice variable (keep all but last element)

我正在尝试对我的 makefile 中的变量执行切片。 我用这个:

C_SOURCES := $(foreach dir, $(C_SOURCEDIRS), $(wildcard $(dir)/*.cpp))

要生成所有代码源文件的列表,然后使用这个:

C_OBJS := $(subst $(C_SOURCEDIR), $(CLIENT_BUILD_DIR), $(C_SOURCES:.cpp=.o))

生成所有关联目标文件的所有名称。但是,构建目录本身 (CLIENT_BUILD_DIR) 一直作为 C_OBJS 的最后一个元素出现。 (我也不完全确定为什么会这样...)

作为一种 hack,我决定删除 C_OBJS 的最后一个元素(将其切掉,保留所有 n - 1 个第一个元素),并尝试这样做:

C_OBJS := $(wordlist, 1, $(words $(C_OBJS)) - 1, $(C_OBJS))

然而这导致 C_OBJS 为空! 我已阅读 documentation for text functions,但除非我没有正确理解某些内容,否则它应该按预期工作:使 C_OBJS = C_OBJS 中的所有元素,最后一个元素除外。

感谢任何帮助! (对于任何可以解释 为什么 CLIENT_BUILD_DIR 首先出现在 C_OBJS 中的人的奖励 cookie;以及可能如何避免它)[编辑:查看答案对于那部分]

如果需要,这是有问题的 makefile 的完整片段:

CLIENT_SRC_DIR   := $(SOURCEDIR)/Client
CLIENT_BUILD_DIR := $(BUILDDIR)/Client
C_DIRS           := $(notdir $(shell find $(CLIENT_SRC_DIR) -type d -print | tail -n +2))
C_SOURCEDIRS     := $(foreach dir, $(C_DIRS), $(addprefix $(CLIENT_SRC_DIR)/, $(dir)))
C_TARGETDIRS     := $(foreach dir, $(C_DIRS), $(addprefix $(CLIENT_BUILD_DIR)/, $(dir)))
C_SOURCES        := $(foreach dir, $(C_SOURCEDIRS), $(wildcard $(dir)/*.cpp))
C_OBJS           := $(subst $(C_SOURCEDIR), $(CLIENT_BUILD_DIR), $(C_SOURCES:.cpp=.o))
C_OBJS           := $(wordlist, 1, $(words $(C_OBJS)) - 1, $(C_OBJS))
C_DEPS           := $(C_OBJS:.o=.d)

谢谢!

感谢 Vroomfondel 的评论,我意识到 'slice' 无法正常工作只是因为 make 正在处理字符串,因此不知道 -1 是什么意思。

另一个注意事项:C_OBJS 行中有一个拼写错误(不知何故总是这些类型的错误需要最长的修复时间); C_SOURCEDIR 不是一个存在的变量!因此 make 将其视为空字符串,这反过来又使 subst 命令无法按预期工作...

教训:注意 忍者拼写错误

这将评估除 $(VAR) 的最后一个词之外的所有词:

VAR2 := $(wordlist 2,$(words $(VAR)),x $(VAR))

你也可以把它做成一个函数:

define firstwords
$(wordlist 2,$(words $(1)),x $(1))
endef

VAR2 := $(call firstwords,$(VAR))