zoukankan      html  css  js  c++  java
  • Makefile 的使用

    Makefile里有什么?

    Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

    1. 显式规则。显式规则说明了,如何生成一个或多个目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
    2. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写Makefile,这是由make所支持的。
    3. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
    4. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
    5. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜杠进行转义,如:“#”。

    最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。 

    make的工作方式

    GNU的make工作时的执行步骤如下:

    1. 读入所有的Makefile。
    2. 读入被include的其它Makefile。
    3. 初始化文件中的变量。
    4. 推导隐晦规则,并分析所有规则。
    5. 为所有的目标文件创建依赖关系链。
    6. 根据依赖关系,决定哪些目标要重新生成。
    7. 执行生成命令。

    1-5步为第一个阶段,6-7为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。 

    Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.

    3种格式的shell命令区别如下:

    • 不用前缀 :: 输出执行的命令以及命令执行的结果, 出错的话停止执行
    • 前缀 @   :: 只输出命令执行的结果, 出错的话停止执行
    • 前缀 -   :: 命令执行有错的话, 忽略错误, 继续执行

    例子第一篇:

    OBJS = ./persion.o
    #OBJS是生成目标文件的依赖 all : persion   @echo
    "version 03" persion : $(OBJS)   g++ -o $@ $^
    #根据依赖生成目标文件persion;$(OBJS)的作用是取出变量值;变量$@指代目标文件;变量$^指代所有依赖文件;$<指代第一个依赖文件
    ./%.o : ./%.cpp   g++ -o $@ -c $^ #利用通配规则生成.o文件

    #伪目标clean和install .PHONY : clean .PHONY :
    install clean:   rm -rf ./persion ./*.o install:   tar -zcvf persion.tar.gz ./persion   @echo "make tar sucess"

    第二篇:

    srcs = $(wildcard ./src/*.cpp)
    #取srcs目录下所有.cpp文件 objs = $(patsubst %.cpp,%.o,$(srcs)) #将srcs中的所有.cpp文件替换为.o文件 all:./obj/hello_world ./obj/hello_world:$(objs)   g++ $^ -o $@ $(objs):%.o : %.cpp   g++ -c $^ -o $@ -I ./inc do:   @cp ./src/*.o ./obj   @rm ./src/*.o .PHONY : clean clean:   @rm -rf ./obj/*.o ./obj/hello_world

    1、makefile里的函数

    makefile里的函数使用,和取变量的值类似,是以一个‘$’开始,然后是一个括号里面是函数名和需要的参数列表,多个变量用逗号隔开,像这样

    return = $(functionname  arg1,arg2,arg3...)。

    可能这里的'$'更像是从某个地址取值类似的操作。

    2、 wildcard

    使用:SRC = $(wildcard *.c ./foo/*.c) 

    搜索当前目录及./foo/下所有以.c结尾的文件,生成一个以空格间隔的文件名列表,并赋值给SRC.当前目录文件只有文件名,子目录下的文件名包含路径信息,比如./foor/bar.c。

    3、notdir

    使用:SRC = $(notdir wildcard)

    去除所有的目录信息,SRC里的文件名列表将只有文件名。

    4、patsubst

    使用:OBJ = $(patsubst %.c %.o $(SRC)) 

    patsubst是patten substitude的缩写,匹配替代的意思。这句是在SRC中找到所有.c 结尾的文件,然后把所有的.c换成.o。

  • 相关阅读:
    Directory文档目录操作
    文件序列化和反序列化
    COOKIE
    转载深入ASP.NET MVC之二:路由模块如何工作
    Running 32Bit RDP on 64 Bit Windows OS
    MS CRM Isv Web.config设置
    QualifyLead PlugIn(转)
    MS CRM帮助访问不正确,
    (转)CrmTrace encountered an error. Additional Info:Error in GetFileName MS CRM
    MS CRM 2011储存电子邮件凭证
  • 原文地址:https://www.cnblogs.com/nanqiang/p/8394919.html
Copyright © 2011-2022 走看看