zoukankan      html  css  js  c++  java
  • 如何编写makefile文件

    最近一直在学习makefile是如何编写的。
          当我们写的程序文件比较少的时候,敲入gcc /g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷。linux有一个自带的make命令,它让你的工作省去了很大的力气,但是你要学习如何编写makefile文件。
          makefile是一种特殊的文件格式,他将会帮你自动管理你的项目,很强大。它是这样工作的:
        1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
        2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
        3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
        4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
        5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了
     
    下面通过实例一步步讲解如何使用makefile。下面的四段代码。
     
     
    [cpp] view plaincopy
     
    1. /////main.cpp  
    2.   
    3. #include "functions.h"   
    4.   
    5. int main()  
    6.   
    7. {   
    8.   
    9. print_hello();   
    10.   
    11. cout << endl;   
    12.   
    13. cout << "The factorial of 5 is " << factorial(5) << endl;   
    14.   
    15. return 0;   
    16.   
    17. }   
    18.   
    19.   
    20.   
    21. ///hello.cpp   
    22.   
    23. #include "functions.h"   
    24.   
    25. void print_hello()  
    26.   
    27. {   
    28.   
    29. cout << "Hello World!";   
    30.   
    31. }   
    32.   
    33.   
    34.   
    35. ///factorial.cpp  
    36.   
    37. #include "functions.h"   
    38.   
    39. int factorial(int n)  
    40.   
    41. {   
    42.   
    43. if(n!=1)  
    44.   
    45. return(n * factorial(n-1)); }   
    46.   
    47. else return 1;   
    48.   
    49. }   
    50.   
    51. //functions.h  
    52.   
    53. void   
    54.   
    55. print_hello();  
    56.   
    57.  int factorial(int n);   

    请将以上文件放到一个目录下。
     

    请注意: 我用的是g++进行编译的,你也可以按照你自己的选择来编译程序

    make的作用

    如果你运行:    make命令, 它将会自动的在你的目录下寻找makefile文件,然后执行它,如果你几个makefile文件,你可以指定某一个特定的makefile文件 使用如下命令:

    make -f  mymakefile

    如果你想知道更多的make 用法,可以执行man  make 命令

    执行过程

    1. 编译器将会编译你的源文件,然后输出目标文件
    2. 链接器执行目标文件然后创建一个可执行文件。
    手动编译  
     

    最不理想的一种执行方式就是

     g++ main.cpp hello.cpp factorial.cpp -o hello

     

    akefile 基本规则

    makefile的基本规则是有以下构成:

    target: dependencies

    [tab] system command

    利用以上语法编写如下       

    all:

            g++main.cpp hello.cpp factorial.cpp -o hello

    然后运行你的makefile,如下

    make -f Makefile-1

    如上代码叙述,所写的目标是all,all是makefile默认的目标,如果没有其他规定,make语法将要执行这个目标文件。

    我们还发现,all 目标并没有依赖的,所以按照命令让他安全的执行。

    最后,make 通过 我们给的命令进行编译程序

    使用依赖

    这是因为,如果你修改一个单独的文件在你的项目,你不必重新编译一切,只有你修改。 请看下边的例子

    [plain] view plaincopy
     
    1. all: hello  
    2.   
    3. hello: main.o factorial.o hello.o  
    4.     g++ main.o factorial.o hello.o -o hello  
    5.   
    6. main.o: main.cpp  
    7.     g++ -c main.cpp  
    8.   
    9. factorial.o: factorial.cpp  
    10.     g++ -c factorial.cpp  
    11.   
    12. hello.o: hello.cpp  
    13.     g++ -c hello.cpp  
    14.   
    15. clean:  
    16.     rm -rf *o hello  

    我们看到目标all 只有依赖,没有系统命令。为了去执行正确,它必须满足所有的目标所依赖的。目标都回去搜索所有的依赖,然后去执行它。

    在例子中,我们看到了clean的目标,clean 这个目标就是清楚中间生成的.o文件和那些可执行文件

    使用变量和注释

    当你写makefile文件的时候,当你想改变一些编译的一些选项的时候,他是非常有用处的。

     

     
    [plain] view plaincopy
     
    1. # 这是注释,CC 编译器.  
    2.  CC=g++  
    3. # CFLAGS  是选项  
    4. CFLAGS=-c -Wall  
    5. #  目标文件  
    6. OBJECTS=main.o factorial.o hello.o  
    7. all: hello  
    8.   
    9. hello: $(OBJECTS)     
    10.     $(CC) main.o factorial.o hello.o -o hello  
    11.   
    12. main.o: main.cpp  
    13.     $(CC) $(CFLAGS) main.cpp  
    14.   
    15. factorial.o: factorial.cpp  
    16.     $(CC) $(CFLAGS) factorial.cpp  
    17.   
    18. hello.o: hello.cpp  
    19.     $(CC) $(CFLAGS) hello.cpp  
    20.   
    21. clean:  
    22.     rm -rf *o hello  

    你可以看到,使用这些有时候是非常有用的。你可以使用它们,赋值,当你想改变一些变量值的时候,然后你可以使用$(var),来应用这些变量。

     

    如何继续下去

    通过以上简要的介绍,你就可以简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边讲的只是冰山一角,你可以通过拥有变量和函数的make的文档来写。

    Makefile有三个非常有用的变量.分别是$@,$>,$<代表的意义分别是: 
    $@--目标文件,$>--所有的依赖文件,$<--第一个依赖文件.
    经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习 
    一个Makefile的缺省规则 
    ..c.o: 
    gcc -c $< 
    这个规则表示所有的 .o文件都是依赖与相应的.c文件的.


    [plain] view plaincopy
     
    1. CC=g++  
    2. CFLAGS=-c -Wall  
    3. LDFLAGS=  
    4. SOURCES=main.cpp hello.cpp factorial.cpp  
    5. OBJECTS=$(SOURCES:.cpp=.o)  
    6. EXECUTABLE=hello  
    7.   
    8. all: $(SOURCES) $(EXECUTABLE)  
    9.       
    10. $(EXECUTABLE): $(OBJECTS)   
    11.     $(CC) $(LDFLAGS) $(OBJECTS) -o $@  
    12.   
    13. .cpp.o:  
    14.     $(CC) $(CFLAGS) {1}lt; -o $@  
    15.    

     

  • 相关阅读:
    java.net.BindException: Address already in use: 解决方法
    openlayers中单击获取要素
    OpenLayers绘制图形
    springboot启动失败( No active profile set, falling back to default profiles: default)
    Java学习日报7.16
    Java学习日报7.15
    Java学习日报7.14
    Java学习日报7.13
    Java学习日报7.12
    Java学习日报7.10
  • 原文地址:https://www.cnblogs.com/dyc-cfc/p/4325181.html
Copyright © 2011-2022 走看看