Makefile 中隐式规则中的 -c 标志错误

Posted

技术标签:

【中文标题】Makefile 中隐式规则中的 -c 标志错误【英文标题】:Error with -c flag in implicit rule in Makefile 【发布时间】:2020-06-05 18:56:50 【问题描述】:

我正在学习 makefile,我正在尝试通过使用隐式规则来减少我的 makefile。到目前为止,这就是我所拥有的:

CC = /usr/bin/g++
OBJECTS_INTERACTIVE = calcular.o calc_interactive.o
    
calc_interactive: $(OBJECTS_INTERACTIVE)
    $(CC) $(OBJECTS_INTERACTIVE) -o $@              

calcular.o: calcular.c calcular.h
    $(CC) -c calcular.c

calc_interactive.o: calcular.h calc_interactive.c
    $(CC) -c calc_interactive.c

如果我这样运行它,没有错误。但是,我想使用像 calcular.o: calcular.h 这样的隐式规则,AFAIK 在后台执行 g++ -c calcular.c但显然它在没有 -c 标志的情况下执行该命令,我认为它是关键,我没有设法让 g++ 在使用隐式规则时使用 -c 标志。这就是我想要实现的目标:

CC = /usr/bin/g++
OBJECTS_INTERACTIVE = calcular.o calc_interactive.o

calc_interactive: $(OBJECTS_INTERACTIVE)
    $(CC) $(OBJECTS_INTERACTIVE) -o $@  

calcular.o: calcular.h

calc_interactive.o: calcular.h 
    

它会产生这个错误:

jules@desktop:$ make
/usr/bin/g++ -c calc_interactive.c
/usr/bin/g++ calcular.o calc_interactive.o -o calc_interactive
g++: error: calcular.o: No such file or directory 
makefile:11: recipe for target 'calc_interactive' failed 
make: *** [calc_interactive] Error 1 

EDIT:所有文件的详细粘贴箱 https://pastebin.com/FZy5kqzj

【问题讨论】:

你为什么要在 .c 文件上运行 g++ 问题不在于“使用-c 运行”。如果这是问题所在,那么您在尝试构建 calculator.o 文件时会出错,因为它无法链接。这里的问题是文件calculatior.o 甚至不存在,并且make 没有尝试创建它。这意味着您的 makefile 有问题。但是,由于您只向我们展示了有效的版本,而没有向我们展示失败的版本,我们无法为您提供真正的帮助。 @ChristianGibbons 我之前在处理 c++,后来改用 C。我不认为更改编译器会产生不同的结果,因为文件非常基本(仅打印功能) 假设显示的第二个makefile 导致了这个问题,我不明白它是如何产生你所看到的症状的。仅从输出来看,我猜有一条规则告诉 make 它重建 calcular.o calc_interactive.o 但实际上只重建 calc_interactive.o 【参考方案1】:

首先,不要使用 C++ 编译器编译 C 源代码,除非您确定它是严格使用这两种语言的公共子集编写的。 C 和 C++ 各自具有对方所缺乏的特性,并且可以编写符合这两种语言但对各自具有不同含义的代码。除非您在编写双语言代码时有意识且消息灵通,否则请为 C 代码使用 C 编译器。

其次,如果make,正好使用这个makefile:

CC = /usr/bin/g++
OBJECTS_INTERACTIVE = calcular.o calc_interactive.o

calc_interactive: $(OBJECTS_INTERACTIVE)
    $(CC) $(OBJECTS_INTERACTIVE) -o $@  

calcular.o: calcular.h

calc_interactive.o: calcular.h

产生你声称的输出:

jules@desktop:$ make
/usr/bin/g++ -c calc_interactive.c
/usr/bin/g++ calcular.o calc_interactive.o -o calc_interactive
g++: error: calcular.o: No such file or directory 
makefile:11: recipe for target 'calc_interactive' failed 
make: *** [calc_interactive] Error 1

那么最可能的结论是calcular.o 不存在,并且不存在make 知道如何构建它的源文件。特别是,没有calcular.c。这也意味着原来的 makefile 也不能再工作了。也许您不小心删除了源文件,或者在文件名或 makefile 或类似文件中引入了拼写错误。

我认为g++ 的错误消息也有可能具有误导性。如果calcular.o 已经存在并且是最新的,但它的访问控制属性阻止您打开它进行阅读,那么make 不会尝试重建它,但g++ 可能 问题一个误导性的诊断,其中“没有这样的文件或目录”实际上意味着“我无法打开这样的文件”。在这种情况下,删除calcular.o,以便make 需要重建它,可能是最干净的解决方案。

【讨论】:

我将编译器更改为 GCC,但它仍然产生错误的输出。我用一个包含每个文件详细信息的 pastebin 编辑了我的 OP,我仔细检查了所有内容,仍然不知道会发生什么。我知道它可能并不那么重要,但我只是想学习,我无法弄清楚为什么它不起作用。

以上是关于Makefile 中隐式规则中的 -c 标志错误的主要内容,如果未能解决你的问题,请参考以下文章

Makefile 中的隐式规则

Makefile:相似文件的不同标志

makefile失败 - 隐式规则编译一个目标文件但不编译其余文件

makefile(06)_隐式规则

采坑经验:Dubbo 2.6.x版本中隐式参数attachment的错误使用方式,稍不注意就会出现生产事故

Makefile 隐式规则不起作用