C++ 生成文件问题

A C++ makefile issue

提问人:Vinod 提问时间:7/25/2019 更新时间:7/25/2019 访问量:43

问:

我最近开始使用这个makefile(改编自网络)来构建我的C++代码:

a.exe:  main.o
    g++ $(CFLAGS) -o $@ $^
main.o: main.cpp code.hpp
CFLAGS=-ggdb -std=c++17 -Wall -Werror=pedantic -Wextra 

#-------------------------------------------------------------

run:    a.exe
    ./a.exe

clean:
    rm -f *.o
    rm -f *.exe
    rm -f *.gch
    rm -f *.log

build:  clean   a.exe

%.o:    %.cpp
    g++ $(CFLAGS) -c $<

#====================================================

在我的文件中,我使用以下别名:.bashrc

alias mkbld='make build >& build.log'

当我在命令行上执行上述别名时,我看到 makefile 中指定的 clean before build 首先删除当前工作目录中的所有相关文件,然后文件作为构建的一部分重新生成。但是,不会重新生成该文件。我认为构建前的清理逻辑也应该以相同的方式应用于此文件(尽管此文件本身不是构建的),因为每次构建日志都会写入此文件,并且每次都应重新创建。build.log

知道为什么这没有发生吗?

C++ 生成文件

评论


答:

2赞 Sam Varshavchik 7/25/2019 #1

什么时候

make build >& build.log

通过您的 shell 别名执行;但 shell 首先创建文件,然后执行,其标准输出/错误重定向到该文件。它是创建文件并设置重定向的 shell。build.logmake

所以,这显然是发生的第一件事。然后,您的 Makefile 会在某个时间点执行:

rm -f *.log

当然,这会愉快地删除刚刚创建的文件。记住计算机编程的黄金法则:计算机总是会完全按照你的要求去做,而不是你想让它做什么。你告诉计算机:首先,创建一个名为 的文件,然后:其次,删除所有名为 ;您的计算机勤奋地按照您的指示进行操作。build.logbuild.log*.log

P.S. 此时,标准输出和错误仍重定向到这个现已删除的文件;所以,基本上,一切都消失在虚空中(请原谅C++双关语),再也看不到了。

有几种可能的解决方法,最好的解决方法取决于您以这种方式做事的最初目的是什么。一些选项包括:

1) 使用一些其他扩展名,例如 ,用于捕获的标准输出或错误。build.out

2)使命令更智能,并排除此特定文件,但删除所有其他文件。rm*.log

3)使命令更加智能,并让它只删除早于某个预定时间间隔的文件。使用这种方法,当前时间戳将防止它被删除。rm*.logbuild.log

取决于你想做什么,但这是对你所看到的行为的解释。

评论

0赞 David Schwartz 7/25/2019
中的命令真的不是一个好主意。如您所见,他们删除您不想删除的文件太容易了。rmclean