c++ Makefile在使用`touch`命令后自动修改规则,非常奇怪的情况,有人知道吗?

pgpifvop  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(168)

我正在学习C++。我写了下面的Makefile来编译我的程序:

  1. NAME = test
  2. CC = c++
  3. CFLAGS = -Wall -Wextra -Werror -std=c++98
  4. SRCS = test.cpp
  5. OBJS = ${SRCS:.cpp=.o}
  6. all: ${NAME}
  7. %.o: ${SRCS}
  8. ${CC} ${CFLAGS} -c $< -o $@
  9. ${NAME}: ${OBJS}
  10. ${CC} ${CFLAGS} ${OBJS} -o ${NAME}
  11. clean:
  12. rm ${OBJS}
  13. fclean: clean
  14. rm ${NAME}
  15. re: fclean
  16. all
  17. .PHONY: all clean fclean re .c.o

Makefile工作正常,直到我使用touch test.cpp命令来查看它是否按预期重新链接。
然后我的Makefile首先重新编译test.cpp,然后它尝试链接Makefile.o并输出一个文件Makefile
下面是我终端上的输出显示:

  1. c++ -Wall -Wextra -Werror -std=c++98 -c test.cpp -o Makefile.o
  2. c++ Makefile.o -o Makefile
  3. rm Makefile.o
  4. Makefile:1: warning: NUL character seen; rest of line ignored
  5. Makefile:1: *** missing separator. Stop.

最重要的是,我的整个Makefile被随机字符串和字符(不是真的随机,但我不知道它们来自哪里,还有一大堆NUL字符)替换,下面是它的屏幕截图:

我在WSL2,Windows 11,Ubuntu 20.04下代码,在VSCode.
我真的很感激一些想法,谢谢!
我通过删除%.o规则解决了这个问题,所以我只是用${CC} ${CFALGS} ${SRCS} -o ${NAME}编译。
但我还是想知道为什么编译到对象文件首先会引起这个问题

juzqafwq

juzqafwq1#

您猜对了问题出在%.o规则中。你看:

  1. SRCS = test.cpp
  2. ...
  3. %.o: ${SRCS}
  4. ${CC} ${CFLAGS} -c $< -o $@

该模式规则告诉Make构建 any 对象文件的方法是编译test.cpp。Make总是检查makefile是否可以重新构建,可以肯定的是,可以通过编译test.cpp并链接结果对象文件来重新构建。所以你最终得到了一个makefile,它不是makefile,它实际上是一个可执行的二进制文件,应该被命名为test(这是一个不好的名字,但这是另一个故事)。
解决办法很简单:

  1. %.o: %.cpp
  2. ${CC} ${CFLAGS} -c $< -o $@

相关问题