• Makefile例子引入


    Makefile规则

    target ... :prerequisites...
                    command
    
    
    target就是一个目标文件,可以是object file,也可以是可以执行文件,也可以是一个标签
    
    
    prerequisites就是要生成那个target所需要的文件或者目标文件
    
    command就是make执行的命令的,任意的shell命令
    
    target依赖于prerequisites,其生成规则定义在command中。
    prerequisites中如果有一个规则以上的文件比target文件要新的话,command锁定义的命令就会被执行。

    例子1

    [root@typhoeus79 makefile]# ll
    total 16
    -rw-r--r-- 1 root root  69 Jun 20 11:27 head.c
    -rw-r--r-- 1 root root  45 Jun 20 11:27 head.h
    -rw-r--r-- 1 root root 150 Jun 20 11:30 Makefile
    -rw-r--r-- 1 root root  81 Jun 20 11:28 test.c
    ------------------------------------------------------------------------
    [root@typhoeus79 makefile]# more head.h 
    #include <stdio.h>
    
    void printword(char *s);
    [root@typhoeus79 makefile]# more head.c
    #include "head.h"
    
    void printword(char *s)
    {
        printf("%s
    ",s);
    }
    [root@typhoeus79 makefile]# more test.c 
    #include "head.h"
    
    int main()
    {
        char *s="Hello world!";
    
        printword(s);
    }
    [root@typhoeus79 makefile]# more Makefile 
    test: test.o head.o
            gcc -o test test.o head.o
    
    head.o: head.c head.h
            gcc -c head.c
    test.o: test.c
            gcc -c test.c
    
    clean:
            rm -rf test.o head.o test
    

      

    make是如何工作的

    在默认的情况下,只输入make命令,那么:

    1、make会找在当前目录下名字为makefile或者Makefile文件;

    2、如果找到,它会找第一个目标文件,例如上面例子中的test文件,并把这个作为最终的目标文件

    3、如果test目标文件不存在,或者edit所依赖的后面的.o文件的文件修改时间要比test文件新,那么就会执行后面所定义的命令生成test这个文件

    4、如果test所依赖的.o文件也不存在,那么make会在当前文件中找目标文件为.o的文件依赖性,如果找到再根据类似3生成.o文件

    整个make的依赖性,make会一层一层地区找文件的依赖关系,直到最终编译出第一个目标文件。

    makefile中使用变量

    PROJECT_NAME = "sqlparser"
    VERSION = "2.3.0"
    LDFLAGS = -lz -lm -lpthread -lcrypt -lcrypto
    CFLAGS = -fPIC -Wall -W -pipe -Wno-unused-parameter -g  -Wswitch -Wpointer-arith -Wredundant-decls -Wformat -D_GNU_SOURCE
    OBJS = sql_parse.o sql_lex.o 
            sql_select.o sql_insert.o sql_update.o sql_delete.o sql_replace.o sql_set.o sql_ddl.o sql_create_table.o sql_alter_table.o 
            sql_partition.o sql_define.o sql_show.o sql_util.o sql_transaction.o sql_dml.o sql_prepared.o
    TARGET = sample libsqlparse.a
    LIBDIR = ./output/
    CC = gcc
    

    声明一个变量objects,通过$(objects)的方式来使用这个变量,改良版的makefile如下:

    [root@typhoeus79 makefile]# more Makefile 
    OBJS = test.o head.o
    CC = gcc
    
    test: $(OBJS)
            $(CC) -o test test.o head.o
    
    head.o: head.c head.h
            gcc -c head.c
    test.o: test.c
            gcc -c test.c
    
    clean:
            rm -rf test.o head.o test
    [root@typhoeus79 makefile]# make clean
    rm -rf test.o head.o test
    [root@typhoeus79 makefile]# make
    gcc -c test.c
    gcc -c head.c
    gcc -o test test.o head.o
    

     make自动推导

    make可以自动推动文件以及文件依赖关系后面的命令

    只要make看到一个[.o]文件,会自动把[.c]文件加到依赖关系,并且对于的cc -c [.c]也会被推动出来

    对应上面的makefile继续被修改为

    [root@typhoeus79 makefile]# make clean
    rm -rf test.o head.o test
    [root@typhoeus79 makefile]# make
    gcc    -c -o test.o test.c
    gcc    -c -o head.o head.c
    gcc -o test test.o head.o
    [root@typhoeus79 makefile]# more Makefile 
    OBJS = test.o head.o
    CC = gcc
    
    test: $(OBJS)
            $(CC) -o test test.o head.o
    
    head.o: head.h
    
    clean:
            rm -rf test.o head.o test
    

     隐晦规则

    .PHONY: clean
    clean:
            rm -rf test.o head.o test
    

    .PHONY表示clean是个伪目标文件
    另类风格的makefile

    make可以自动推导命令,看到那堆[.o]和[.h]的依赖不爽,重复的[.h]是否可以收拢起来?

    [root@typhoeus79 makefile]# more Makefile 
    OBJS = test.o printInt.o printWord.o
    CC = gcc
    
    test: $(OBJS)
            $(CC) -o test $(OBJS)
    
    $(OBJS): printWord.h
    printWord.o:printInt.h
    
    .PHONY: clean
    clean:
            rm -rf $(OBJS) test
    [root@typhoeus79 makefile]# make
    gcc    -c -o test.o test.c
    gcc    -c -o printInt.o printInt.c
    gcc    -c -o printWord.o printWord.c
    gcc -o test test.o printInt.o printWord.o
    

     这种风格,使得makefile简单,但是文件依赖关系显得凌乱,依赖关系看不清楚,对于文件多,不合适。

    [root@typhoeus79 makefile]# more Makefile 
    OBJS = test.o printInt.o printWord.o
    CC = gcc
    
    test: $(OBJS)
            $(CC) -o test $(OBJS)
    
    test.o:printWord.h
    
    printWord.o:printInt.h
    
    .PHONY: clean
    clean:
            rm -rf $(OBJS) test
    [root@typhoeus79 makefile]# make
    gcc    -c -o test.o test.c
    gcc    -c -o printInt.o printInt.c
    gcc    -c -o printWord.o printWord.c
    gcc -o test test.o printInt.o printWord.o
    

     清空目标文件的规则

    每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,不仅便于重编译,也很利于保持文件的清洁。

    .PHONY: clean
    clean:
            rm -rf $(OBJS) test
    

    更稳健的方式,.PHONY意思clean是一个伪目标,在rm命令前面加一个小减号的意思,也许某些文件出现问题,但不要管,继续做后面的事情。

    clean规则不要放在文件的开头,不然,就会变成make的默认目标。

    不成文的规矩,clean从来都是放在文件的最后。

    错误的例子:

    .PHNOY: clean
            clean:
                    rm -rf printInt.o
    

     clean是目标对象,一定不能加[Tab]键,否则出错:

    [root@typhoeus79 makefile]# make -f testMakefile clean
    make: *** No rule to make target `clean'.  Stop.
    
  • 相关阅读:
    迪杰斯特拉算法简单分析
    华科机考:二叉排序树(改)
    华科机考:八进制
    华科机考:阶乘
    华科机考:找位置
    华科机考:回文字符串
    华科机考:a+b
    华科机考:N阶楼梯上楼
    华科机考:大整数排序
    iOS 适配iOS9
  • 原文地址:https://www.cnblogs.com/gsblog/p/3798991.html
Copyright © 2020-2023  润新知