makefile - Makefile 与 Windows 资源文件的循环依赖关系
问题描述
在运行 Makefile 时,有几个关于循环依赖关系下降的问题(这里和这里),但是,我仍然对它们发生的原因感到有些困惑。
例如,我正在尝试编译一个包含资源文件的 Win32 GUI 程序(来自本教程)。这些资源文件通过windres
命令编译为目标文件,因此它们可以链接到最终的可执行文件(如此处所述):
CC = gcc
CFLAGS = -mwindows
DEPS = resource.h
OBJ = menu_one.o $(patsubst %.rc,%.rc.o,$(wildcard *.rc))
all: menu_one
%.rc.o: %.rc
windres $^ -o $@
%.o: %.c $(DEPS)
$(CC) -c $< -o $@ $(CFLAGS)
menu_one: $(OBJ)
$(CC) $^ -o $@ $(CFLAGS)
该命令$(patsubst %.rc,%.rc.o,$(wildcard *.rc))
获取所有以结尾的资源文件.rc
并.o
在它们上添加扩展名(例如resource.rc.o
)。
当我运行它时,一切似乎都正常工作,并且我得到了一个工作可执行文件,但是,Make 输出以下内容:
gcc -c menu_one.c -o menu_one.o -mwindows
make: Circular menu_one.rc <- menu_one.rc.o dependency dropped.
windres menu_one.rc -o menu_one.rc.o
gcc menu_one.o menu_one.rc.o -o menu_one -mwindows
这种循环依赖的发生是因为我在技术上有两个.o
规则吗?换句话说,我该如何纠正这种循环依赖?
编辑1:
我尝试按照@MadScientist所说的进行操作,但是,这仍然与 Make 产生了循环依赖关系。经过一番谷歌搜索后,我发现了以下页面。在最底部有一个标题为“循环文件依赖项”的部分。这让我想到了 Make 的输出:
make: Circular menu_one.rc <- menu_one.rc.o dependency dropped.
看起来是rc
后缀创建了这种依赖关系——即使它不是输出目标文件的文件扩展名的一部分(即file.rc.o
)。如果我将输出文件后缀更改为.res.o
,则循环依赖将完全消失:
...
RESOBJ = $(patsubst %.rc,%.res.o,$(wildcard *.rc))
OBJ = menu_one.o $(RESOBJ)
...
%.res.o: %.rc
windres $^ -o $@
...
这引发了一个非常相似的问题,如果我想使用前面的后缀.rc.o
,你将如何完成这个?可能吗?
编辑2:
@MadScientist建议使用match-anything 规则完美地解决了这个问题。这现在允许我使用.rc.o
后缀结尾。请参阅下面@MadScientist的更新答案。
解决方案
一种方法是不使用扩展名命名windres
输出文件。.o
如果您选择不同的扩展名,则不会出现此问题。
另一种方法是对目标使用静态模式规则windres
:
RCOBJ := $(patsubst %.rc,%.rc.o,$(wildcard *.rc))
OBJ = menu_one.o $(RCOBJ)
...
$(RCOBJ) : %.rc.o : %.rc
windres $^ -o $@
由于静态模式规则是创建显式规则的简写,而不是隐式规则,它们不参与搜索,因此 make 不会产生循环依赖。
预计到达时间
好的,我在本地创建了您的示例。使用make -d
我们可以看到会发生什么:make 需要构建menu_one.rc.o
并且它找到我们的规则,前提是menu_one.rc
. 然后它需要查看它是否可以重新manu_one.rc
构建,并找到构建可执行文件的通用模式规则:
%: %.o ; ...
将此模式与目标匹配menu_one.rc
给出了先决条件menu_one.rc.o
,并且您有一个循环。
您需要做的是通知 make 这些*.rc
文件是源文件并且 make 不应该尝试构建它们。您可以通过声明终端规则来做到这一点。GNU make 手册中全面讨论了处理match-anything 规则(目标为单独的规则,它匹配任何目标)的复杂性。%
添加这个以通知 make 你的.rc
文件是终端的(也就是说,它们不能从其他东西构建):
%.rc:
推荐阅读
- swift - 如何将 FBSDKCoreKit 集成到 Swift 自定义框架中?
- sql - 旋转附加 24 笔贷款的最后 6 笔付款
- bash - grep 两个模式之间的字符串 文件中的多个实例?
- php - 使用模式构建器 hasTable 方法阐明数据库问题
- r - 闪亮的流体行下的while循环
- javascript - 我正在尝试将提供不和谐机器人的反应转换为在使用特定反应时发送消息的机器人。我无法让它回应
- google-chrome - 字体在 Firefox 中看起来更大
- google-apps-script - 通过 Google Apps 脚本安全地调用 Google Cloud 函数
- angular - 如何在 WebStorm / PhpStorm 中启用自定义 Angular 库的自动导入?
- c# - 将 2 个不同 texbox 中的 2 个 txt 文件从小写转换为大写