c - Makefile 中的自动变量未正确扩展
问题描述
我正在使用以下代码:
HELLO_WORLD=hello
$(HELLO_WORLD): $(addsuffix .c,$@)
gcc $< -o $@
但是,当我运行代码时,我收到以下错误,这意味着 $< 没有对任何东西进行评估:
gcc -o hello
gcc: fatal error: no input files
当我使用以下代码时...
HELLO_WORLD=hello
$(HELLO_WORLD): $(addsuffix .c,$@)
gcc $(addsuffix .c,$@) -o $@
... Makefile 评估为以下命令...
gcc hello.c -o hello
...这正是我想要的。但是,我不想使用 adduffix 两次。如果我更改了先决条件,我想使用 $<。我该怎么做呢?
解决方案
问题不$<
在于配方中的扩展。$@
问题是先决条件列表中的扩展。
自动变量,例如$@
,仅在配方中定义,而不在目标或先决条件列表中定义。这在自动变量的 GNU Make 手册部分中突出显示:
一个常见的错误是尝试
$@
在先决条件列表中使用;这行不通。
实际上hello.c
不在先决条件列表中的事实并不妨碍您调用make hello
. 它只是意味着make hello
将始终调用编译器,即使hello.c
没有被修改。但这确实意味着$<
它将与计算的先决条件列表一样为空。
GNU make 确实有一个功能可以让您对先决条件进行第二次扩展;这在手册中有说明。但更简单的解决方案是根本不依赖于$@
先决条件列表。如果您尝试创建自己的通用 C 编译配方,请为目标文件 ( .o
) 目标使用模式规则。对于最终可执行文件,列出最终可执行文件的所有先决条件(几乎可以肯定不止一个文件)。
通常这是使用具有SRCS
和OBJS
(或者SOURCES
如果OBJECTS
您不介意键入元音)名称的单独变量来完成的。通常,您将目标文件作为最终可执行文件的先决条件(这将是一个链接操作),因为每个单独的源文件都有自己的头文件先决条件。
推荐阅读
- flutter - 颤振本地化加载后如何重新加载应用程序
- docker - 如何从 docker 注册表中删除空存储库
- algorithm - 在排名(排序)列表上执行前缀搜索的有效方法?
- symfony - Composer 更新成功,但 Composer 安装在创建的锁定文件上失败
- dynamics-crm - 将 crm 动态升级到本地 9.0.5 后出现 bpf 错误
- excel - 从 Workbook_Open() 运行时,Workbooks.Add 不会激活新工作簿
- python - 不确定的进度条不会在 python tkinter 中停止
- mysql - Mysql 拒绝完成某些命令,返回无穷无尽的 '<'
- php - Jquery 不发送 textarea name="post_description"
- java - 添加矩阵运算。矩形之间