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

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

我正在学习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}编译。
但我还是想知道为什么编译到对象文件首先会引起这个问题

juzqafwq

juzqafwq1#

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

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

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

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

相关问题