zoukankan      html  css  js  c++  java
  • makefile

    make

    make : linux自带构建器, 构建规则在makefile中

    makefile文件的命名: makefile, Makefile

    makefile中的规则可分为三部分: 目标, 依赖, 命令
    格式:

    目标:依赖
    (tab缩进)命令
    

    工作原理:
      检测依赖是否存在, 向下搜索规则, 如果有规则是用来生成查找依赖的, 执行规则中的命令
      依赖存在: 判断是否需要更新, 原则是目标的时间要晚于依赖的时间, 否则需要更新
      内部会有些构建的规则

    变量定义:
      自定义变量: obj=a.o b.o c.o
      变量取值: aa=$(obj)
      makefile自带变量: 一般大写, 有些被赋值, 有些没有赋值
        CPPFLAGS: 头文件目录
        CC
      自动变量: 只能在命令中使用
        $@: 规则中的目标
        $<: 规则中的第一个依赖
        $^: 规则中的所有依赖

    命令参数:
      命令后加-f: 强制执行
      命令前加-: 忽略执行失败的命令, 继续向下执行其余的命令

    模式匹配:
      %.o:%.c

    函数: makefile中的所有的函数都有返回值
      查找指定目录下指定类型的文件: wildcard
        src = $(wildcard ./*.c)
      匹配替换: patsubst
        obj = $(patsubst %.c, %c, $(src)), 替换类型的文件, 要替换的类型的文件, 源文件

    声明伪目标: 不做文件更新与是否存在的检查.PHONY

    版本一

    缺点: 效率地, 修改一个文件, 所有文件都会被全部重新编译

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    app:main.c add.c div.c mul.c  sub.c
    	gcc main.c add.c div.c mul.c sub.c
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc main.c add.c div.c mul.c sub.c
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  a.out  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ ./a.out 
    sum = 26
    
    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    app:main.o add.o div.o mul.o sub.o
    	gcc main.o add.o div.o mul.o sub.o
    
    main.o:main.c
    	gcc main.c -c
    
    add.o:add.c
    	gcc add.c -c
    
    div.o:div.c
    	gcc div.c -c
    
    mul.o:mul.c
    	gcc mul.c -c
    
    sub.o:sub.c
    	gcc sub.c -c
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc main.c -c
    gcc add.c -c
    gcc div.c -c
    gcc mul.c -c
    gcc sub.c -c
    gcc main.o add.o div.o mul.o sub.o
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  a.out  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    zyb@server:~/dir_test/dir_test_1/src$ vim add.c  # 只修改一个文件
    zyb@server:~/dir_test/dir_test_1/src$ make		 # 只重新编译2个文件
    gcc add.c -c
    gcc main.o add.o div.o mul.o sub.o
    

    缺点: 后面的编译.o文件命令冗余

    版本二

    使用自定义变量和匹配替换

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    obj = main.o add.o div.o mul.o sub.o
    target = app
    $(target):$(obj)
    	gcc $(obj) -o $(target)
    
    %.o:%.c			# 当需要的.o文件没有时, 会进行替换
    	gcc -c $< -o $@
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c mul.c -o mul.o
    gcc -c sub.c -o sub.o
    gcc main.o add.o div.o mul.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    

    使用自动变量

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    obj = main.o add.o div.o mul.o sub.o
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    #	gcc $(obj) -o $(target)
    
    %.o:%.c
    	gcc -c $< -o $@
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c mul.c -o mul.o
    gcc -c sub.c -o sub.o
    gcc main.o add.o div.o mul.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    
    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    obj = main.o add.o div.o mul.o sub.o
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    #	gcc $(obj) -o $(target)
    zyb@server:~/dir_test/dir_test_1/src$ make
    cc    -c -o main.o main.c
    cc    -c -o add.o add.c
    cc    -c -o div.o div.c
    cc    -c -o mul.o mul.c
    cc    -c -o sub.o sub.c
    gcc main.o add.o div.o mul.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    

    版本三

    使用makefile函数查找与替换

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    src = $(wildcard ./*.c)
    obj = $(patsubst %.c, %.o, $(src))
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    #	gcc $(obj) -o $(target)
    
    %.o:%.c
    	gcc -c $< -o $@
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c mul.c -o mul.o
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c sub.c -o sub.o
    gcc mul.o main.o add.o div.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    

    版本四

    添加清除功能, 编写一个清理项目的规则

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    src = $(wildcard ./*.c)
    obj = $(patsubst %.c, %.o, $(src))
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    
    %.o:%.c
    	gcc -c $< -o $@
    
    hello:
    	echo "haha"
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c mul.c -o mul.o
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c sub.c -o sub.o
    gcc mul.o main.o add.o div.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    
    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    src = $(wildcard ./*.c)
    obj = $(patsubst %.c, %.o, $(src))
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    
    %.o:%.c
    	gcc -c $< -o $@
    
    clean:
    	rm $(obj) $(target)
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c mul.c -o mul.o
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c sub.c -o sub.o
    gcc mul.o main.o add.o div.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    zyb@server:~/dir_test/dir_test_1/src$ make clean
    rm  ./mul.o  ./add.o  ./main.o  ./div.o  ./sub.o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    
    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    src = $(wildcard ./*.c)
    obj = $(patsubst %.c, %.o, $(src))
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    
    %.o:%.c
    	gcc -c $< -o $@
    
    clean:
    	-mkdir /haha	# 忽略执行失败的命令, 继续向下执行
    	rm $(obj) $(target)
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c mul.c -o mul.o
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c sub.c -o sub.o
    gcc mul.o main.o add.o div.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ make clean
    mkdir /haha	# 忽略执行失败的命令, 继续向下执行
    mkdir: cannot create directory ‘/haha’: Permission denied
    makefile:11: recipe for target 'clean' failed
    make: [clean] Error 1 (ignored)
    rm  ./mul.o  ./add.o  ./main.o  ./div.o  ./sub.o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ touch clean
    zyb@server:~/dir_test/dir_test_1/src$ make clean
    make: 'clean' is up to date.
    

    版本五

    声明伪目标: 不被做文件更新, 是否存在的检查

    zyb@server:~/dir_test/dir_test_1/src$ cat makefile 
    src = $(wildcard ./*.c)
    obj = $(patsubst %.c, %.o, $(src))
    target = app
    $(target):$(obj)
    	gcc $^ -o $@
    
    %.o:%.c
    	gcc -c $< -o $@
    
    .PHONY:clean
    clean:
    	-mkdir /haha	# 忽略执行失败的命令, 继续向下执行
    	rm $(obj) $(target)
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  clean  div.c  head.h  main.c  makefile  mul.c  sub.c
    zyb@server:~/dir_test/dir_test_1/src$ make
    gcc -c mul.c -o mul.o
    gcc -c main.c -o main.o
    gcc -c add.c -o add.o
    gcc -c div.c -o div.o
    gcc -c sub.c -o sub.o
    gcc mul.o main.o add.o div.o sub.o -o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  add.o  app  clean  div.c  div.o  head.h  main.c  main.o  makefile  mul.c  mul.o  sub.c  sub.o
    zyb@server:~/dir_test/dir_test_1/src$ make clean
    mkdir /haha	# 忽略执行失败的命令, 继续向下执行
    mkdir: cannot create directory ‘/haha’: Permission denied
    makefile:12: recipe for target 'clean' failed
    make: [clean] Error 1 (ignored)
    rm  ./mul.o  ./add.o  ./main.o  ./div.o  ./sub.o app
    zyb@server:~/dir_test/dir_test_1/src$ ls
    add.c  clean  div.c  head.h  main.c  makefile  mul.c  sub.c
    

    进阶版

    zyb@server:~/dir_test/dir_test_1$ cat makefile 
    target=app
    CPPFLAGES=./include
    path=./src
    src=$(wildcard ./src/*.c)
    obj=$(patsubst %.c, %.o, $(src))
    
    $(target):$(obj)
    	gcc $^ -o $@
    
    %.o:%.c
    	gcc -c $< -I $(CPPFLAGES) -o $@
    zyb@server:~/dir_test/dir_test_1$ tree
    .
    ├── include
    │   └── head.h
    ├── lib
    ├── makefile
    └── src
        ├── add.c
        ├── div.c
        ├── main.c
        ├── mul.c
        └── sub.c
    
    3 directories, 7 files
    zyb@server:~/dir_test/dir_test_1$ make
    gcc -c src/mul.c -I ./include -o src/mul.o
    gcc -c src/main.c -I ./include -o src/main.o
    gcc -c src/add.c -I ./include -o src/add.o
    gcc -c src/div.c -I ./include -o src/div.o
    gcc -c src/sub.c -I ./include -o src/sub.o
    gcc src/mul.o src/main.o src/add.o src/div.o src/sub.o -o app
    zyb@server:~/dir_test/dir_test_1$ ls
    app  include  lib  makefile  src
    
  • 相关阅读:
    python学习笔记(excel中处理日期格式)
    python学习笔记(生成xml)
    python学习笔记(接口自动化框架 V1.0)
    python学习笔记(excel+unittest)
    刷题[RoarCTF 2019]Easy Java
    刷题[GKCTF2020]
    php bypass disable function
    刷题[MRCTF2020]Ezpop
    刷题[安恒DASCTF2020四月春季赛]Ez unserialize
    刷题[HFCTF2020]EasyLogin
  • 原文地址:https://www.cnblogs.com/hesper/p/10686996.html
Copyright © 2011-2022 走看看