make与makefile

当我们写程序过程中存在多个文件之间有复杂的包含关系时,若修改了其中一个源文件,就重新编译所有文件,一般是不必要的,并且当文件很多时,就显得非常笨拙。所有包含该文件的文件需要重新编译,而其它无关系的文件则不需要编译,但往往判断的这个过程会很令程序员头疼,并且一不小心就会出现某些需要重新编译的文件被遗漏的情况,这样就会使程序无法正常工作。

make就可以解决上述问题,它会在必要时编译所有受改动影响的源文件。

但是make自身是不能完成这项任务的,我们需要为其提供一个文件,告诉它如何去处理文件之间的关系,这个文件就是makefile文件。

就是在makefile文件中按照一定的格式把要生成的文件在编译时所需要的源文件以及编译规则写出来。这样,make会根据makefile文件按照规则在需要时重新编译所有受改动影响的源文件。可以同时存在多个不同的makefile文件分别管理项目的不同部分。makefile文件一般和其它源文件放在同一目录下。

make -f  makefile文件名

-f 选项就是指定将哪个文件作为makefile文件。如果没有使用-f选项,标准版本make命令将首先在当前目录下找名字为makefile的文件,找不到会继续查找Makefile的文件。(特殊的GNU Make则会按照GNUmakefile、makefile、Makefile的顺序搜索)

makefile文件由一组依赖关系和规则构成。完整的makefile文件例子会在后面列出。

makefile中的每个依赖关系由 一个目标文件(一般为要创建的可执行文件)和一组该目标所依赖的源文件组成。

makefile文件依赖关系的写法()如下:

mypro:   main.o  myc1.o

main.o:  main.c  a.h  b.h

myc1.o:  myc1.c  b.h

mypro1:   mypro1.c

最开始是目标文件名称,然后一个冒号,后面是目标文件所依赖的源文件(冒号和后面的源文件之间以及不同源文件之间用空格或制表符间隔)

特别需要注意的是,虽然makefile文件中已经写入了多个目标文件,但是如果只是这样执行 make 则make命令只会创建makefile文件中的第一个目标,即mypro

若要一次性创建makefile中的所有文件,需要在makefile文件的第一个目标定义为all(我们称之为伪目标),即:

all:  mypro  mypro1

mypro:   main.o  myc1.o

main.o:  main.c  a.h  b.h

myc1.o:  myc1.c  b.h

mypro1:   mypro1.c

或者执行make命令时,加上all参数 :   make  all

makefile文件的规则:

规则就是指当make创建目标文件时的方式,比如在编译myc1.o文件时,如何进行编译(如可能需要指定头文件的目录等)。

在此应特别注意:makefile文件中的 空格 和 制表符 是有区别的。规则所在的行必须以 制表符 开头,不可以用空格。并且makefile文件中不能以空格结尾,可能会使make命令执行失败(这属于历史遗留问题)

另外,makefile文件中可以使用宏定义。

下面举例完整的makefile文件:

定义一个命名为Makefile123的makefile文件

#cat Makefile123

all: mypro

#This is a makefile

#the compiler

CC = gcc

#the path

INCLUDE = .

#where to install

INSTDIR = /usr/local/bin

install: mypro

@if [ -d $(INSTDIR) ]; \

then \

cp mypro $(INSTDIR) &&\

chmod a+x $(INSTDIR)/mypro &&\

chmod og-w $(INSTDIR)/mypro &&\

echo "Installed in $(INSTDIR)" ;\

else \

echo "Sorry, $(INSTDIR) does not exist" ; \

fi

mypro: main.o c1.o

gcc -o mypro main.o a.o

main.o: main.c m.h

$(CC) -I$(INCLUDE) -c main.c

c1.o: c1.c

$(CC) -c c1.c

clean:

-rm main.o c1.o

1、make中的特殊符号:

  • 告诉make命令忽略所有错误

@   告诉make执行某条命令前不要将该条命令显示在准输出上

#  是makefile中的注释符号

CC = gcc 以及 INCLUDE = . 和INSTDIR = /usr/local/bin 是makefile中自行建立的的宏定义,引用方式为$(CC)、$(INCLUDE)和$(INSTDIR)

2、注意all只指定了一个目标mypro,所以只执行 make -f Makefile123时,则默认只创建目标mypro

我们可以看到在Makefile123文件中存在两个目标clean 和 install。

install依赖于mypro ,执行make -f Makefile123 install时,make会自行判断创建文件的正确顺序

该文件中目标install的规则由一串shell脚本命令组成,此处注意,make命令在执行规则时会调用一个shell,并且每个规则都使用一个新的shell,所以在代码结尾加上反斜杠\,使得所有shell脚本命令在逻辑上处于一行。 &&符号保证保证前面的命令执行成功后面的才会继续执行。

clean目标后面没有依赖文件,则执行 make -f Makefile123 clean时,clean对应的规则总会执行,而不是像其他目标一样只有在依赖文件发生变化时执行规则。

时间: 2024-10-16 17:01:53

make与makefile的相关文章

关于makefile中变量的多次赋值以及override指令

1 基本原则如下 1.1 原则1 变量的普通赋值是有先后顺序的,后面的赋值会覆盖掉前面的赋值. 1.2 原则2 使用的时候,用的是其前面最后的赋值,就算其后面有使用了override指令的赋值也不会影响这条原则. 1.3 原则3 当使用了override指令定义赋值了变量后,其后对该变量的所有的赋值都是无效的.但是override之前的所有的赋值都是有效的.使用的时候是往前最近原则. 2 override变量.命令行参数和普通变量之间的屏蔽关系 override变量会屏蔽命令行参数,除非用+=:

使用Makefile去管理程序

前言:在gcc中如何使用分屏操作  : 在命令行中使用    : sp + filename     vim  Makefile  编辑make工程   第一行使用 # 进行注释   说明是什么make  内容格式:  目标文件:  依赖文件 ·  ·  ·  但是一定要注意如果要使用编译指令一定要用table键 不能使用几个空格代替 另外  max.h 和min.h 的内容就是函数声明 下面说下这样make的好处吧:  在大型程序中能很好帮我们管理我们的代码和项目,程序的任何部分分工都很明确,

Contiki 2.7 Makefile 文件(三)

2.第二部分 这里的usage,targets,savetarget,savedefines都是伪目标. 和all不同,这些伪目标不会被执行,除非显式指定这些目标. 这里有两个目标savetarget,savedefines前边我们提过. 通过命令 make TARGET=esb savetarget可以保存默认的TARGET到Makefile.target中. 通过命令 make TARGET=esb DEFINES=MYTRACE,MYVALUE=4711 savedefines 可以保存默

My first makefile to compile multiple C files

I have three files to compile: main.c, func.c,  func.h The steps: 1   main.c   to   main.o 2   func.c    to   func.o 3    link main.o func.o to main(file that can execute) So, u need to run at least three commands without a Makefile.Then if u have 10

liunx中ctags 与makefile的使用

ctags 是vim下可以帮助阅读代码的一个的工具,它可以很方便的看到程序的源代码 使用ctags可以有两种方法:(1).可以在任意目录下建立文件,然后使用 ctags *.c,这个命令的意思是把当前目录下的所有文件生成标签文件(vim可以通过标签,跳转到标签文件处)例如: vim ctag.h vim ctag.c vim main.c 在main.c中把光标移至fun函数处,按Ctrl+[就会跳转到fun函数定义的地方,即ctag.c处,Ctrl+T回转到main.c函数 (2).输入cta

linux中make命令的简单使用以及Makefile文件的书写

Makefile 会不会写makele,从一个侧面说明了一个是否具备完成大型工程的能力. 一个工程中的源件不计数,其按类型.功能.模块分别放在若干个目录中,makele定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makele就像一个Shell脚本一样,其中也可以执行操作系统的命令.makele带来的好处就是"自动化编译",一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率. ma

makefile编译文件介绍

通常在C语言程序开发中,尤其是大型项目的构建,我们不可能一个文件一个文件去编译,通常会编写Makefile文件使用make命令完成项目的编译构建: 如下:math项目是简单的计算那个数字大,哪个数字小,以及两个数字和的小程序.由max.c,min.c , sum.c 和main.c构成,分别如下: max.c #include <stdio.h> int max(int a,int b) {     if(a>b){         return a;      }else{      

通用多目录makefile的写法

我的项目文件层次是:项目名称/include.output.src src/admin.stu.tch.common 最外层的Makefile: DEBUG = yMYDEBUG = DEBUGifeq ($(DEBUG),y)DEBFLAGS = -O -g -D$(MYDEBUG)elseDEBFLAGS =endif PRJ_HOME := $(shell pwd)SOURCES := $(wildcard *.c)OBJECTS := ${SOURCES:%.c=%.o}INCPATH

mcstructs使用CMake生成Makefile文件

CMakeLists.txt project(MCSTRUCTS) set(SRC_LIST src/main.c src/mcslist.c src/mcsringbuf.c) add_executable(mcstructs ${SRC_LIST}) 执行过程: [email protected]:~/projects/mcstructs$ cmake . -- Configuring done -- Generating done -- Build files have been writ

makefile实例(2)-多个文件实例

1,源文件依赖关系 defs.h command.h buffer.h main.cpp * util.cpp * kde.cpp * * command.cpp * * display.cpp * * insert.cpp * * search.cpp * * files.cpp * * * 2, 源文件 因为这里只是想做一下简单测试,所以很多源文件的内容都是空的. [[email protected] 1-makefile]#head *.h ==> buffer.h <== #pragm