-o并非编译参数,而是gcc内部的重命名参数。真正参与编译的参数有-c -s -e等。html
gcc -o test main.c 若不制定相似于-c -s -e这样的编译参数,直接使用-o参数,gcc会自动默认执行-c -s -e参数,并根据-o参数指定的名称生成可执行文件。
https://www.cnblogs.com/zhangpengshou/p/3587751.htmllinux
2.1.一、变量定义与变量操做shell
https://blog.csdn.net/naughfy/article/details/80150312tcp
obj = test.c
obj := test.c
二者之间的区别?函数
变量追加、变量替换 makefile 文件变量赋值有如下几种 = // 最通用的用法,用在递归展开方式较多 := //变量必须以前就定义了,用在直接展开方式较多 ?= 若是该变量没有赋值,则对该变量赋值 += 给变量追加赋值 @echo $(OPT) // 变量使用 make OPT=add //make 传递参数
2.1.一、变量参数传递
https://blog.csdn.net/darennet/article/details/9003010学习
//宏定义参数传递,用于源代码中宏开关。 CFLAGS += -D POSGP730 -D*表示:#define * 如:-DPOSGP730等价于#define POSGP730 -Wall 表示打开全部编译告警信息 -O2表示优化级别
在makefile中能够预先使用一个未定义的变量, 这个变量能够在make执行时传递给它
好比makefile中有这么一行
include $(M)/$(COMPAT_CONFIG)
这个M能够经过make传递过来
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
其中的M就是$(PWD)
甚至能够进行更复杂的操做, 就像在Makefile中同样
make CFLAG=-DDEBUG优化
2.1.一、编译查找规则
一、入口: makefile认为"第一个目标做为入口。 重点:第一个、目标。
二、依赖性查找
三、若能找到,则执行对应的操做。(显示)
四、若找不到,makefile强大的自动推倒能力,执行隐士的相关操做。(隐士)ui
//显示 all:test1.o test2.o gcc -o $@ $^ test1.o:test1.c gcc -o test1.o test1.c test2.o:test2.c gcc -o test2.o test2.c //隐士 all:test1.o test2.o gcc -o $@ $^ test1.o: //自动推倒依赖test1.c 并编译cc -c -o test1.0 test1.c test2.o: //隐士 all:test1.o test2.o gcc -o $@ $^ //自动推倒目标与依赖,并编译cc -c -o test1.0 test1.c
2.1.二、可执行文件生成规则
makefile最终编译生成的可执行程序与伪目标没有任何关系,仅仅取决于arm-linux-gcc -o 以后所定义的名称。 (通常也采用@<)使其名字与伪目标相同。.net
2.1.二、新旧比对编译
一、若是目标不存在,执行命令。(包括依赖和命令)
二、若是目标存在,依赖文件有更新(依赖文件是递归的,找依赖的依赖,若是有更新,就更新)。执行命令。
三、若是目标存在,且依赖没有更新,(递归的,包括依赖的依赖。。。),不更新,不执行命令。code
https://www.cnblogs.com/warren-wong/p/3979270.html
$@:目标的名字 $^:构造所需文件列表全部全部文件的名字 $<:构造所需文件列表的第一个文件的名字 $?:构造所需文件列表中更新过的文件 //$@:就是test1.o $<:就是test1.c test1.o:test1.c gcc -o $@ $< // $^:就是test1.c head.c test1.o:test1.c head.c gcc -o $@ $^
%与*通配符的关系:
转义符的使用:
https://blog.csdn.net/liuzhuchen/article/details/51776820
if then else then
ifep
wildcard扩展通配符
Makefile规则中,通配符会被自动展开。但在变量
的定义和函数引用
时,通配符将失效。这种状况下若是须要通配符有效,就须要使用函数“wildcard”,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的全部文件列表。若是不存在任何符合此模式的文件,函数会忽略模式字符并返回空。
//使用说明 obj = $(wildcard *.c)
//变量定义与函数引用通配符失效,举例说明 //好比函数为swapfun,使用通配符的方式去引用函数 obj = %.c $(*fun argument)
notdir去除路径
去除全部的目录信息,SRC2里的文件名列表将只有文件名,去除掉已xx.c命名的文件夹信息。
SRC = $(wildcard *.c) SRC2 = $(notdir wildcard)
patsubst 替换通配符
patsubst( patten substitude, 匹配替换的缩写)函数。
它须要3个参数:第一个是一个须要匹配的式样,第二个表示用什么来替换它,第三个是一个须要被处理的由空格分隔的字列。例如,处理那个通过上面定义后的变量,
OBJS = $(patsubst %.c,%.o,$(SRC2 ))
这行将处理全部在 SRC2 列个中的字(一列文件名),若是它的 结尾是 '.c' ,就用'.o' 把 '.c' 取代。
//使用举例 SOURCES = $(wildcard *.c) FILES = $(notdir$(SOURCES)) OBJS = $(patsubst %.c, %.o, $(FILES) ) SRC = $(wildcard *.c) OBJ = $(patsubst %.c,%.o,$(notdir ${SRC}))
TARGET = arm-none-linux-gnueabi CC = $(TARGET)-gcc AR = $(TARGET)-ar LD = $(TARGET)-ld STRIP = $(TARGET)-strip CFLAGS = -Wall -I../../include -I../../../include -fPIC LDFLAGS = -L../../lib -ldrivercomm -lmodbus -lmodbustcp -lprintmanage -L ../../lib.arm -lxmlrpcsys ifeq (1,${release}) CFLAGS += -Os else CFLAGS += -g -DDEBUG_PRINTF endif NAME = CL_DL_JG_YJ_BMU-H1 PROGRAM_OUTPUT = $(NAME).so PAC_OUTPUT = $(NAME).pac PROGRAM_OBJS = Driver.o TEST_OUTPUT = test TEST_OBJS = Test.o all: program test program: version.h $(PROGRAM_OBJS) $(CC) -shared $(PROGRAM_OBJS) $(LDFLAGS) -o $(PROGRAM_OUTPUT) ../../pack/pack $(NAME) test: version.h $(TEST_OBJS) $(CC) $(TEST_OBJS) -o $(TEST_OUTPUT) $(LDFLAGS) -ldl newversion: @if [ ! -f .version ]; then \ echo 1 > .version; \ else \ expr 0`cat .version` + 1 > .version; \ fi compile.h: newversion @echo \#define SOFTWARE_COMPILE_TIME \"`date +%H:%M:%S`\" >> .ver @echo \#define SOFTWARE_COMPILE_DATE \"`date +%Y/%m/%d`\" >> .ver @echo \#define SOFTWARE_COMPILE_BY \"`logname`\" >> .ver @echo \#define SOFTWARE_COMPILE_HOST \"`hostname`\" >> .ver @echo \#define SOFTWARE_COMPILER \"`$(CC) -v 2>&1 | tail -1`\" >> .ver @mv -f .ver $@ version.h: compile.h @echo \#define SOFTWARE_BUILD_VERSION `cat .version` >> .ver @mv -f .ver $@ .PHONY: clean clean: @rm -f *.o *.d version.h compile.h @rm -f $(PROGRAM_OUTPUT) $(TEST_OUTPUT) $(PAC_OUTPUT) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $<
以上述makefile为例,分析makefile的查找规则与执行熟悉。
https://blog.csdn.net/skywalkzf/article/details/6926395
makefile学习笔记: https://www.cnblogs.com/wang_yb/p/3990952.html
strip:
函数名称:去空格函数—strip。
函数功能:去掉字串开头和结尾的空字符, 若字串中间部分也包含空格,则会多个连续空字符合并为一个空字符。
示例:
STR = a b c
LOSTR = $(strip $(STR))
结果是“a b c”。
makefeil:fileter函数 foreach函数
https://www.cnblogs.com/lengbingshy/p/3936116.html
https://www.cnblogs.com/yuguangyuan/p/10929967.html
https://blog.csdn.net/zhoudengqing/article/details/41777957
https://www.cnblogs.com/GyForever1004/category/1155268.html
makefiel中使用shell的语法进行判断
在Makefile中执行shell命令,一行建立一个进程来执行。这也是为何不少Makefile中有不少行的末尾都是“; ”,以此来保证代码是一行而不是多行,这样Makefile能够在一个进程中执行
http://ju.outofmemory.cn/entry/322934
# 适用与.h与.c处于同一文件的工程 CC = gcc CFLAGS = -Wall LIB = -lpthread -levent -lssl -ldl -lcrypto -levent_openssl #去除编译连接的文件 CLIENT_IGNORE_SOURCE := https-server.c SERVER_IGNORE_SOURCE := https-client.c #分别获取须要连接的文件 CLIENT_LOCAL_SOURCE = $(filter-out $(CLIENT_IGNORE_SOURCE),$(wildcard *.c)) SERVER_LOCAL_SOURCE = $(filter-out $(SERVER_IGNORE_SOURCE),$(wildcard *.c)) CLIENT_LOCAL_OBJ = $(patsubst %.c,%.o,$(notdir ${CLIENT_LOCAL_SOURCE})) SERVER_LOCAL_OBJ = $(patsubst %.c,%.o,$(notdir ${SERVER_LOCAL_SOURCE})) all: @echo "Wrong build option, please run 'make client' or "make server" to build."; @exit 13; client:${CLIENT_LOCAL_OBJ} $(CC) $(CLIENT_LOCAL_OBJ) -o $@ $(LIB) server:${SERVER_LOCAL_OBJ} $(CC) $(SERVER_LOCAL_OBJ) -o $@ $(LIB) %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm *.o client server