Makefile笔记

objects := $(wildcard *.o)
all: $(objects)
$(objects): %.o: %.c
 $(CC) -c $(CFLAGS) $< -o $@

    %.o : %.c
            $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

.PHONY : clean
clean :
 rm $(objects) # 或-rm或@rm
----------------------------------------------------------------
$@
    表示规则中的目标文件集。

$%
    仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。

$<
    依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。

$?
    所有比目标新的依赖目标的集合。以空格分隔。

当你希望只对更新过的依赖文件进行操作时,"$?"在显式规则中很有用,例如,假设有一个函数库文件叫"lib",其由其它几个object文件更新。那么把object文件打包的比较有效率的Makefile规则是:

    lib : foo.o bar.o lose.o win.o
            ar r lib $?

$^
    所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
 
$+
    这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
----------------------------------------------------------------
sources = foo.c bar.c
sinclude $(sources:.c=.d)
# 变量$(sources)所有[.c]的字串都替换成[.d]
%.d: %.c
 @set -e; rm -f $@; /
 $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; /
 sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; /
 rm -f $@.$$$$
# main.o : main.c defs.h --> main.o main.d : main.c defs.h
----------------------------------------------------------------
make -n 或 --just-print
make -nw

   The `-W' flag provides two features:

   * If you also use the `-n' or `-q' flag, you can see what `make'
     would do if you were to modify some files.

   * Without the `-n' or `-q' flag, when `make' is actually executing
     commands, the `-W' flag can direct `make' to act as if some files
     had been modified, without actually modifying the files.

   使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的

make -t 或 --touch
make -q 或 --question
make -s 或 --silent
make -C <dir> 或 --directory=<dir> 指定读取makefile的目录
make -i 或 --ignore-errors
make -k 或 --keep-going 及 .IGNORE目标
----------------------------------------------------------------
        exec:
                cd /home/hchen
                pwd

        exec:
                cd /home/hchen; pwd
----------------------------------------------------------------
     IMMEDIATE = DEFERRED
     IMMEDIATE ?= DEFERRED
     # 如果没定义
     IMMEDIATE := IMMEDIATE
     # 只能使用已定义好的变量
     IMMEDIATE += DEFERRED or IMMEDIATE

   For the append operator, `+=', the right-hand side is considered
immediate if the variable was previously set as a simple variable
(`:='), and deferred otherwise.

     define IMMEDIATE
       DEFERRED
     endef
---------------------------------------------------------------
    ifeq (0,${MAKELEVEL})
     cur-dir   := $(shell pwd)
     whoami    := $(shell whoami)
     host-type := $(shell arch)
     MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
    endif
---------------------------------------------------------------
    nullstring :=
    space := $(nullstring) # end of the line
---------------------------------------------------------------
    libs_for_gcc = -lgnu
    normal_libs =

    ifeq ($(CC),gcc)
      libs=$(libs_for_gcc)
    else
      libs=$(normal_libs)
    endif

    foo: $(objects)
            $(CC) -o foo $(objects) $(libs)
---------------------------------------------------------------
    comma:= ,
    empty:=
    space:= $(empty) $(empty)
    foo:= a b c
    bar:= $(subst $(space),$(comma),$(foo))
    # 把$(foo)中的空格替换成逗号,所以$(bar)的值是“a,b,c”
---------------------------------------------------------------
$(subst <from>,<to>,<text>)
$(patsubst <pattern>,<replacement>,<text>)
 $(patsubst %.c,%.o,x.c.c bar.c)
$(strip <string>)
 去掉<string>字串中开头和结尾的空字符
 $(strip a b c )从“a b c ”得到“a b c”
---------------------------------------------------------------
$(dir <names...>) 

    名称:取目录函数——dir。
    功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。
    返回:返回文件名序列<names>的目录部分。
    示例: $(dir src/foo.c hacks)返回值是“src/ ./”。

$(notdir <names...>) 

    名称:取文件函数——notdir。
    功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“/”)之后的部分。
    返回:返回文件名序列<names>的非目录部分。
    示例: $(notdir src/foo.c hacks)返回值是“foo.c hacks”。
 
$(suffix <names...>) 
    
    名称:取后缀函数——suffix。
    功能:从文件名序列<names>中取出各个文件名的后缀。
    返回:返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
    示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是“.c .c”。

$(basename <names...>)

    名称:取前缀函数——basename。
    功能:从文件名序列<names>中取出各个文件名的前缀部分。
    返回:返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
    示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar hacks”。

$(addsuffix <suffix>,<names...>) 

    名称:加后缀函数——addsuffix。
    功能:把后缀<suffix>加到<names>中的每个单词后面。
    返回:返回加过后缀的文件名序列。
    示例:$(addsuffix .c,foo bar)返回值是“foo.c bar.c”。

$(addprefix <prefix>,<names...>) 

    名称:加前缀函数——addprefix。
    功能:把前缀<prefix>加到<names>中的每个单词后面。
    返回:返回加过前缀的文件名序列。
    示例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。

$(join <list1>,<list2>)

    名称:连接函数——join。
    功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中。
    返回:返回连接过后的字符串。
    示例:$(join aaa bbb , 111 222 333)返回值是“aaa111 bbb222 333”。
---------------------------------------------------------------
$(foreach <var>,<list>,<text>)
    names := a b c d
    files := $(foreach n,$(names),$(n).o)
    # $(files)的值是“a.o b.o c.o d.o”。
---------------------------------------------------------------
    reverse =  $(2) $(1)

    foo = $(call reverse,a,b)
---------------------------------------------------------------
    sources = foo.c bar.c
    ifneq ( $(MAKECMDGOALS),clean)
    include $(sources:.c=.d)
    endif
只要我们输入的命令不是“make clean”,那么makefile会自动包含“foo.d”和“bar.d”这两个makefile。
---------------------------------------------------------------
 There are two reasons to use a phony target: to avoid a
conflict with a file of the same name, and to improve performance.

    .PHONY: all
    all: prog1 prog2 prog3 prog4
---------------------------------------------------------------
http://www.chinaunix.net/jh/23/408225.html 及 make manual摘录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值