扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
问题1:通过各目标的命令拆分写到不同的地方,会发生什么?
创新互联公司-专业网站定制、快速模板网站建设、高性价比南郑网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式南郑网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖南郑地区。费用合理售后完善,十载实体公司更值得信赖。.PHONY : all
VAR := test
all :
@echo "all : $(VAR)"
include 1.mk
文件1.mk内容:
all :
@echo "this is command from 1.mk"
Makefile中出现同名目标时:
依赖:所有的依赖将合并到一起,成为目标的最终依赖
命令:当多处出现同一目标的命令时,make发出警告,所有之前定义的命令被最后的命令取代。
注意:
当使用include包含其他文件(makefile)时,需要确保被包含的文件中的同名目标只有依赖,没有命令;否则,同名目标的命令将被覆盖!
Make中提供了一些常用的,例行的规则实现,当目标的规则未提供时,make尝试使用隐式规则
下面的代码可以编译成功吗?为什么?
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
app.out : $(OBJS)
$(CC) -o $@ $^
$(RM) $^
@echo "Target ==> $@"
%.o : %.c
@echo "my rule"
$(CC) -c -o $@ $^
根据我们的初步分析,上面的Makefile中存至少两个问题:
1.没有定义CC 和RM变量而直接使用
2.没有定义生成.o文件的规则(只有链接没有编译)
运行结果:
为什么可以成功运行,原因在于make中的隐式规则。
Make中提供了生成目标文件的隐式规则,会使用预定义变量完成编译工作;
改变预定义变量间部分改变隐式规则的行为,当存在自定义规则时,不再使用隐式规则。
目标的依赖不存在时,make会尝试通过依赖名逐一查找隐式规则,并通过依赖名推导出可能的源文件。
这种行为看起来简化了makefile的写法,但可能会带来意想不到的问题。
隐式规则副作用:
编译效率低下:make从隐式规则和自定义规则中选择最终的规则
举例说明:
makefile:
app.out : main.o func.o
$(CC) -lstdc++ -o $@ $^
main.c:
#include
extern void greeting();
int main()
{
greeting();
return 0;
}
由于我们并没有定义greeting这个函数,所以我们猜测编译时会报告链接错误,找不到greeting这个符号。
实际输出结果:
我们看到这里直接使用func.p文件生成func.o文件,但由于我的环境中没有安装pc这个软件,所以报错。整个过程完全和我们预期不同。
隐式规则链:
当依赖的目标文件不存在时,make会极力组合各种隐式规则对目标进行创建,进而产生意料之外的编译行为!
例:需要名为N.o的目标:N.y --> N.c --> N.o
我们可以直接使用make -p命令来查看所有的隐式规则,
1.局部禁用:在Makefile中自定义规则,如定义一个只有目标和依赖,没有命令的规则,如:
%.o : %.p
这样就可以使用我们自定义的规则,而非隐式规则
2.全局禁用
make -r
显然这种简单实用,推荐使用
后缀规则时旧式的“模式规则”,可以通过后缀描述的方式自定义规则
1.双后缀规则:定义一对文件后缀(依赖文件后缀和目标文件后缀)
如: .cpp <---> %.o : %.cpp
2.单后缀规则:定义单个文件后缀(源文件后缀)
如: .c <---> % : %.c
注意:
后缀规则中不允许有依赖,后缀规则必须有命令,否则无意义
已经逐步被模式规则替代,建议直接使用模式规则
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流