现在的位置: 首页 > 综合 > 正文

make和makfile的介绍

2017年06月15日 ⁄ 综合 ⁄ 共 3070字 ⁄ 字号 评论关闭

make工具和Makefile文件

无论是在Linux还是在UNIX环境中,make都是一个非常重要的编译工具。无论是自己进行项目开发还是安装应用软件,都需要使用make工具。利用make工具,可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序而言,使用make工具和makefile文件就可以清晰地理顺各个源文件之间的关系。而且如此多的源文件,如果每次都要输入gcc命令进行编译的话,对程序员来说是很难忍受的。make工具可以自动完成编译工作,并且只对程序员在上次编译后修改过的部分进行编译。因此,有效地利用make工具可以大大提高项目开发的效率.

makefile文件名及使用

makefile文件的名一般是makefileMakefile

使用方法:make

makfile文件名也可以任意取,只需要在使用时加上参数-f即可,假如有一个makefile文件为anyfile,那么使用方法为:make-f anyfile

makefile文件的基本语法

 

  • 注释:"#"开始
  • Makefile规则:

    target...:prerequisites

    (tab)command
    目标:依赖
    执行命令

    target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。

    ①prerequisites就是要生成那个target所需要的文件或是目标。
    ②command也就是make需要执行的命令。(任意的Shell命令)
    这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行(command一定要以Tab键开始,否者编译器无法识别command),减少重复编译,提高了其软件工程管理效率。
  • 变量:和C语言中的宏功能相同
    变量的定义:objects= main.o fscanf_to_scanf.o
    嘿嘿,以后就可以用$(objects)来代替main.o和fscanf_to_scanf.o了
  • 目录搜索:VPATH和vpath
    在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。
    Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

    VPATH= src:../headers

    上面的的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔。
    另一个设置文件搜索路径的方法是使用make的“vpath”关键字(注意,它是全小写的),这不是变量,这是一个make的关键字,这和上面提到的那个VPATH变量很类似,但是它更为灵活。它可以指定不同的文件在不同的搜索目录中(详细请自己查找)。
  • 三个常用自动变量:Makefile 有三个非常有用的变量:$@,$^,$<。
    main:main.o fscanf_to_scanf.o

    其意义为:

    $@:目标文件-->main
    $^:所有的依赖文件-->main.o fscanf_to_scanf.o
    $<:第一个依赖文件-->main.o
    当文件中定义了VAPTH,使用这三个自动变量将自动包含VPATH中所定义的路径,目录搜索的结果并不改变规则中的命令:命令按原样被执行。因此,必须写出与目录搜索相适应的命令。这可以通过使用’$^’这样的自动变量来完成。’$^’表示规则中的所有依赖文件,包含它们所在的目录名(参见目录搜索)

makefile实例

有一个程序,包含三个文件main.c、fscanf_to_scanf.c、fscanf_to_scanf.h,fscanf_to_scanf.c在目录bb下,fscanf_to_scanf.h在目录cc下,main.c和makefile文件在同一目录下,因此,我写下了一下三个makefile文件,可以一一对应以上所讲语法:

 

#makefile1
#这就是注释行,以"#"开始
main : main.o fscanf_to_scanf.o 
    gcc -o main main.o fscanf_to_scanf.o 
main.o : main.c cc/fscanf_to_scanf.h 
    gcc -c main.c cc/fscanf_to_scanf.h -Icc 
fscanf_to_scanf.o : bb/fscanf_to_scanf.c cc/fscanf_to_scanf.h 
    gcc -c bb/fscanf_to_scanf.c -Icc 
clean : clean_o clean_r 
clean_o: 
    rm -rfv *.o 
clean_r:
    rm -rfv *main

 

 

#makefile2 
#各种变量的定义
objectc = bb/fscanf_to_scanf.c
objecth = cc/fscanf_to_scanf.h
object = $(objectc) $(objecth)
objects =main.o fscanf_to_scanf.o
#main : main.o fscanf_to_scanf.o
main : $(objects)
    gcc -o main main.o fscanf_to_scanf.o
main.o : main.c $(objecth)
    gcc -c main.c -Icc
fscanf_to_scanf.o : $(object)
    gcc -c $(objectc) -Icc
clean : clean_o clean_r
.PHONY : clean
clean_o:
    rm -rfv *.o
clean_r:
    rm -rfv main

 

 

#makefiel3 
#使用了VPATH,make会自动在VPATH指定路径下寻找相关文件
VPATH = .:./bb:./cc
object = main.o fscanf_to_scanf.o

main : $(object)
    gcc -o $@ $^
#下面这个依赖文件就不需要添加路径名
main.o : main.c fscanf_to_scanf.h
    gcc -c $< -Icc
#下面这个$<就相当于bb/fscanf_to_scanf.c
fscanf_to_scanf.o : fscanf_to_scanf.c fscanf_to_scanf.h
    gcc -c bb/fscanf_to_scanf.c -I cc
clean : clean_o clean_r
.PHONY : clean
clean_o:
    rm -rfv *.o
clean_r:
    rm -rfv main

 

附加说明

makefile文件还有很多规则,但是常用的就这些,像伪目标,就是上面几个makefile文件中

.PHONY:clean

 

这个声明clean就是伪目标。.PHONY 来显示的指名一个目标是伪目标,有两个作用一个是改善性能,另外一个是来避免冲突
还有关于命令中-I的用法,这是属于gcc命令里面的参数,目的是为了包含.h文件所在路径

抱歉!评论已关闭.