如何正确组合 gcc 标志 -o 和 -MM?
How to combine gcc flags -o and -MM correctly?
在一个简单程序的编译和链接过程中,我遇到了一个我无法解释的怪异行为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 语句提供的文件中。目标文件似乎以某种方式被修改,以至于链接器无法再读取它们。
有什么建议吗?
您的 object 文件被截断为 0 字节作为预处理器选项 side-effect -MM
参考the documentation of GCC's preprocessor options
并且您会看到 -MM
与 -M
具有相同的效果,只是不针对任何系统生成依赖规则 headers
#include
-由翻译单位编辑。
对于 -M
选项,您将看到:
Instead of outputting the result of preprocessing, output a rule suitable for make describing the dependencies of the main source file...
还有:
Passing -M to the driver implies -E...
然后转到选项 -E
你会看到:
If you use the -E option, nothing is done except preprocessing.
(这实际上有点草率。真的应该这样写:“如果你使用 -E 选项,除了预处理之外没有完成 translation。”)
-o filename
选项指定无论请求何种输出文件 - 预处理代码、汇编、object 代码或二进制 - 都应写入 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
和一路翻译到object代码,输出在obj/<name>.o
要执行您想要的操作,请将命令中的选项 -MM
替换为 -MMD
。在文档中,您将看到:
-MD
-MD is equivalent to -M -MF file, except that -E is not implied... Since -E is not implied, -MD can be used to generate a dependency output file as a side effect of the compilation process.
-MMD
Like -MD except mention only user header files, not system header files.
[我的重点]
在一个简单程序的编译和链接过程中,我遇到了一个我无法解释的怪异行为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 语句提供的文件中。目标文件似乎以某种方式被修改,以至于链接器无法再读取它们。
有什么建议吗?
您的 object 文件被截断为 0 字节作为预处理器选项 side-effect -MM
参考the documentation of GCC's preprocessor options
并且您会看到 -MM
与 -M
具有相同的效果,只是不针对任何系统生成依赖规则 headers
#include
-由翻译单位编辑。
对于 -M
选项,您将看到:
Instead of outputting the result of preprocessing, output a rule suitable for make describing the dependencies of the main source file...
还有:
Passing -M to the driver implies -E...
然后转到选项 -E
你会看到:
If you use the -E option, nothing is done except preprocessing.
(这实际上有点草率。真的应该这样写:“如果你使用 -E 选项,除了预处理之外没有完成 translation。”)
-o filename
选项指定无论请求何种输出文件 - 预处理代码、汇编、object 代码或二进制 - 都应写入 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
和一路翻译到object代码,输出在obj/<name>.o
要执行您想要的操作,请将命令中的选项 -MM
替换为 -MMD
。在文档中,您将看到:
-MD
-MD is equivalent to -M -MF file, except that -E is not implied... Since -E is not implied, -MD can be used to generate a dependency output file as a side effect of the compilation process.
-MMD
Like -MD except mention only user header files, not system header files.
[我的重点]