`

makefile 基础知识

阅读更多

Makefile基础 :

 

make命令会自动读取当前目录下的Makefile文件,完成相应的编译步骤。Makefile由一组规则(Rule)组成,每条规则的格式是:

target ... : prerequisites ... 
	command1
	command2
	...

 
例如:

main: main.o stack.o maze.o
	gcc main.o stack.o maze.o -o main

 

main是这条规则的目标(Target)main.ostack.omaze.o是这条规则的条件(Prerequisite)

目标和条件之间的关系是:欲更新目标,必须首先更新它的所有条件;所有条件中只要有一个条件被更新了,目标也必须随之被更新。所谓“更新”就是执行一遍规则中的命令列表,命令列表中的每条命令必须以一个Tab开头,

注意不能是空格,Makefile的格式不像C语言的缩进那么随意,对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行它。

 

通常Makefile都会有一个clean规则,用于清除编译过程中产生的二进制文件,保留源文件:

clean:
	@echo "cleanning project"
	-rm main *.o
	@echo "clean completed"

 把这条规则添加到我们的Makefile末尾,然后执行这条规则:

$ make clean 
cleanning project
rm main *.o
clean completed

 如果在make的命令行中指定一个目标(例如clean),则更新这个目标,如果不指定目标则更新Makefile中第一条规则的目标(缺省目标)。

 

命令前面加@-字符的效果:

        如果make执行的命令前面加了@字符,则不显示命令本身而只显示它的结果;

       通常make执行的命令如果出错(该命令的退出状态非0)就立刻终止,不再执行后续命令,但如果命令前面加了-号,即使这条命令出错,make也会继续执行后续命令。

通常rm命令和mkdir命令前面要加-号,因为rm要删除的文件可能不存在,mkdir要创建的目录可能已存在,这两个命令都有可能出错,但这种错误是应该忽略的。

 

     文件名则不一定是Makefile。事实上,执行make命令时,是按照GNUmakefilemakefileMakefile的顺序找到第一个存在的文件并执行它,不过还是建议使用Makefile做文件名。除了GNU make,有些UNIX系统的make命令不是GNU make,不会查找GNUmakefile这个文件名,如果你写的Makefile包含GNU make的特殊语法,可以起名GNUmakefile,否则不建议用这个文件名。

 

隐含规则和模式规则:

make的隐含规则数据库可以用make -p命令打印,打印出来的格式也是Makefile的格式,包括很多变量和规则。

#号在Makefile中表示单行注释,就像C语言的//注释一样。CC是一个Makefile变量,用CC = cc定义和赋值,用$(CC)取它的值,其值应该是cc

$@$<是两个特殊的变量,$@的取值为规则中的目标,$<的取值为规则中的第一个条件。%.o: %.c是一种特殊的规则,称为模式规则(Pattern Rule)

 

一个目标依赖于若干条件,现在换个角度,以条件为中心,Makefile还可以这么写:

main: main.o stack.o maze.o
	gcc main.o stack.o maze.o -o main

main.o stack.o maze.o: main.h
main.o maze.o: maze.h
main.o stack.o: stack.h

clean:
	-rm main *.o

.PHONY: clean

 

对于多目标的规则,make会拆成几条单目标的规则来处理,例如

target1 target2: prerequisite1 prerequisite2
	command $< -o $@

 

这样一条规则相当于:

target1: prerequisite1 prerequisite2
	command prerequisite1 -o target1

target2: prerequisite1 prerequisite2
	command prerequisite1 -o target2

 注意两条规则的命令列表是一样的,但$@的取值不同。

 

变量:

foo = $(bar) 
bar = Huh? 

all: 
	@echo $(foo)

 我们执行make将会打出Huh?。当make读到foo = $(bar)时,确定foo的值是$(bar),但并不立即展开$(bar),然后读到bar = Huh?,确定bar的值是Huh?,然后在执行规则all:的命令列表时才需要展开$(foo),得到$(bar),再展开$(bar),得到Huh?。因此,虽然bar的定义写在foo之后,$(foo)展开还是能够取到$(bar)的值。

 

有时候我们希望make在遇到变量定义时立即展开,可以用:=运算符,例如:

x := foo
y := $(x) bar

all: 
	@echo "-$(y)-"

 运算符是?=,例如foo ?= $(bar)的意思是:如果foo没有定义过,那么?=相当于=,定义foo的值是$(bar),但不立即展开;如果先前已经定义了foo,则什么也不做,不会给foo重新赋值。

 

 

常用的特殊变量有:

 

  • $@,表示规则中的目标。

  • $<,表示规则中的第一个条件。

  • $?,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。

  • $^,表示规则中的所有条件,组成一个列表,以空格分隔。

  •  

     

    main: main.o stack.o maze.o
    	gcc main.o stack.o maze.o -o mainv

    可以改写成:

    main: main.o stack.o maze.o
    	gcc $^ -o $@

     

    常用的make命令行选项

    -n选项只打印要执行的命令,而不会真的执行命令,这个选项有助于我们检查Makefile写得是否正确,由于Makefile不是顺序执行的,用这个选项可以先看看命令的执行顺序,确认无误了再真正执行命令。

    -C选项可以切换到另一个目录执行那个目录下的Makefile,

    make命令行也可以用=:=定义变量,如果这次编译我想加调试选项-g,但我不想每次编译都加-g选项,可以在命令行定义CFLAGS变量,而不必修改Makefile编译完了再改回来:

    $ make CFLAGS=-g
    cc -g   -c -o main.o main.c
    cc -g   -c -o stack.o stack.c
    cc -g   -c -o maze.o maze.c
    gcc main.o stack.o maze.o -o main

    如果在Makefile中也定义了CFLAGS变量,则命令行的值覆盖Makefile中的值。

     

     

    分享到:
    评论

    相关推荐

      makefile基础知识.pdf

      "makefile基础知识" Makefile 是一种自动化编译工具,常用于大型开发项目的管理和维护。它可以将复杂的开发项目分解成多个易于管理的模块,並高效地处理源文件之间的复杂关系。 Makefile 的主要功能是描述源程序...

      Makefile基础知识

      【Makefile基础知识】深入理解Makefile的使用与原理 Makefile是Linux环境下自动化构建和管理项目的强大工具,它能够帮助开发者高效地编译、链接和管理项目中的源代码。掌握Makefile的基础知识,有助于提高软件开发...

      Makefile基础知识及Makefile Kconfig 内核配置 内核裁剪.rar

      **Makefile基础知识:** 1. **目标和依赖:** Makefile中最基本的概念是目标(Target)和依赖(Dependency)。目标是需要创建或更新的文件,依赖则是目标文件生成所依赖的其他文件。例如,`target: dependency1 ...

      Makefile基础知识学习 很好 肯定能学会

      ### Makefile基础知识详解 #### 第一部分:概述 Makefile是一种用于描述如何构建程序或文档的脚本文件。它被广泛应用于软件开发过程中,用来管理项目的编译和链接过程。通过Makefile,开发者可以轻松地组织复杂的...

      Makefile基础使用_嵌入式-常用知识&面试题库_大厂面试真题.pdf

      Makefile基础使用_嵌入式知识点总结 ...* 面试题库:Makefile基础知识是嵌入式系统开发的基础知识之一,常被作为面试题。 Makefile是嵌入式系统开发的重要工具,掌握Makefile的基础知识对于嵌入式系统开发至关重要。

      Makefile教程,Makefile快速学习资料

      标题中提到的“Makefile教程”是指...总的来说,这部分内容为我们提供了Makefile基础知识的介绍,以及其在软件编译中的重要性。它还简要描述了编译和链接的基本过程,并为接下来深入探讨Makefile的编写规则奠定了基础。

      makefile中文高清版.pdf

      #### 二、Makefile基础知识 - **基本概念**: - **目标 (Target)**: Makefile 中的目标通常是需要创建的文件名,如可执行文件或库文件。 - **依赖项 (Prerequisite)**: 指创建目标所需要的文件,通常是指源代码...

      超级经典makefile

      #### 三、Makefile基础知识 - **目标和依赖**:makefile的核心在于定义“目标”以及它们之间的“依赖”关系。目标通常是输出文件,如可执行文件或者库文件;依赖则是生成目标所需要的源文件或其他目标。 - **规则**...

      makefile详细资料

      ### Makefile基础知识详解 #### 一、Makefile概念与重要性 **Makefile**是一种用于自动化构建过程的脚本文件,广泛应用于软件工程领域。它主要用于定义如何编译和链接程序,通过设置一系列规则来控制文件的依赖...

      makefile编程.pdf

      #### 二、Makefile基础知识 1. **Makefile简介** - Makefile是一个文本文件,其中包含了构建项目的指令。 - 它定义了目标文件、依赖关系及构建命令。 - 通过`make`命令执行Makefile中的指令来构建项目。 2. **...

      Makefile写法

      ### Makefile基础知识与实践 #### 一、Makefile概述 **Makefile** 是一种用于自动化构建过程的脚本文件,在软件开发过程中具有重要的作用。它主要用于管理项目的编译过程,帮助开发者有效地组织和自动化编译任务。...

      GNU-Makefile.zip_makefile PDF

      以上只是Makefile基础知识的一部分,深入理解并熟练运用Makefile能够极大地提升软件项目的构建效率和维护性。通过阅读《GNU Makefile中文手册.pdf》,你可以更全面地了解Makefile的细节和技巧,从而更好地利用这一...

      跟我一起写 Makefile.doc

      #### 三、Makefile基础知识 1. **Makefile的基本结构**: - **目标(target)**:Makefile中的目标是指要构建的对象,如最终的可执行文件或中间文件。 - **依赖(dependency)**:指明目标文件依赖于哪些源文件或其他...

      跟我一起写makefile

      #### 三、Makefile基础知识 - **目标(Targets)**:Makefile中的目标是指最终想要构建的产品,如可执行文件或库文件。 - **依赖(Dependencies)**:为了构建某个目标所需的其他文件,例如源代码文件或头文件。 - **...

      自动生成 Makefile 的全过程详解

      在深入了解 automake 和 autoconf 之前,我们先简要回顾一下 Makefile 的基础知识。 - **Makefile 的功能**:Makefile 是一种用于描述软件项目中文件之间的依赖关系以及编译规则的脚本文件。它可以帮助开发者自动...

      跟我一起学makefile

      ### makefile基础知识详解 #### 一、makefile简介 **makefile**是一种用于自动化构建过程的脚本文件,在软件开发领域极为常见,特别是在C/C++项目中。它定义了一组规则来告诉构建系统如何编译源代码并链接生成可...

      Makefile.docx

      Makefile基础知识概要 Makefile是 UNIX-like 系统中一种常用的构建自动化工具,用于管理和维护大型软件项目。Makefile文件由一系列规则组成,每条规则都定义了一个目标文件的生成过程。下面是Makefile基础知识概要...

    Global site tag (gtag.js) - Google Analytics