zoukankan      html  css  js  c++  java
  • 从gcc到Makefile简易版

    1、Makefile的应用
      我们主要用它来编译源代码,生成结果代码,然后把结果代码连接起来生成可执行文件或者库文件。
    2、Makefle简单例子的深入学习
      程序概述:为了连接makefile的流程,我将最简单的程序“hello wrold!”分成两个.c文件,并最终在main中进行编译。
      以下都是对同个文件进行makefile的编译,知识makfile编写回比较贴近shell脚本的语法
      如果没有指定输出项目的时候Make会自动找到makefile中第一个目标中没有通配符的目标进行构造,所以步骤是:
      例子1:
      终端界面的命令格式

      gcc -o hello main.c hello.c wrold.c

      注释:gcc 代表的是编译器类型

      -o 表示生成可执行文件
      hello 表示生成的可执行文件的名称
      *.c 表示c程序文件


      例子2:
      接下来我们编写Makefile文件

      hello: main.c hello.c wrold.c
      gcc -o hello main.c hello.c wrold.c

      注释:它主要分成了三个部分

      第一行冒号之前的hello,我们称之为目标(target),被认为是这条语句所要处理的对象,具体到这里就是我们所要编译的这个程序hello。
      冒号后面的部分(main.c hello.c wrold.c),我们称之为依赖关系表,也就是编译hello所需要的文件,(此部分是可以省略的)
      命令部分,相信你也看得出这就是一条编译命令。现在我们只要将上面这两行语句写入一个名为Makefile或者makefile的文件,然后在终端中输入make命令,就会看到它按照我们的设定去编译程序了。
      请注意,在第二行的“gcc”命令之前必须要有一个tab缩进。语法规定Makefile中的任何命令之前都必须要有一个tab缩进,否则make就会报错。
      

      例子3:
      接下来我们使用shell脚本语言对于makefile进行更改

      cc = gcc
      prom = hello
      source = main.c hello.c wrold.c
    
      $(prom): $(source)
      $(cc) -o $(prom) $(source)

      注释:$(名字) 代表一个变量,shell脚本在执行这个变量时,会进行替换

      cc、prom以及source。它们分别告诉了make我们要使用的编译器、要编译的目标以及源文件
      

      例子4:
      对于一个文件的修改,需要重新编译整个流程(其他的.c文件也需要编译)

      cc = gcc
      prom = hello
      objs = main.o hello.o wrold.o
    
      $(prom): $(objs)
      $(cc) -o $(prom) $(objs)
    
      main.o: main.c
      $(cc) -c main.c
    
      hello.o: hello.c
      $(cc) -c hello.c
    
      wrold.o: wrold.c
      $(cc) -c wrold.c

      注释:标准的编译过程中,源文件往往是先被编译成目标文件,然后再由目标文件连接成可执行文件的。我们可以利用这一点来调整一下这些文件之间的依赖关系。

      总工程通过.o文件进行编译的话,如果.c文件没改变,那么原先的.o可以继续使用,不需要重新编译。
      

      例子5:
      我们发现许多类型重复的语句,这样的效率并不高,可以将类型一样的语句整合到一起

      cc = gcc
      prom = hello
      objs = main.o hello.o wrold.o
    
      $(prom): $(objs)
      $(cc) -o $(prom) $(objs)
    
      %.o:%.c
      $(cc) -c $< -o $@

      注释:makeefile中使用的”%“通配符和系统中“*”通配符的区别:

      %.o:%.c的的意思是,“%”代表通配符的意思,等价于% =任意字符(比如main,hello等),当然结尾的格式要一样
      $@:目标的名字($@代表的是当前语句的目标,即%.o)
      $^:构造所需文件列表所有所有文件的名字
      $<:构造所需文件列表的第一个文件的名字
      $?:构造所需文件列表中更新过的文件

      例子6:
      增加自动清理编译结果的功能就可以为其定义一个带伪目标的规则

      cc = gcc
      prom = hello
      objs = main.o hello.o wrold.o
    
      %.o:%.c
      $(cc) -c $< -o $@
    
      $(prom): $(objs)
      $(cc) -o $(prom) $(objs)
    
      #%.o:%.c 
      # $(cc) -c $< -o $@
    
      clean:
      rm -rf $(prom) $(objs)

     注释:有了上面最后两行代码,当我们在终端中执行make clean命令时,它就会去删除该工程生成的所有编译文件。

      而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)
      

      例子7:
      自动扫描当前文件夹下的.c或.h文件

      cc = gcc
      prom = hello
      deps = $(shell find ./ -name "*.h")
      src = $(shell find ./ -name "*.c")
      objs = $(src:%.c=%.o)
    
      $(prom): $(objs)
      $(cc) -o $(prom) $(objs)
    
      %.o:%.c
      $(cc) -c $< -o $@
    
      clean:
      rm -rf $(prom) $(objs)

      注释:$(shell find ./ -name "*.h") //意思是寻找当前文件夹下的.h文件

        $(src:%.c=%.o) //将src中的.c结尾的变量名字替换成.o结尾的名字

  • 相关阅读:
    Intellij Idea免费激活方法
    算法中的 log 到底是什么?
    java 历史版本下载
    IntelliJ远程调试教程
    【转载】 tensorflow batch_normalization的正确使用姿势
    【转载】 Tensorflow如何直接使用预训练模型(vgg16为例)
    某宝购入牙膏厂U后其售后事宜的思虑
    【转载】 tensorflow: 怎样找到对应的bazel 版本和安装
    【转载】 优必选悉尼 AI 研究院何诗怡:基于课程学习的强化多标签图像分类算法 | 分享总结
    【转载】 科研工作者的哪些「新手常见错误」
  • 原文地址:https://www.cnblogs.com/goul/p/11647754.html
Copyright © 2011-2022 走看看