生成文件覆盖默认隐式规则
Makefile overriding default implicit rule
为什么此规则不能覆盖默认隐式规则?
当调用 make 时,如下所示:make myapp
(假设 myapp.c 在那里)。make 运行默认命令来构建和链接程序,而不是在此隐式规则中定义的命令:
#... omitted code
LCUS=$(LIBS)/libcus.a
#... omitted code
% : %.o $(LCUS)
echo !!! Custom build !!!
$(MY_CMD) $< -o $@ $(LCUS)
自GNU在线make
手册:
您可以覆盖内置隐式规则(或已定义的规则) 你自己)通过定义具有相同目标的新模式规则和 先决条件,但命令不同。
所以我假设这是因为先决条件与隐式规则不同。
另请参阅make
手册:
链接单个对象文件
n
由n.o
自动通过 通过C编译器运行链接器(通常称为ld
)。这 使用的精确命令是$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
。 此规则对于只有一个的简单程序做正确的事情 源文件。如果有多个,它也会做正确的事情 目标文件(可能来自各种其他源文件),一个 其名称与可执行文件的名称匹配。因此x: y.o z.o
当
x.c
时,y.c
和z.c
都将执行:cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x rm -f x.o rm -f y.o rm -f z.o
所以基本上make
理解从.o
文件生成的程序文件的隐式规则,但是当你扔进静态库时,它就不理解了。 一种简单的测试方法是从依赖项中删除$(LCUS)
(作为临时措施),以查看它是否随后使用您的规则而不是内置的规则。 如果是这样,那么你就知道那是你的问题。 如果只是添加myapp
来替换%
是一个问题,因为您希望规则构建多个目标,则可以尝试以下操作:
$(APPS): % : %.o $(LCUS)
其中$(APPS)
是一个变量,包含您要构建的所有应用程序。 这将允许一个规则构建多个目标。 您也可以完全跳过变量的使用,并放置一个空格分隔的列表。 这是静态模式规则的示例,可在此处找到更多信息。 静态模式和隐式规则之间的区别可以在这里找到。
您的规则与内置隐式规则不同,因此它不会取消它。
此外,make 始终首选不需要生成中间文件的规则。如果您预先创建.a
文件,则可能会改用您的规则(但甚至可能仍然不会)。
如果您取消内置规则并将规则保留在原位,我相信它应该可以正常工作。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 如何使用默认参数等选择模板专业化
- 具有默认模板参数的多态类的模板推导失败
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 此代码是否违反一个定义规则
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 初始化具有非默认构造函数的std::数组项的更好方法
- 何时提供默认参数作为模板参数
- 是默认情况下分配给char数组常量的值
- 生成文件不对文件使用隐式规则
- 具有默认值的引用获取函数
- 具有默认模板类型的默认构造函数的类型推导
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- C++模板函数的默认参数的 ODR 规则
- 哪些规则控制参数默认赋值?
- 对于默认定义的移动构造函数,noexcept的规则是什么
- 默认模板参数是否进入单定义规则
- C++ STL 映射和设置容器的 insert() 函数违反了默认参数的规则?
- 生成文件覆盖默认隐式规则
- 已删除的默认构造函数(和复制控件成员)缺少规则