今天跟大家唠唠我在Makefile里用`patsubst`的故事,这玩意儿,刚开始看文档,一脸懵,后来实操几次,真香!
事情是这样的,之前接个项目,工程里头一堆`.c`文件,编译的时候得生成对应的`.o`文件。原始的Makefile写得那叫一个冗长,每个`.o`文件都得手动指定依赖的`.c`文件。我就寻思,这不行,以后文件多还不得累死?必须得找个办法偷懒。
然后我就盯上`patsubst`。这玩意儿,我开始看的时候,啥` 那怎么用到我的工程里?我先用`$(SOURCES := $(wildcard .c))`搞到一个所有`.c`文件的列表,这`wildcard`也挺好使,一下子就把所有`.c`文件都找出来。然后,我就琢磨着怎么把`.c`换成`.o`。 我尝试着写:`$(OBJECTS := $(patsubst %.c, %.o, $(SOURCES)))`。 这一句的意思就是,把`$(SOURCES)`里的所有`.c`结尾的文件,替换成`.o`结尾的文件,存到`$(OBJECTS)`里。 刚开始我还不太确定能不能行,编译一下,成!所有的`.o`文件都自动生成,Makefile一下子简洁不少。 但是问题又来,光生成`.o`文件还不行,还得告诉编译器,每个`.o`文件依赖哪个`.c`文件。总不能每个`.o`都依赖所有的`.c`文件? 我又开始翻文档,折腾一下午,终于搞明白。我写一个规则: makefile $(OBJECTS): %.o: %.c $(CC) -c $< -o $@ 这啥意思?意思是说,所有的`.o`文件,都依赖对应的`.c`文件。`<`是第一个依赖文件,`@`是目标文件。这样,make就知道每个`.o`文件该怎么编译。 把这两招结合起来,整个Makefile就变得非常简洁。以后再添加新的`.c`文件,只需要把`.c`文件放到工程目录里,make会自动找到它,编译成`.o`文件,然后链接成可执行文件。 现在回想起来,刚开始学`patsubst`的时候,确实觉得挺难的。但是当你真正把它用到实际项目中,解决问题的时候,就会觉得这玩意儿真香。而且通过这回实践,我对Makefile的理解也更深一层。所以说,实践才是检验真理的唯一标准嘛 总结一下这回的实践过程: 搞定! 希望我的这回实践经历能对大家有所帮助。Makefile这东西,看着难,用起来也挺有趣的,多动手试试,你也能成为Makefile高手!