Chinaunix首页 | 论坛 | 博客
  • 博客访问: 520779
  • 博文数量: 137
  • 博客积分: 3170
  • 博客等级: 中校
  • 技术积分: 1455
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-17 11:47
文章分类

全部博文(137)

文章存档

2015年(2)

2013年(1)

2012年(6)

2011年(5)

2010年(62)

2009年(61)

我的朋友

分类: LINUX

2009-07-25 18:53:39

   #井号键 pound key hash key

1.可以不是对整个工程编译,例如:make foo.c ,便于快速解决语法错误。

2.非真正执行make命令   make --just-print   make -n 显示make的执行过程
3. target1,target2,target3:prequsites1,preqisites2
     command1
     command2
     command3
如果右边没有依赖对象,则只当目标不存在时,才会去update
4.PHONY target(不代表文件的目标) 规则所相应的命令,总是会执行,因为它不存在。用.PHONY可以声明一个phony目标,这样可以避免和存在的同名文件冲突。另外,还有empty target,这个target可以作为一个时间戳吧。
还是理解的不深入。以下中有一段很深入的对于phony target的例子,很棒!

5.自动变量 automatic variables,还是比较常用的
$@   target---目标
$%   The filename element of an archive member specification---依赖
$< The filename of the first prerequisite--第一个依赖
$? The names of all prerequisites that are newer than the target, separated by
spaces.所有比target新的依赖。
$^ The filenames of all the prerequisites, separated by spaces.
5.1  关于变量:

以下是很好的讲解makefile的blog
http://blog.electric-cloud.com/2009/03/23/makefile-performance-shell/

FOO=abc
BAR_1:=$(FOO)
BAR_2 =$(FOO)
FOO=def

all:
    @echo $(BAR_1)
    @echo $(BAR_2)

输出:

abc
def

上面的BAR_1为简单变量,它是立即替换为abc, BAR_2是recursive variable ,它是用到的时候替换的。

6.  VPATH包含一系列的目录,这些目录是供target和prerequisites搜索的,而非命令行中的文件。
make在当前目录找不到相关文件时会进入这些目录,会遍历vpath目录,会使用第一个找到的文件,
注意VPATH和vpath是不同的!!!!
    VPATH的标准格式  :
vpath pattern directory-list
例如:
vpath %.c src
vpath %.h include
讲述VPATH和vpath区别的好文章!
http://hi.baidu.com/lavrock/blog/item/9baf607e97dd59310dd7da47.html
7.“%”的意思是匹配零或若干字符,类似于unix的*
8.查看依赖文件 gcc -M stdio.h,有时候需要加上-I 指令,否则无法
正确显示。
9.采用-l来链接库效率更好,移植性更好
对于.a和.so文件,makefile优先在通用路径中查找
-L选项可以重新定位搜索路径
10.两种方法链接库文件生成可执行文件
cc count_words.o libcounter.a /lib/libfl.a -o count_words

cc count_words.o -lcounter -lfl -o count_words

11.libname.a(module.o)
库名(成员名),便于更新.a库的作用吧
libgraphics.a(bitblt.o): bitblt.o
$(AR) $(ARFLAGS) $@ $<
ar命令可以把一些.o文件集成到.a文件里。
-lfl 和usr/lib/libfl.a都可以通过链接,但是-lfl链接的是/usr/lib/libfl.so(测试环境ubuntu9.04),链接器首先查找shared library  , 而后是archive library。
-L 可以链接指定的lib目录。
-l出现在prerequisites里面,make 查找这个库,倾向于shared library,然后替代为绝对
径。                                                              ***对于由makfile自身编译生成的libraries,不能用-l
***库在命令行中的排列顺序也是很重要的!
the order of libraries on the command
line is of fundamental importance.
***circular references or circularities
问题。
***p39库的相互依赖讲得很好,可以以后参考!


12.非常规范的makefile
/home/jacky/tstProject/example_make/ch02-cw5中的Makefile
VPATH      = src include
CPPFLAGS = -I include
count_words: count_words.o counter.o lexer.o -lfl
    gcc $^ -o $@
count_words.o: count_words.c counter.h
    gcc $(CPPFLAGS) -c $< -o $@
counter.o: counter.c counter.h lexer.h
    gcc $(CPPFLAGS) -c $< -o $@

lexer.o: lexer.c lexer.h
    gcc $(CPPFLAGS) -c $< -o $@

lexer.c: lexer.l
    flex -t $< > $@
13.CHAPTER2
13.1 Explicit rules:目标文件和依赖文件明确指定。
Pattern rules :利用通配符。
Implicit rules:既属于pattern rules 也属于suffix rules
13.2  规则rule对于同样的依赖,可以设置多个目标prequsite。注意规则rule的双向性。
13.3  注意makefile和shell对于通配符的执行点是不同的。makfile采取立即替换,而shell则是在执行时进行替换。
13.4  ch02-cw3 cw4编译时出现如下错误:

make: cc:命令未找到
make: ***

14.函数:

$(patsubst search-pattern,replace-pattern,text)

等价于:

$(variable:search=replace)

variable是指代text的变量。

(words text) 返回text中的单词数,text中的单词以whitespace分割。

$(word n,text) 返回第n个单词,如果n大于text中单词数目,函数返回empty.

$(firstword text)  返回第一个单词.

$(wordlist start,end,text)  返回start到end之间的单词.

比较复杂的应用:

uid_gid = $(wordlist 3, 4, \
            $(subst :, , \
              $(shell grep "^jacky:" /etc/passwd)))
uid:
    @echo $(uid_gid)

输出:

1000 1000


$(sort list)   对list中的单词进行排序。
$(shell command)   需要在subshell中执行。command命令的输出被读取作为shell函数的返回值。

以下函数用于判断字符串中有无重复的

has-duplicates = $(filter \
                   $(words $1) , \
                   $(words $(sort $1)))
all:
    @echo $(call has-duplicates, word dd dd ddddo)


15. chapter05 第五章:

15.1 命令是一行shell脚本,make提取出每一行把它发给subshell去执行,

这一过程需要fork/exec,如果采用一些特殊的标识符,那么可以减少fork和exec.如果make发现了一些可以优化的因素(没有wildcard characters and i/o redirection),那么可以不用产生subshell.

在make的目标下一行,如果起始字符是tab键,那么这一行被认为是shell命令,除非前一行以"\"结尾.

15.2当make启动时,除了SHELL环境变量,其他的环境变量和系统的相同。

15.3 对于使用for循环的makefile,要注意使用';'和'\'来使语句一起执行。还有&&的使用。需要注意。

15.4 利用@可以避免打印命令本身,更简洁吧。

16 chapter06

16.1 如果我们添加了头文件注释,并且我们不想再编译相关的源文件,可以执行  make --touch命令。.PHONY文件不受--touch影响。

16.2 make通过MAKEFLAGS将参数传递给submake.

16.3 关于

%.d: %.c
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -M $< | \
    $(SED) 's,\($(notdir $*)\.o\) *:,$(dir $@)\1 $@: ,' > $@.tmp
    $(MV) $@.tmp $@
实际上最难懂的就是sed的操作了,sed操作的目的是什么?


jacky@JACKY:~/mydoc/srcForLearn/examples/ch06-non-recursive$ cc  -I lib -I include  -M lib/db/playlist.c
playlist.o: lib/db/playlist.c /usr/include/stdio.h \
  /usr/include/features.h /usr/include/sys/cdefs.h \
  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
  /usr/include/gnu/stubs-32.h \
  /usr/lib/gcc/i486-linux-gnu/4.3.3/include/stddef.h \
  /usr/include/bits/types.h /usr/include/bits/typesizes.h \
  /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
  /usr/lib/gcc/i486-linux-gnu/4.3.3/include/stdarg.h \
  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h


playerlist.d文件

lib/db/playlist.o lib/db/playlist.d: lib/db/playlist.c /usr/include/stdio.h \
  /usr/include/features.h /usr/include/sys/cdefs.h \
  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
  /usr/include/gnu/stubs-32.h \
  /usr/lib/gcc/i486-linux-gnu/4.3.3/include/stddef.h \
  /usr/include/bits/types.h /usr/include/bits/typesizes.h \
  /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
  /usr/lib/gcc/i486-linux-gnu/4.3.3/include/stdarg.h \
  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h


读《跟我一起写 Makefile》摘录:
.PHONY : clean
clean :
-rm edit $(objects) 
在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。

引用其它的 Makefile
include
!!!如果你想让make不理那些无法读取的
文件,而继续执行,你可以在include前加一个减号“-”。如:
-include ;
其表示,无论include过程中出现什么错误,都不要报错继续执行。和其它版本make兼容的相关命令是sinclude,其作用和这一个是一样的。

如果你要让通配符在变量中展开,也就是让objects的值是所有[.o]的文件名的集合,那么,你可以这样:
objects := $(wildcard *.o)  ,而不是:
objects = *.o
关于伪目标,文中提到可以同时编译多个可执行程序,可以利用。
多目标好用否?
1.5.7静态模式:
: :

还可以利用filter函数:

$(filter %.o,$(files)): %.o: %.c
   $(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
   emacs -f batch-byte-compile $<

我认为也是用到了多目标吧。

阅读(2139) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~