赞
踩
目录
patsubst:模式替换函数。pattern:模式,substitute:替换。
在Linux中使用make工具来编译程序(特别是大程序),而make工具所执行的动作依赖于Makefile文件。
当工程复杂度再上一个高度时,会觉得手写Makefile很麻烦时就需要用CMake、autotools等工具生成Makefile,实际上Windows系统下很多IDE工具内部也是使用类似Makefile的方式组织工程文件的,只不过被封装成图形界面,对用户不可见。
make命令根据文件更新的时间戳来决定哪些文件需要重新编译,这使得可以避免编译已经编译过的、没有变化的程序,可以大大提高编译效率。
注意:要想完整地了解Makefile的规则,请参考《GNU Make使用手册》。
Makefile本质:无论多么复杂的语法,都是为了更好地解决项目文件之间的依赖关系。
Makefile三要素:目标、依赖、命令。 格式如下:
目标:依赖
<tab>命令
目标通常是要生成的文件名称,可以是可执行文件或OBJ文件,也可以是一个执行的动作名称(伪目标,比如clean)。
依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。
命令是生成目标时所执行的动作。一个规则可以含有几个命令,每个命令占一行。
注意:每个命令行前面必须是一个Tab字符。
命令被执行的条件:依赖文件比目标文件新 或 目标文件还没生成。
通常,如果一个依赖发生了变化,就需要规则调用命令以更新或创建目标。但是并非所有的目标都有依赖,例如目标clean的作用只是清除文件,并没有依赖。
- targeta:targetb targetc
- echo "targeta"
- targetb:
- echo "targetb"
- targetc:
- echo "targetc"
main.c
- #include <stdio.h>
- int main()
- {
- play();
- stop();
- return 0;
- }
mp3.c
- #include <stdio.h>
- void play()
- {
- printf("play music!\r\n");
- }
- void stop()
- {
- printf("stop music!\r\n");
- }
-
注意:=延迟赋值是指在调用时才会被赋值。 即图中的echo "$(B)"时才把A的值赋给B。
%:匹配任意多个非空字符,相当于shell的*通配符。
.o文件默认使用.c文件进行编译。
学习了Makefile变量,对先前的mp3进行加深。
- ifeq (var1,var2)
- ... //如果var1和var2相等,执行条件
- else
- ... //如果var1和var2不相等,执行条件
- endif
- ifneq (var1,var2)
- ... //如果var1和var2不相等,执行条件
- else
- ... //如果var1和var2相等,执行条件
- endif
Makefile官方手册:https://www.gnu.org/software/make/manual
格式:$(patsubst PATTERN,REPLACEMENT,TEXT)。PATTERN为模式,REPLACEMENT为新模式,TEXT为文本。
示例:$(patsubst %.c,%.o,x.c.c bar.c)
TEXT中有两个单词,分别为x.c.c和bar.c,将单词去匹配模式,即%.c。
可知,x.c.c和bar.c都是.c结尾,所以能匹配模式。能匹配模式的话,就把单词去匹配新模式,即x.c.o和bar.o。
简单来说,把字符串“x.c.c bar.c”中以.c结尾的单词替换成以.o结尾的字符。函数的返回结果是“x.c.o bar.o”。
格式:$(notdir NAMES...)
示例:$(notdir src/foo.c hacks),返回值为“foo.c hacks”。
格式:$(wildcard PATTERN)
示例:$(wildcard *.c),返回值为当前目录下所有.c源文件列表。
格式:$(foreach VAR,LIST,TEXT)
示例:
dirs:=a b c d
$(foreach dir,$(dirs),$(wildcard $(dir)/*))
首先dir=a,执行$(wildcard $(dir)/*)),即找a目录下的所有文件。然后dir=b,执行$(wildcard $(dir)/*)),即找b目录下的所有文件。
以此类推,等同于files:=$(wildcard a/* b/* c/* d/*)
写一个头文件,并把头文件添加到编译器的头文件路径中。gcc -l +"头文件"。
实时检查头文件的更新情况,一旦头文件发生变化,应该要重新编译所有相关文件。
- ARCH?=x86
- ifeq ($(ARCH),x86)
- CC=gcc
- else
- CC=arm-linux-guneabihf-gcc
- endif
-
-
- TARGET=shm
- BUILD_DIR=build
- SRC_DIR=module
- INC_DIR=include
- CFLAGS=$(patsubst %,-I %,$(INC_DIR))
- INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h))
-
- SOURCE=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
- OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCE)))
- VPATH=$(SRC_DIR)
-
- $(BUILD_DIR)/$(TARGET):$(OBJS)
- $(CC) $(^) -o $(@)
- $(BUILD_DIR)/%.o:%.c $(INCLUDE) | create_build
- $(CC) -c $< -o $@ $(CFLAGS)
-
- .PHONY:clean create_build
- clean:
- rm -r $(BUILD_DIR)
- create_build:
- mkdir -p $(BUILD_DIR)
注意:Makefile的内容OBJS中SOURCES少了个S
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。