我正在学习C++。我写了下面的Makefile来编译我的程序:
NAME = test
CC = c++
CFLAGS = -Wall -Wextra -Werror -std=c++98
SRCS = test.cpp
OBJS = ${SRCS:.cpp=.o}
all: ${NAME}
%.o: ${SRCS}
${CC} ${CFLAGS} -c $< -o $@
${NAME}: ${OBJS}
${CC} ${CFLAGS} ${OBJS} -o ${NAME}
clean:
rm ${OBJS}
fclean: clean
rm ${NAME}
re: fclean
all
.PHONY: all clean fclean re .c.o
Makefile工作正常,直到我使用touch test.cpp
命令来查看它是否按预期重新链接。
然后我的Makefile首先重新编译test.cpp
,然后它尝试链接Makefile.o
并输出一个文件Makefile
。
下面是我终端上的输出显示:
c++ -Wall -Wextra -Werror -std=c++98 -c test.cpp -o Makefile.o
c++ Makefile.o -o Makefile
rm Makefile.o
Makefile:1: warning: NUL character seen; rest of line ignored
Makefile:1: *** missing separator. Stop.
最重要的是,我的整个Makefile被随机字符串和字符(不是真的随机,但我不知道它们来自哪里,还有一大堆NUL
字符)替换,下面是它的屏幕截图:
我在WSL2,Windows 11,Ubuntu 20.04下代码,在VSCode.
我真的很感激一些想法,谢谢!
我通过删除%.o
规则解决了这个问题,所以我只是用${CC} ${CFALGS} ${SRCS} -o ${NAME}
编译。
但我还是想知道为什么编译到对象文件首先会引起这个问题
1条答案
按热度按时间juzqafwq1#
您猜对了问题出在
%.o
规则中。你看:该模式规则告诉Make构建 any 对象文件的方法是编译
test.cpp
。Make总是检查makefile是否可以重新构建,可以肯定的是,可以通过编译test.cpp
并链接结果对象文件来重新构建。所以你最终得到了一个makefile,它不是makefile,它实际上是一个可执行的二进制文件,应该被命名为test
(这是一个不好的名字,但这是另一个故事)。解决办法很简单: