最近越来越感觉到,在linux下面身为一个程序员,不会makefile就不是一个合格的程序员,所以今天我们介绍下常用的makefile编写.

了解知识:
  编译:把高级语言书写的代码转换为机器可识别的机器指令。编译高级语言后生成的指令虽然可被机器识别,但是还不能被执行。编译时,编译器检查高级语言的语法、函数与变量的声明是否正确。只有所有的语法正确、相关变量定义正确编译器就可以编译出中间目标文件。通常,一个高级语言的源文件都可对应一个目标文件。目标文件在Linux 中默认后缀为".o"(如“ foo.c”的目标文件为“ foo.o”)。

  链接:将多.o 文件,或者.o 文件和库文件链接成为可被操作系统执行的可执行程序( Linux 环境下,可执行文件的格式为“ ELF”格式)。链接器不检查函数所在的源文件,只检查所有.o 文件中的定义的符号。将.o 文件中使用的函数和其它.o 或者库文件中的相关符号进行合并,对所有文件中的符号进行重新安排(重定位),并链接系统相关文件(程序启动文件等)最终生成可执行程序。

Makefile简介 :
      当使用 make 工具进行编译时,工程中以下几种文件在执行 make 时将会被编译 (重新编译):
      1. 所有的源文件没有被编译过,则对各个 C 源文件进行编译并进行链接,生成最后的可执行程序;
      2. 每一个在上次执行 make 之后修改过的 C 源代码文件在本次执行 make 时将会被重新编译;
      3. 头文件在上一次执行 make 之后被修改。则所有包含此头文件的 C 源文件在本次执行 make 时将会被重新编译。
      后两种情况是 make 只将修改过的 C 源文件重新编译生成.o 文件,对于没有修改的文件不进行任何工作。重新编译过程中,任何一个源文件的修改将产生新的对应的.o文件,新的.o 文件将和以前的已经存在、此次没有重新编译的.o 文件重新连接生成最后的可执行程序。

makefile的基本规则: 

    Makefile由一组规则组成,规则如下:

                    目标(app):依赖(main.c a.c b.c)
                                        命令(gcc main.c a.c b.c -o app)

         makefile基本规则三要素:

                     目标:要生成的目标文件

                     依赖:目标文件由哪些文件生成

                     命令:通过执行该命令由依赖文件生成目标

makefile工作原理:

makefile变量:

  在Makefile中使用变量有点类似于C语言中的宏定义,使用该变量相当于内容替换, 使用变量可以使Makefile易于维护,修改内容变得简单变量定义及使用。

  1).普通变量
        foo = abc            // 定义变量并赋值
        bar = $(foo)        // 使用变量,$(变量名)
        定义了两个变量:foo、bar,其中bar的值是foo变量值的引用。
       变量定义直接用’=’
       使用变量值用$(变量名)
    2)makefile中也提供了一些变量(变量名大写)供用户直接使用,我们可以直接对其进行赋值
        src = main.c func1.c func2.c
        CC = gcc #arm-linux-gcc
        CPPFLAGS : C预处理的选项如:-I
        CFLAGS: C编译器的选项–Wall –g -c
        LDFLAGS : 链接器选项–L –l
    3)自动变量
        $@:表示规则中的目标
        $<:表示规则中的第一个条件
        $^:表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复的项则消除重复项。
        注意:自动变量只能在规则的命令中中使用
    4)模式规则
        至少在规则的目标定义中要包含'%','%'表示一个或多个,在依赖条件中同样可以使用'%',依赖条件中的'%'的取值取决于其目标
            模式规则示例:
                %.o:%.c
                    $(CC) –c $(CFLAGS) $(CPPFLAGS) $< -o $@

makefile函数:
   makefile中的函数有很多,在这里给大家介绍两个最常用的。
  1.    wildcard – 查找指定目录下的指定类型的文件    
    src = $(wildcard *.c)//找到当前目录下所有后缀为.c的文件,赋值给src
  2.    patsubst – 匹配替换
    obj = $(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
  注意:在makefile中所有的函数都是有返回值的。
clean:
  用途:清除编译生成的中间.o文件和最终目标文件
  make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令,解决方案:
    伪目标声明: .PHONY:clean
        声明目标为伪目标之后,makefile将不会该目标是否存在或者该目标是否需要更新
    clean命令中的特殊符号:
                    “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
                    “@”不显示命令本身,只显示结果。如:“@echoclean done”
其它了解内容:
    make 默认执行第一个出现的目标,可通过make dest指定要执行的目标
    make -C 指定目录: 进入指定目录,调用里面的Makefile
    make -n :只打印要执行的命令,不会真正执行命令
    make -p :显示隐含规则数据库中的信息
    make -f :-f执行一个makefile文件名称,使用make执行指定的makefile

    

关于makefile的那些事儿的更多相关文章

  1. 说说Makefile那些事儿

    说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...

  2. makefile那些事儿

    一.好处 自动化编译,一条make命令,整个工程可以完全自动编译,make命令是构建大型项目的首选方案. makefile就像一个shell脚本一样,用来定义规则,一个名称包含一条或多条命令,在终端m ...

  3. Linux就这个范儿 第8章 我是Makefile

    Linux就这个范儿 第8章 我是Makefile P287 Makefile的作用就是——自动化编译,一旦写好,只需要一个make命令(解析Makefile,执行Makefile中描述的操作),整个 ...

  4. 如何自己编译apue.3e中代码 & 学习写makefile

    本来是搜pthread的相关资料,看blog发现很多linux程序员都看的一本神书<APUE>,里面有系统的两章内容专门讲pthread(不过是用c语言做的代码示例,这个不碍事,还是归到原 ...

  5. [apue] linux 文件系统那些事儿

    前言 说到 linux 的文件系统,好多人第一印象是 ext2/ext3/ext4 等具体的文件系统,本文不涉及这些,因为研究具体的文件系统难免会陷入细节,甚至拉大段的源码做分析,反而不能从宏观的角度 ...

  6. 彻底掌握Makefile(一)

    彻底掌握Makefile(一) 介绍 makefile就是一个可以被make命令解析的文件,他定义了一系列编译的规则,帮助我们更加方便.简洁的去完成编译的过程.在一个大工程当中我们会有各种各样的文件, ...

  7. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

  8. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  9. 编写简单的Makefile文件

    makefile中的编写内容如下: www:hello.c x.h gcc hello.c -o hello clean: rm hello www:hello.c  x.h 表示生成www这个文件需 ...

随机推荐

  1. js原型链和继承

    在了解js原型链之前构造函数.原型对象.对象实例这几种概念必须要明白. 1. 创建对象有几种方法 //原型链指向objectvar o1={name:'o1'}; var o11=new Object ...

  2. Zabbix监控web,MySQL,TCP状态,Nginx

    接上篇Zabbix使用SMTP发送邮件报警并且制定报警内容 Zabbix怎么设置声音告警 web监控 在zabbix server选择web 创建一个监控web的场景 添加后这里有数字1 查看 假如在 ...

  3. Javaweb Tomcat 项目部署方式

    一.静态部署 1.直接将web项目文件件拷贝到webapps 目录中     Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用.所以可以将JSP ...

  4. tomcat------->简单配置

    主机名:www.snowing.com 域名:snowing.com http://主机+服务器端口号/path(web应用)/xxx.html 例: http://localhost:8080/it ...

  5. NGINX优化参数

    (1)nginx运行工作进程个数,一般设置cpu的核心或者核心数x2 如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor / ...

  6. 【Python数据挖掘】回归模型与应用

    线性回归 ( Linear Regression ) 线性回归中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归称为一元线性回归. 如果回归分析中包括两个或两个以上的自变量, ...

  7. Spark 源码分析 -- Stage

    理解stage, 关键就是理解Narrow Dependency和Wide Dependency, 可能还是觉得比较难理解 关键在于是否需要shuffle, 不需要shuffle是可以随意并发的, 所 ...

  8. HDFS 手写mapreduce单词计数框架

    一.数据处理类 package com.css.hdfs; import java.io.BufferedReader; import java.io.IOException; import java ...

  9. JMeter场景运行(非GUI方式运行命令)

    JMeter场景运行方式可分为两种:  GUI方式运行,视窗运行,双击jmeter.bat启动运行即可以看到运行界面:  非GUI方式运行,在命令窗口中使用java –jar命名运行: 但不管是以 ...

  10. ShuffleNet

    ShuffleNet (An Extremely Efficient Convolutional Neural Network for Mobile Devices) —— Face++ shuffl ...