如何正确组合gcc标志-o和-MM?

问题描述 投票:1回答:1

在简单程序的编译和链接期间,我遇到了无法解释的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语句随附的文件中。似乎已对目标文件进行了某种修改,以使链接程序无法再读取它们。

有什么建议吗?

gcc dependencies linker-errors
1个回答
1
投票

您的目标文件被截断为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中输出>

    要执行所需的操作,请在命令中将选项-MM替换为-MMD。在文档中,您将看到:

    -MD

    -MD等效于-M -MF文件,只是不隐含-E ... ... [由于不隐含-E,因此-MD可以用作生成依赖项输出文件,作为编译的副作用过程。

    -MMD

  • 类似于-MD,只提及用户头文件,不提及系统头文件。

    [我的重点]
    © www.soinside.com 2019 - 2024. All rights reserved.