• Makefile目标,伪目标,头文件自动依赖


    目标

    即我们最终要生成的文件,make默认生成第一个目标,注意 makefile中tab和空格不是一回事,规则使用tab缩进,编辑器不要设置诸如“将tab替换为空格之类的选项”,目标的结构如下

    目标:依赖1 依赖2
    <TAB>生成目标的规则
    

    伪目标

    无论如何也要执行的目标,需要使用.PHONY:标识

    .PHONY:clean
    clean:
        rm -f *.o
    

    常见伪目标

    all 是所有目标的伪目标,功能是编译所有目标
    clean 删除所有被make创建的文件
    install 安装已经编译好的程序,其实就是把目标执行文件拷贝到指定目标中
    print 这个伪目标的功能是列出改变过的源文件
    tar 把源程序打包备份,就是一个tar文件
    dist 创建一个压缩文件,一般吧tar文件压缩成Z文件或gz文件
    TAGS 更新所有目标,以备完整的重编译使用
    check/test 测试makefile流程

    例子

    circle:main.o circle.o
        cc main.o circle.o -o circle
    main.o:main.c
        cc -c main.c
    circle.o :circle.c
        cc -c circle.c
    clean:
        rm *.o *.h circle
    

    自动依赖头文件

    makefile是根据依赖关系,时间戳和生成规则来判断哪些文件需要更新,但是我们通常写的生成规则并不会包含头文件,依赖关系也不会,这样如果我们更新了头文件,makefile也不会发现,也就不会更新相应的文件,同时,考虑到头文件包含关系的复杂性,我们在写依赖关系之前把所有的头文件理清楚再写进去也不现实,一个好的方式是利用$gcc -M$gcc -MM功能,这两个功能能自动的分析头文件的依赖关系,前者分析目标文件的所有头文件依赖关系,后者分析和我们自定义文件的依赖关系:

    $gcc -M hello.c
    hello.o: hello.c /usr/include/stdio.h /usr/include/features.h 
     /usr/include/i386-linux-gnu/bits/predefs.h 
     /usr/include/i386-linux-gnu/sys/cdefs.h 
     /usr/include/i386-linux-gnu/bits/wordsize.h 
     /usr/include/i386-linux-gnu/gnu/stubs.h 
     /usr/include/i386-linux-gnu/gnu/stubs-32.h 
     /usr/lib/gcc/i686-linux-gnu/4.6/include/stddef.h 
     /usr/include/i386-linux-gnu/bits/types.h 
     /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h 
     /usr/include/_G_config.h /usr/include/wchar.h 
     /usr/lib/gcc/i686-linux-gnu/4.6/include/stdarg.h 
     /usr/include/i386-linux-gnu/bits/stdio_lim.h 
     /usr/include/i386-linux-gnu/bits/sys_errlist.h hello.h
    $gcc -MM hello.c
    hello.o: hello.c hello.h
    

    可以看到,他们的输出的格式刚好就是我们写的依赖关系的格式,所以我们可以综合利用伪目标,重定向,include关键字实现对头文件更新的自动检查

    .PHONY:all
    all:hello dependency
    hello:hello.o
    	gcc hello.o -o hello
    hello.o:hello.c
    	gcc -c hello.c -o hello.o
    dependency:headers
    headers:
    	gcc -M hello.c > headers
    include headers
    
    
    .PHONY:clean
    
    clean:
    	rm -rf hello *.o
    

    分析:make缺省目标会自动以第一个目标为目标,首先依次检查hello<-hello.o<-hello.c发现没有文件被更新,dependency并不是一个文件,也没有时间戳,所以也没有被更新,但是dependency每次都会执行刷新headers文件,我们又include了headers,所以一旦headers里面写的头文件有更新,就会通过hello.o<-xxx.h来找到更新关系,进而更新hello.o并进一步更新hello。至此实现了对头文件的自动依赖问题的解决。
    执行效果:

    //程序就是输出这个N值
    #ifndef __HELLO_H__
    #define __HELLO_H__
    
    #define N 121220;
    
    #endif
    
    $./hello 
    num:121220
    $vi hello.h            #修改头文件中N的值为5
    $make                  #果然重新编译了  
    gcc -c hello.c -o hello.o
    gcc hello.o -o hello
    gcc -M hello.c > headers
    $./hello         
    num:5
    
  • 相关阅读:
    阶梯博弈
    hihoCoder #1199 : Tower Defense Game ——(树型dp)
    2016 China-Final-F题 ——(SA+二分)
    ACM之路(20)—— Splay初探
    2016 ICPC China-Final 现场赛总结
    【Interleaving String】cpp
    【Best Time to Buy and Sell Stock III 】cpp
    【Maximal Rectangle】cpp
    【palindrome partitioning II】cpp
    【Maximum Subarray 】cpp
  • 原文地址:https://www.cnblogs.com/xiaojiang1025/p/5955065.html
Copyright © 2020-2023  润新知