makefile的语法规则 通用模版

没有makefile可以直接make

如果文件是a.c可以直接make a   生成 a  可执行文件



@符号是不显示执行的命令信息
test:
        @echo "liuwei"

不加@符号
echo "liuwei"
liuwei

加上显示
        liuwei   

-遇到错误也往下执行命令
test:
        -rm aaa;
        @echo "liuwei"
目录下没有aaa文件
如果没有-,结果就不会输出  liuwei
加上-, 虽然报错,也输出  liuwei


make  clean:
make clean  一般都把除了源文件外的文件删除
如果makefile同级目录有clean文件,就会报错

解决之道:
    .PHONY:clean  在原来的基础上加上这句话即可解决
  1. .PHONY:clean
  2. clean:
  3. make -C src clean
  4. rm -rf app


make  -C 的使用:
  1. libcalc.a:
  2. make -C src libcalc.a
  3. gcc main.c -Iinclude lib/libcalc.a -o app
  4. libcalc.so:
  5. make -C src libcalc.so
  6. gcc main.c -Iinclude -L./lib -lcalc -o app
  7. .PHONY:clean
  8. clean:
  9. make -C src clean
  10. rm -rf app
make后面的  C  选项 表示 进入到 src  的  文件夹内  执行  src 目录里的 指令



Makefile 高级运用 :

通过四个 .c文件 和 makefile  生成一个静态库


makefile里写法如下:
test:add.c sub.c dive.c mul.c  
        gcc -c $^            

执行如下:
liuwei@liuwei-virtual-machine:~/calc/src$ make test
gcc -c add.c sub.c dive.c mul.c


test : add.c sub.c dive.c mul.c     

test代表目标            后面的四个文件代表这个目标的条件(依赖)

$@  代表目标

$^   代表所有条件

$<  代表第一个条件



%.o : %.c   系统的默认行为         // 是指从.c转换成.o,%是通配符,名字需要一样
  1. test.a : add.o sub.o dive.o mul.o          //直接通过.o文件生成静态库
  2. ar rcs $@ $^ //注意 %@表示目标文件 %^表示所有的条件(依赖)

生成test.a这个库文件,需要后面四个.o文件
不过现在目录里没有四个o文件,系统只能找到四个c文件
这时候就会想办法从.c生成.o
makefile默认有这种机制生成,
最后再创建静态库





如何查看系统默认这种行为:
make -p  > file
通过查看file文件可以得到

然后

可以看到


如何改变这种默认行为:

在makefile里增加
%.o:%.c
        gcc -c $<
  1. test.a:add.o sub.o dive.o mul.o
  2. ar rcs $@ $^
  3. %.o:%.c
  4. gcc -c $<


这时候系统从 .c文件到 .o文件 就会 走 这个流程
于是 cc全部 变成了gcc



makefile变量信息:

在makefile里可以定义变量,输出的时候需要 $(变量名)
  1. NAME = liuwei
  2. test:
  3. echo $(NAME)




makefile里有几个默认的参数变量
通过下面图片,可以得出
   

#编译器参数
CFLAGS    可以修改成   -g  -Wall

#预处理参数         
CPPFLAGS   可以修改成  -I../include    -DDEBUG

#加载器参数     可以修改成 -L../lib
LDFLAGS     


makefile 通用模版:
  1. obj = add.o sub.o mul.o dive.o
  2. target = libcalc.a
  3. $(target):$(obj)        //变量在上面生成    
  4. ar rcs $@ $^    //现在需要.o的时候 通过.c文件走下面的 gcc
  5. %.o:%.c
  6. gcc -c $<




makefile的函数使用:

$(wildcard *.c)  :                              //寻找当前目录下的所有 .c 文件
src = $(wildcard *.c)            
test:
        @echo $(src)

[liuwei@ ~/calc/src]$>make test
add.c dive.c mul.c sub.c



$(patsubst %.c , %.o , %(src)) :            //把src目标的所有 .c文件 置换成 .o文件
src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))        
test:
        @echo $(src)
        @echo $(obj)

[liuwei@ ~/calc/src]$>make test
add.c dive.c mul.c sub.c
add.o dive.o mul.o sub.o


于是 通用模版 可以 再次变化成 以下形式
  1. src = $(wildcard *.c)
  2. obj = $(patsubst %.c,%.o,$(src))
  3. target = libcalc.a
  4. $(target):$(obj)
  5. ar rcs $@ $^
  6. %.o:%.c
  7. gcc -c $<
  8. clean:
  9. rm -rf *.o
  10. rm -rf libcalc.a
  11. rm -rf ../lib/libcalc.a
  12. rm -rf ../lib/libcalc.so




练习最终版本:

生成静态库的makefile版本:
  1. pos = ../lib
  2. src = $(wildcard *.c)
  3. obj = $(patsubst %.c,%.o,$(src))
  4. target = libcalc.a
  5. $(target):$(obj)
  6. ar rcs $@ $^
  7. mv $@ $(pos)
  8. %.o:%.c
  9. gcc -c $<
  10. clean:
  11. rm -rf $(obj)
  12. rm -rf $(pos)/$(target)

生成动态库的makefile版本:   
  1. src = $(wildcard *.c)
  2. obj = $(patsubst %.c,%.o,$(src))
  3. target = libcalc.so
  4. pos = ../lib
  5. $(target):$(obj)
  6. gcc -shared -W -o $@ $(obj) // 此时 $obj 为 四个.o文件 但是目录缺少.o文件,于是走下面的 %.o:%.c
  7. mv $@ $(pos)
  8. %.o:%.c
  9. gcc -fPIC -c $<
  10. clean:
  11. rm -rf *.o
  12. rm -rf $(pos)/$(target)






posted @ 2014-09-03 23:11  我爱背单词  阅读(294)  评论(0编辑  收藏  举报