1 -static 这个选项,当gcc连接库的时候,如果同时存在静态库和共享库,默认是连接共享库,而指定了-static 就优先连接静态库。
2 WEC_LDFLAGS=-I$(LIB) -I$(LIB1) 这是一句字符串展开替换,然后赋值给WEC_LDFLAGS,就类似于sprintf(WEC_LDFLAGS, "-l%s -l%s" , LIB, LIB1) 这种语法在makefile里面很常用。其实CC=arm-linux-gcc -O2 -I$(INC) -I$(INC1) -static 和这句的道理是一样的,都是展开替换。
3 LIBS= -lpthread -lc -lgcc -liconv -lfreetype -lpng -lz -lm -ljpeg -lgif 这句是什么意思,这句是你这个makefile,连接时所有库的选项。可以把它看成一个字符串,(其实makefile里面定义这些变量,都是字符串)这里定义的LIBS变量的具体用处下面再说。至于你问的-l和-L的区别 -llibrary指定连接某一个库,-Ldir指定连接时搜索库的路径;比如你自己的库,或者下载的第三方库,不然编译器将只在标准库的目录找,这个dir就是目录的名称。而-I(大写i)指定了编译时的头文件搜索目录。
4
all:
$(CC) $(WEC_LDFLAGS) $(SRCS) -o $(TARGET) $(LIBS)
//$(LIBS)这个干嘛的?
这句才是makefile的核心 这种target:语法,是定义了一个工作目标。
all:是make默认的工作目标,它干了些啥呢
首先 $(CC) 展开了这个变量CC=arm-linux-gcc -O2 -I$(INC) -I$(INC1) -static 其实就是调用gcc的命令行字符串。
然后 $(WEC_LDFLAGS)展开了这个变量WEC_LDFLAGS=-I$(LIB) -I$(LIB1) 其实是指定了库目录,我猜你抄错了吧这里看着就应该是-L$(LIB) -L$(LIB1)
然后 $(SRCS)展开了源文件tom_ACDC.c uart_control.c lcm.c font.c touch.c control.c database.c communication.c filesystem.c rtc.c gprs.c
然后 $(TARGET)展开了编译目标 tom_ACDC_02
然后 $(LIBS) 展开需要连接的单个库,到此,工作目标的第一个命令行字符串就构造完毕了
这行$(CC) $(WEC_LDFLAGS) $(SRCS) -o $(TARGET) $(LIBS)就等价于运行一个shell命令:
arm-linux-gcc -O2 -I$(INC) -I$(INC1) -static -L/usr/local/arm_linux_4.2/lib/gcc/arm-linux/4.2.1
) -L/usr/local/arm_linux_4.2/arm-linux/lib tom_ACDC.c uart_control.c lcm.c font.c touch.c control.c database.c communication.c filesystem.c rtc.c gprs.c -o tom_ACDC_02 -lpthread -lc -lgcc -liconv -lfreetype -lpng -lz -lm -ljpeg -lgif 这就是展开后实际运行的命令,分开定义然后展开是为了方便大家扩展,和维护,要是不这样,直接给你写这么长一串东西,谁看了都得晕。
5
$(STRIP) $(TARGET)
//这句什么意思?
这句其实是工作目标all的第二行命令
展开后其实很简单就是arm-linux-strip tom_ACDC_02
这句的用处就是在4里面命令编译连接生成目标文件tom_ACDC_02后,再调用arm-linux-strip来去掉目标文件中的调试信息,减小文件大小。
6
clean:
rm -f *.o
......
rm -f *.gdb
//为什么要清除这些呢? 源文件都没有的。
这里,clean是这个makefile的第二个工作目标,这个工作目标平时是不执行的
只有你在用make clean这样来运行make的时候才会执行这个工作目标,也很简单就是单纯的清除中间文件而已。
GUNmake太博大精深了,是可以用一辈子的东西,如果要深入了解,你可以研习附件里面的GNUmake的教程。
条件语句中使用到了三个关键字:“ifeq”、“else”和“endif”。其中:
此关键字用来判断参数是否相等,格式如下:
`ifeq 'ARG1' "ARG2"'替换展开“ARG1”和“ARG1”后,对它们的值进行比较
通常我们会使用它来判断一个变量的值是否为空(不是任何字符)。
参数值可能是通过引用变量或者函数得到的,因而在展开过程中可能造成参数值中包含空字符(空格等)。
一般在这种情况时我们使用make的“strip”函数来对它变量的值进行处理,去掉其中的空字符。
格式为:
即就是在“$(foo)”中存在若干前导和结尾空格,
“TEXT-IF-EMPTY”也会被作为Makefile需要执行的一部分。
关键字“ifneq”实现的条件判断语句和“ifeq”相反
关键字“ifdef”用来判断一个 变量 是否 已经 定义。
ifdef 只是测试一个变量是否有值,
不会对变量进行 替换展开 来判断变量的值 是否 为空。
对于变量“VARIABLE-NAME” ,除了
“VARIABLE-NAME=”这种情况以外,使用 其它方式 对它的定义都会使“ifdef”返回 真 。
就是说,
即使我们通过 其它方式 (比如,定义它的值引用了其它的变量)给它赋了一个 空值 , “ifdef”也会返回真。
举例:
例 1中的结果是:“frobozz = yes” ;
而例 2的结果是:“frobozz = no”。
其原因就是在例 1中,变量“foo”的定义是“foo = $(bar)” 。
虽然变量“bar”的值为空,
但是“ifdef”判断的结果是真。
因此当我们需要 判断一个变量的值是否为空 的情况时,
需要使用 ifeq (或者 ifneq )而不是“ifdef”
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)