0
点赞
收藏
分享

微信扫一扫

make脚本


Linux系统专门提供了一个make命令来自动维护目标文件,与手工编译和连接相比,make命令的优点在于他只更新修改过的文件(在Linux中,一个文件被创建或更新后有一个最后修改时间,make命令就是通过这个最后修改时间来判断此文件是否被修改),而对没修改的文件则置之不理,并且make命令不会漏掉一个需要更新的文件。

程序员将这些依赖关系写入一个叫makefile的文件中,make命令当就知道这些依赖关系。




Linux中项目代码文件众多的时候,make工具可以 组织项目。 可以把命令行封装到文件。

对比:Windows里的那种文件的格式是 .bat
项目组织脚本makefile,这个脚本有专门解释工具make 
make脚本语法。
    1、make与make脚本关系
       make脚本可以是任意的名字。推荐命名: Makefile 或 makefile
      如果名字不是Makefile则需要使用 -f
        make -f  脚本文件。
      如果文件名是Makefile ,则 直接make后,系统会自动搜索出该脚本文件   
    2、make脚本语法
         1)make脚本都是由目标(TARGET)构成的。     //一个目标里可以有多个指令,支持换行
                一个目标就是编译任务(TASK)

目标语法:
         目标名:完成编译目标依赖的文件(其他目标) 或 没有文件也可以;
         Tab键编译的指令    //注意: 必须是Tab键,而且不能空格

注意:    @这个符号是防止 命令行回显的。

      使用make执行 make脚本的时候,默认每个任务的指令会显示出来。
      如果不显示,就在指令前加个@

  3、make脚本可以有多个目标
       make默认执行第一个目标
       如果想执行指定的目标:make 目标名
    4、目标之间的关系 ,或目标与文件的关系

      但目标不是文件,称为伪文件。
      伪目标声明的语法:

       .PHONY:伪目标名
       伪目标名:
         指令
 

  make的目标的规则:           1、伪目标没有任何规则
           2、文件目标
              检测目标依赖的文件(目标)与目标文件的新旧。
              目标文件比目标依赖文件新,make不工作。
     补充:#注释
     应用经验:
        建议把每个阶段编译的结果文件作为目标。
        这样目标就有执行依赖关系。     //这个执行依赖关系,make工具就会自动调用
        其中的* . o目标自动生成目标
        依赖目标使用空格分隔!

总结:

目标分为:
  (1)目标文件,用来比较文件的日期,根据新旧判定是否调用依赖的目标。
  (2) 伪目标,作为依赖,则会被永远执行。不会去比较文件的新旧。

  (3)依赖目标执行的条件:目标与依赖目标的新旧比较。
       目标新:不调用;      目标旧 : 调用

 

5、为了方便,在make脚本中可以定义变量。 
     变量名=值  
     $(变量名)

 

常用的目标如下:   include
   clean
   install
   all   //若是有多个项目,就用他。 all:demo demo1

 

makefile脚本案例1:





    1. SOURCES=demo4.c  
    2. LIB=libfun.so  
    3. demo4:$(SOURCE) $(LIB)  
    4.     gcc demo4.c -lfun -L. -odemo4  
    5. libfun.so:fun.c  
    6.     gcc -shared -olibfun.so fun.c  
    7. run:demo4 huan  
    8.     demo4  
    9.   
    10. .PHONY:huan  
    11. huan:  
    12.     export LD_LIBRARY_PATH=.




    makefile脚本案例2:



    1. SOURCES=main.cpp frmlogin.cpp netctapp.cpp frmmain.cpp frmadminadd.cpp  
    2. HEADERS=frmlogin.h netctapp.h frmmain.h frmadminadd.h  
    3. netct:$(SOURCES)  $(HEADERS)  
    4.     @g++  $(SOURCES) libqcurses.so -o netct -lcurses  
    5. clean:  
    6.     @rm -f netct



    shell 脚本执行方式(source ./*.sh, . ./*.sh, ./*.sh)的区别


    结论一: ./*.sh的执行方式等价于sh ./*.sh或者bash ./*.sh,此三种执行脚本的方式都是重新启动一个子shell,在子shell中执行此脚本。

    结论二: .source ./*.sh和 . ./*.sh的执行方式是等价的,即两种执行方式都是在当前shell进程中执行此脚本,而不是重新启动一个shell 而在子shell进程中执行此脚本

    验证依据:没有被export导出的变量(即非环境变量)是不能被子shell继承的

    验证结果:





      1. [root@localhost ~]#name=du       //定义一般变量    
      2. [root@localhost ~]# echo ${name}    
      3. du    
      4. [root@localhost ~]# cat test.sh      //验证脚本,实例化标题中的./*.sh    
      5. #!/bin/sh    
      6. echo ${name}    
      7. [root@localhost ~]# ls -l test.sh    //验证脚本可执行    
      8. -rwxr-xr-x 1 root root 23 Feb  6 11:09 test.sh    
      9. [root@localhost ~]# ./test.sh        //以下三个命令证明了结论一    
      10.     
      11. [root@localhost ~]# sh ./test.sh    
      12.     
      13. [root@localhost ~]# bash ./test.sh    
      14.     
      15. [root@localhost ~]# . ./test.sh     //以下两个命令证明了结论二    
      16. du    
      17. [root@localhost ~]# source ./test.sh    
      18. du    
      19. [root@localhost ~]#

       

      举报

      相关推荐

      0 条评论