在简单程序的编译和链接期间,我遇到了无法解释的gcc
怪异行为。
这对我来说很好用
cc -Wall -c -o obj/main.o src/main.c
cc -Wall -c -o obj/foo.o src/foo.c
cc -Wall -o bin/program obj/main.o obj/foo.o
但是,一旦我要求gcc
在单独的文件中创建并存储依赖项信息,链接器就会引发错误:
cc -MM -MP -MF deps/main.d -Wall -c -o obj/main.o src/main.c
cc -MM -MP -MF deps/foo.d -Wall -c -o obj/foo.o src/foo.c
cc -Wall -o bin/program obj/main.o obj/foo.o
# obj/main.o: file not recognized: File truncated
# collect2: error: ld returned 1 exit status
我希望gcc
将依赖项信息写入-MF语句随附的文件中。似乎已对目标文件进行了某种修改,以使链接程序无法再读取它们。
有什么建议吗?
您的目标文件被截断为0字节,这是预处理器选项-MM
的副作用
参考the documentation of GCC's preprocessor options并且您看到-MM
与-M
具有相同的效果,除了没有针对任何系统头生成依赖项规则#include
-由翻译单元编辑。
对于-M
选项,您将看到:
而不是输出预处理结果,而是输出一条适合于描述主源文件依赖性的规则...
还有:
将-M传递给驱动程序意味着-E ...
然后转到选项-E
,您会看到:
如果使用-E选项,则除预处理外什么都不做。
(实际上有点草率。它实际上应显示为:“如果使用-E选项,则除预处理外,不进行任何[[translation。”]
-o filename
选项指定所请求的输出文件是任何类型-预处理的代码,汇编,目标代码或二进制文件-应将其写入filename
。例如,命令
cc -MM -MP -MF deps/main.d -Wall -c -o obj/main.o src/main.c
指示编译器(除其他外):-
-E
。]-MM
)obj/main.o
);改为写入deps/main.d
(通过-MF deps/main.d
)obj/main.o
被破坏并打开以接收以下文件的输出预处理没有预处理的输出;生成的依赖关系规则被写入deps/main.d
,并在命令完成后关闭obj/main.o
,其中包含0个字节。相同obj/foo.o
发生了事情。当然,这不是您想要的。选项-M
和-MM
仅用于生成依赖文件独立于编译。但是你想要一个命令来生成一个依赖文件deps/<name>.d
和
obj/<name>.o
中输出>要执行所需的操作,请在命令中将选项 -MD-MM
替换为-MMD
。在文档中,您将看到:-MD等效于-M -MF文件,只是不隐含-E ... ... [由于不隐含-E,因此-MD可以用作生成依赖项输出文件,作为编译的副作用过程。
-MMD
类似于-MD,只提及用户头文件,不提及系统头文件。
[我的重点]