zoukankan      html  css  js  c++  java
  • Makefile文件规则

    makefile文件由一组依赖关系和规则构成。每个依赖关系由一个目标(一般为可执行文件)和要创建这个目标所需依赖的一组源文件构成。而规则定义了目标的创建方式。

    依赖关系的写法是:目标名称+冒号+空格或制表符tab,最后是由空格或制表符隔开的文件列表,如:

    myapp: main.o b.o f.o

    main.o: main.c a.h

    b.o: b.c a.h b.h

    f.o: f.c b.h f.h

    make命令假设在makefile文件中的第一个目标myapp是想创建的目标文件,确定创建所需依赖的源文件,先检查有没有现成的文件,再看makefile文件中有没有说明如何创建该文件,如果都没有则将报告一个错误。这样找到目标文件那一条线上的所有文件。同时make命令能自行判断出创建所需文件的正确顺序。

    还可以定义伪目标如 all: myapp myall.1,就将创建myapp以及其帮助文件。

    规则:

    首先提一条可能有点奇怪的makefile语法,就是空格和tab是有区别的,规则所在的行必须以tab开头,用空格将导致make不能正常工作。这有历史上的原因。

    大多数规则都会包含一个简单的命令,该命令是可以在命令行窗口执行的。

    myapp: main.o b.o f.o  

      gcc -o myapp main.o b.o f.o

    main.o: main.c a.h  

      gcc -c main.c

    b.o: b.c a.h b.h  

      gcc -c b.c

    f.o: f.c b.h f.h  

      gcc -c f.c

    如果我们想通过make实现:清除make过程中产生的中间文件、安装目标至指定目录下等等任务,可以在Makefile文件末尾加如下:

    clean:  

      -rm main.o b.o.f.o

    install: myapp

        @if [ -d $(INSTDIR) ]; \   

        then \   

        cp myapp $(INSTDIR);\   

        chmod a+x $(INSTDIR)/myapp;\  (设置所有用户可执行)   

        chmod og-w $(INSTDIR)/myapp;\  (设置去除other用户和同组用户的可写权限)   

        echo "Installed in $(INSTDIR)";\  

      else \   

        echo "sorry, $(INSTDIR) does not exist";\  

      fi

    增加了2个新目标clean和install。

    "clean: "表示没有依赖关系定义,只定义了规则。rm前带减号-,可让make命令忽略rm命令的执行结果,即使rm出错(如删除对象不存在)也不会返回和显示error,make clean都会成功。

    install目标需要依赖myapp,因此必须先创建myapp。从myapp到install目标是通过一段shell脚本完成的。每行代码以反斜杠\结束,是使所有shell脚本命令在逻辑上处于同一行,作为一个整体传递给一个shell执行。同时以符号@开头可以使得make在执行这条规则前不会在stdout显示这些命令本身。

    这其中有些脚本执行的执行需要你先具有root权限。

    make命令最常用的3个选项是:

    -f <makefilename>: 指定进行make所需的makefile文件名。默认会自动查找匹配名为makefile的文件,如找不到则再找名为Makefile的文件。Makefile也是最多人采用的命名,因为它也会出现在所在目标文件列表首位。如:make -f Makefile123。

    -k 出现错误时仍然继续执行。该命令可以一次列出所有未成功编译的源文件。

    -n 让make命令在正式执行操作前输出将要执行的操作步骤。

    make命令的常用宏定义:

    $@ 当前目标文件名

    $< 当前所依赖的源文件的名称

    $* 当前所依赖的源文件的名称(不带后缀名)

    $? 当前目标所依赖的源文件列表中比当前目标文件还要新的文件

    同时常会看到下面2个特殊字符:

    -: 表示让make命令忽略所有错误。

    @: 告诉make指令在执行某命令前不在标准输出显示该命令。@结合echo很有用。

    内置规则

    以上都对创建目标文件的规则(每个操作步骤)都做出了精确定义。其实,make命令自带有大量的内置规则,这些内置规则可以极大简化makefile文件中的内容。可以将文件makefile中用于制作目标的规则去掉,而只需指定依赖关系。makefile文件将相对变得很简单,如以下相应部分:

    main.o: main.c a.h

    b.o: b.c a.h b.h

    f.o: f.c b.h f.h

    make使用.<old_suffix>.<new_suffix>来定义一条通用规则,可以从旧后缀名文件创建新后缀名文件。如:

    .cpp.o  

      $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<

    这里的$<表示具体使用时的依赖源文件(旧后缀名文件)的名称(带后缀名)。-xc++是告诉gcc编译器源文件是一个C++文件。

    make用于函数库管理的语法是lib(file.o),用于将file.o文件合并入lib.a文件中,其内置规则常见形式如下:

    .c.a:  

      $(CC) -c $(CFLAGS) $<  $(AR)

      $(ARFLAGS) $@ $*.o

    第一条规则是编译源文件生成目标文件;第二条规则中宏$(AR)和$(ARFLAGS)的默认取值通常是命令ar和选项rv,表示用ar命令将新的目标文件添加到函数库中。

    对于大型的项目,我们往往会将各个函数库下的源文件分不同的子目录存放。使用make完成这一工作的方法有2个:

    1.在子目录中编写单独的makefile文件,用于编译该子目录下的源文件,并将它们保存到一个函数库中,最后将该库文件复制到上一级目录中:

    mylib.a:  

      (cd mylib_directory;$(MAKE))

    此后,执行make mylib.a,命令将首先切换到子目录下,并执行make命令。这两个命令被括号括起来,表示确保它们用同一个shell处理。

    2.定义一些新宏,通过在已知宏($@, $<)的尾部追加字母得到:字母D表示目录,字母F表示文件,并用如下的规则替换相应的内置规则:

    .c.o  

      $(CC) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/$(@F)

    以上表示编译子目录中的源文件并将生成的目标文件置于子目录下。

    接着进一步定义:

    mylib.a: mylib/b.o mylib/f.o  

              ar -rv mylib.a $?

    则函数库将被更新。

    利用gcc -MM和makedepend工具等都可以自动生成依赖关系清单。

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    UNIX网络编程(转载)
    cin、cin.get()、cin.getline()、getline()、gets()等函数的用法(转)
    GSL GNU Scientific Library
    为人处事很有意义
    上海老大杜月笙——教你看穿一个人
    超实用的Linux/Unix快捷键大汇总(开发、管理)(2)(转)
    STL map常用操作简介(转)
    使用ifstream和getline读取文件内容[c++]
    VIM Tips
    超实用的Linux/Unix快捷键大汇总(开发、管理)(1)(转)
  • 原文地址:https://www.cnblogs.com/edgarli/p/2691671.html
Copyright © 2011-2022 走看看