所以我在这里得到了一个make文件,我的项目目前有一个master.c和slave.c,它们都有主要功能。因此我只想将slave.c 文件从构建过程中过滤掉。所以我在定义源文件时使用了过滤器。但是当运行 make 时,项目不断出现“main 的多个定义”错误。当过滤器应该隐藏slave.c 文件时为什么会出现这种情况?
########################################################################
####################### Makefile Template ##############################
########################################################################
#Compiler settings - Can be customized.
CC = gcc
CXXFLAGS = -std=c11 -Wall
LDFLAGS =
# Makefile settings - Can be customized.
APPNAME = master
SUBAPPNAME = slave
EXT = .c
SRCDIR = .
OBJDIR = .
############## Do not change anything from here downwards! #############
SRC := $(filter-out slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
OBJ := $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP := $(OBJ:$(OBJDIR)/%.o=%.d)
#UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)
########################################################################
####################### Targets beginning here #########################
########################################################################
all: $(APPNAME)
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
# Creates the dependecy rules
%.d: $(SRCDIR)/%$(EXT)
@$(CPP) $(CFLAGS) $< -MM -MT $(@:%.d=$(OBJDIR)/%.o) >$@
# Includes all .h files
-include $(DEP)
# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $@ -c $<
################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
$(RM) $(DELOBJ) $(DEP) $(APPNAME)
# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
$(RM) $(DEP)
# Clean only all files with the extension .o
.PHONY: cleanobj
cleanobj:
$(RM) $(DELOBJ)
# Cleans both files with .d and .o extensions
.PHONY: cleanod
cleanod:
$(RM) $(DELOBJ) $(DEP)
来电
SRC := $(filter-out slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
是只是一个字符串操作,也就是说,
make
不知道底层文件树,并尝试从列表slave.c
中抛出字符串yoursrcdir/slave.c yoursrcdir/master.c
,这显然失败了。尽管您一开始可能不同意,但这是一件好事,因为文件树上的过滤器操作的语义绝不是通用的或易于记录或传输。因此,make
只查看所呈现的字符串,并决定逐个字符地比较哪些内容以及哪些内容要删除。
也就是说,重写为
SRC := $(filter-out $(SRCDIR)/slave.c, $(wildcard $(SRCDIR)/*$(EXT)))
将在你的情况下解决问题。 为了获得更广泛的功能,请查找两个函数
abspath
和 realpath
以获取规范格式的文件名,这会阻止 filter
等人。由于操作系统命名法的差异而被绊倒。