zoukankan      html  css  js  c++  java
  • makefile从无到有

    Makefile这玩意在上学时就应该学,可是一直沉浸于IDE的诱惑,所谓“死于安乐”,直到现在一把年纪才开始接触这种基础东西。

    创建C程序

    先写个c程序,保存在main.c里:

    1. //////////////////  
    2. // file: main.c  
    3. //////////////////  
    4.   
    5. #include <stdio.h>  
    6.   
    7. int main()  
    8. {  
    9.     int c = 0;  
    10.     printf("Tommy: %d\n", c+5);  
    11.     return 0;  
    12. }  


    看看我这时的目录结构

    1. ~/code/makefile$ ls  
    2. main.c  


    这时敲个“make”命令试试?

    1. ~/code/makefile$ make  
    2. make: *** 没有指明目标并且找不到 makefile。 停止。  

    创建makefile文件

    显然,我们要建个名为“makefile”的文件。先建一个空的名为makefile的文件:

    1. ~/code/makefile$ touch makefile  
    2. tommy@tommy-zheng-ThinkPad-T61:~/code/makefile$ ls  
    3. main.c  makefile  

    这时再试试“make”命令:

    1. ~/code/makefile$ make  
    2. make: *** 无目标。 停止。  


    加入target
    错误“无目标”告诉我们需要在makefile里添加一些东西:

    1. # 注释 file: makefile  
    2. target:  

    再执行“make”命令:

    1. ~/code/makefile$ make  
    2. make: 没有什么可以做的为 `target'。  

    可以看到前面“无目标”的错误已经解决了。

    加入命令

    继续往makefile里添加东西:

    1. # 注释 file: makefile  
    2. target:  
    3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  

    好了,执行make命令:

    1. ~/code/makefile$ make  
    2. gcc -o tommy main.c  
    3. ~/code/makefile$ ls  
    4. main.c  makefile  tommy  

    main.c被编译了,一个可执行文件“tommy”产生了。我们执行一下试试:

    1. ~/code/makefile$ ./tommy  
    2. Tommy: 5  


    得意我们的makefile写完了!!!

     

    好吧,之前的makefile实在是太简单,以至于没什么实际的用途。现在再深入研究下。

    Target
    在前面的makefile里,有一个叫"target"的东西。其实它可以是任何名字,而且一个makefile里可以有多个target。比如下面的makefile:

    1. # 注释 file: makefile  
    2. tommy:  
    3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  
    4. dosomething:  
    5.     echo just for fun.  

    给make命令一个参数:

    1. ~/code/makefile$ make dosomething  
    2. echo just for fun.  
    3. just for fun.  

    可以看到,make可以用来执行任何一个target底下的命令,而这种命令并不局限于gcc这种编译的命令。每个target用冒号隔开。如果make命令没有指定哪个target,那第一个target下的命令会被执行。

    Dependencies

    make命令一次只能处理一个target,但如果我想一次处理多个target怎么办?这时可以为一个target在冒号后面指定它所依赖的target。修改下makefile:

    1. # 注释 file: makefile  
    2. tommy:  
    3.     gcc -o tommy main.c # 注意,最前面是tab,不是空格!  
    4. dosomething: dofirst dosecond # 先执行另两个target的命令  
    5.     echo just for fun.  
    6. dofirst:  
    7.     echo first.  
    8. dosecond:  
    9.     echo second.  
    10. donothing:  
    11.     echo nothing.  

    make一下看看:

    1. ~/code/makefile$ make dosomething  
    2. echo first.  
    3. first.  
    4. echo second.  
    5. second.  
    6. echo just for fun.  
    7. just for fun.  

    可以看到,dofirst和dosecond在dosomething之前都被make了,但tommy和donothing都没有执行。

    编译多个C文件

    现在增加两个文件f.h和f.c,同时改一下main.c:

    1. ////////////////  
    2. // file: f.h  
    3. ////////////////  
    4.   
    5. int add(intint);  
    6.   
    7. ////////////////  
    8. // file: f.c  
    9. ////////////////  
    10.   
    11. int add(int a, int b)  
    12. {  
    13.     return a + b;  
    14. }  
    15.   
    16. //////////////////  
    17. // file: main.c  
    18. //////////////////  
    19.   
    20. #include <stdio.h>  
    21. #include "f.h"  
    22.   
    23. int main()  
    24. {  
    25.     printf("Tommy-add: %d\n", add(2, 4));  
    26.     return 0;  
    27. }  

    看看我的目录结构:

    1. ~/code/makefile$ ls  
    2. f.c  f.h  main.c  makefile  

    基于前面的“Dependencies”得到的结论,我们可以改写makefile,来让main函数调用f函数:

    1. # file: makefile  
    2. tommy: main.o f.o  
    3.     gcc -o tommy main.o f.o  
    4. main.o:  
    5.     gcc -c main.c -o main.o  
    6. f.o:  
    7.     gcc -c f.c -o f.o  

    看下生成的结果:

    1. ~/code/makefile$ make  
    2. gcc -c main.c -o main.o  
    3. gcc -c f.c -o f.o  
    4. gcc -o tommy main.o f.o  
    5.   
    6. ~/code/makefile$ ls  
    7. f.c  f.h  f.o  main.c  main.o  makefile  tommy  
    8.   
    9. ~/code/makefile$ ./tommy  
    10. Tommy-add: 6  

    可以看到我们的生成了我们想要的东西。

    clean与install
    经常可以看到“make clean”和“make install”的命令。我们也可以提供它们:

    1. # file: makefile  
    2. tommy: main.o f.o  
    3.     gcc -o tommy main.o f.o  
    4. main.o:  
    5.     gcc -c main.c -o main.o  
    6. f.o:  
    7.     gcc -c f.c -o f.o  
    8. clean:  
    9.     rm *.o  
    10. install:  
    11.     mv tommy /usr/local  



    最后再研究下makefile里的宏。其实就是定义一个变量,之后再使用它:

    1. # file: makefile  
    2. INSTALL_PATH = /usr/local  
    3. TEMP_FILES = *.o  
    4. tommy: main.o f.o  
    5.     gcc -o tommy \  
    6.         main.o f.o # 这里演示反斜杠用于换行,注意反斜杠后没有空格,行首是tab而非空格  
    7. main.o:  
    8.     gcc -c main.c -o main.o  
    9. f.o:  
    10.     gcc -c f.c -o f.o  
    11. clean:  
    12.     rm $(TEMP_FILES)  
    13. install:  
    14.     mv tommy $(INSTALL_PATH)  
  • 相关阅读:
    100篇论文
    Tengine vs openresty
    Dottrace跟踪代码执行时间
    Linux Server
    Linux+Apache+Mysql+Php
    linux+nginx+mysql+php
    tshark命令行的使用(转)
    tcpdump VS tshark用法(转)
    Lua语言在Wireshark中使用(转)
    doc-remote-debugging.html
  • 原文地址:https://www.cnblogs.com/zhanglanyun/p/2218834.html
Copyright © 2011-2022 走看看