linux - Makefile 不生成目标代码或可执行文件
问题描述
我正在尝试编写一个从 .c 文件生成汇编代码、目标代码和可执行文件的生成文件。这是我的makefile的内容:
good_echo.s: good_echo.c
gcc -S -fstack-protector-all good_echo.c
good_echo.o: good_echo.s
gcc -S good_echo.s -o good_echo.o
good_echo: good_echo.o
gcc -v good_echo.o -o good_echo
clean:
rm -f good_echo.o good_echo.s good_echo
当我进入终端时,它只生成汇编代码。有人可以解释发生了什么吗?
解决方案
如果你查看 GNU make 手册How make Processes a Makefile你会注意到这句话:
make 读取当前目录中的 makefile 并从处理第一条规则开始。
接下来是下一段:
如果目标不依赖其他规则(或它所依赖的任何东西等),则不会处理该规则,除非您告诉 make 这样做(使用诸如 make clean 之类的命令)。
在这里,您的第一条规则说要构建good_echo.s
,而其他目标都不是它的先决条件,所以它是唯一构建的。
如果你运行,make good_echo
那么一切都将被构建。或者,您可以确保构建目标的规则是您的 makefile 中good_echo
的第一条规则。
或者,您可以使用常用的成语并创建一个目标all
作为第一条规则,这取决于您要生成的内容:
all: good_echo
需要明确的是,除了 makefile 中的第一条规则之外,定义规则的顺序并不重要。
预计到达时间
正如 Joseph Quinsey 在评论中指出的那样,您的规则是:
good_echo.o: good_echo.s
gcc -S good_echo.s -o good_echo.o
是不正确的。该-S
选项告诉编译器在生成程序集并将其写出后停止,但已经将程序集作为您的输入。您想要一个目标文件,因此您应该使用该-c
选项告诉编译器在生成目标文件后停止(而不是尝试链接):
good_echo.o: good_echo.s
gcc -c good_echo.s -o good_echo.o
更清楚地说:编译器可以通过使用文件的扩展名(在这种情况下是指程序集)来推断它给出的输入.s
类型——或者如果你愿意,你可以使用选项强制它-x
——但它不会推断您想要的输出类型:您始终必须使用-c
、-S
和等选项告诉它-E
。如果您不使用其中任何一个,那么它将运行所有步骤并尝试生成可执行程序。
推荐阅读
- java - 从 Java 连接以编写 Janusgraph 以进行远程遍历
- ruby-on-rails - 如何使用 Arel 语法重写我的 Ruby 方法?
- mocha.js - TypeError:无法存根不存在的自己的属性提取-Sinon,Pact
- laravel-5 - 设置 Laravel 文件系统
- c# - C#中使用块内break语句对数据库连接的影响
- reactjs - React with Truffle contract - 资源必须列在 web_accessible_resources 清单中
- firebase - 减少阅读 Firebase Firestore 集合中的文档
- android - Recyclerview 只显示一个数组
- python - 使用 scapy 和 nfqueue 捕获第 2 层数据包
- mongodb - MongoDB 聚合数组文档