摘要:
我在同一个父文件夹中有一个.c文件和一个同名的.cpp文件。我不再希望编译.c文件,但也不想将其从文件夹中删除。
即使我明确指定编译.cpp文件,makefile也在使用.c文件。我该如何解决这个问题?
在将 file3.c 重命名为其他名称时, file3.cpp 将被编译。
详细信息:
' src '中存在的文件文件夹是:
file1.c
file2.c
file3.c
file3.cpp
file4.cpp
makefile的重要摘录:
SOURCE_FILES := ./src/file1.c \
./src/file2.c \
./src/file3.cpp \
./src/file4.cpp
OBJS = $(patsubst %.cpp,%.o,$(filter %.cpp, $(SOURCE_FILES))) \
$(patsubst %.c,%.o,$(filter %.c, $(SOURCE_FILES)))
all : $(OBJS)
$(CXX) $(CFLAGS) $(INCLUDES) -o $(PROJECT).bin $(OBJS) $(LDFLAGS) $(LIBRARIES)
.cpp.o:
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@
@echo 'CPP FILE : ' $<
.c.o:
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@
@echo 'C FILE : ' $<
在做&#39; make&#39;时,echo命令的日志给出:
C FILE : ./src/file1.c
C FILE : ./src/file2.c
C FILE : ./src/file3.c
CPP FILE : ./src/file4.cpp
问题:
答案 0 :(得分:3)
方法make
用于选择使用两种可能的匹配规则中的哪一种取决于您使用的make
版本。 (它在3.81和3.82之间变化,我认为稍微调整了4.0+,但我不确定。)
我认为make 3.81使用了最后一个匹配规则,并使3.82+使用匹配规则和最短的词干(匹配%
的位),然后使用具有相似词干长度的规则之间的第一个匹配规则。
所以看起来你现在正在使用make 3.81。
在这种情况下,应该可以简单地交换两个规则的顺序来获得你想要的行为(假设你总是想要.cpp
个文件来赢得&#34;)。
或者,您可以尝试为file3.o
目标提供显式先决条件,而不是让它猜测。 (即file3.o: file3.cpp
)
这表示您的显式后缀规则都不是必需的,因为make已包含从.o
和.c
文件构建.cpp
文件的默认规则。 (我不知道它们之间的相对顺序,因此您可能需要明确的先决条件,假设有效,内置规则才能正常工作。)
此外,您可能希望使用Pattern Rules代替Old-Fashioned Suffix Rules作为当前实践的一点。
填充我可以看到的OBJS
变量的唯一改进就是过滤结果,因此只需过滤一次。
OBJS = $(filter %.o,$(patsubst %.cpp,%.o,$(SOURCE_FILES)) \
$(patsubst %.c,%.o,$(SOURCE_FILES)))
也就是说你也可以使用Substitution References而不是显式调用$(patsubst)
来缩短这一点。
OBJS = $(filter %.o,$(SOURCE_FILES:.cpp=.o) $(SOURCE_FILES:.c=.o))
答案 1 :(得分:0)
您有.c ==&gt;的规则。 .o和.cpp ==&gt;的.o。 在您的情况下,首先运行file3.c的规则,因为新创建的file3.o文件现在存在。由于目标file3.o文件存在,因此没有理由编译file3.cpp。
查看at the make manual,如果同一目标有2条规则,则使用最后一条规则。