(MAKE)手动建立makefile简单实例解析

转载 2014年02月15日 17:24:27

假设我们有一个程序由5个文件组成,源代码如下:

/*main.c*/

#include
"mytool1.h"
#include
"mytool2.h"

int main()
{
         mytool1_print(
"hello mytool1!");
         mytool2_print(
"hello mytool2!");
        
return0;
}

  

/*mytool1.c*/

#include
"mytool1.h"
#include
<stdio.h>

void mytool1_print(char*print_str)
{
         printf(
"This is mytool1 print : %s\n",print_str);
}

 

/*mytool1.h*/

#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
        
void mytool1_print(char*print_str);
#endif

 

/*mytool2.c*/

#include
"mytool2.h"
#include
<stdio.h>

void mytool2_print(char*print_str)
{
         printf(
"This is mytool2 print : %s\n",print_str);
}

 

/*mytool2.h*/

#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
        
void mytool2_print(char*print_str);
#endif

    首先了解一下make和Makefile。GNU make是一个工程管理器,它可以管理较多的文件。我所使用的RedHat 9.0的make版本为GNU Make version 3.79.1。使用make的最大好处就是实现了“自动化编译”。如果有一个上百个文件的代码构成的项目,其中一个或者几个文件进行了修改,make就能够自动识别更新了的文件代码,不需要输入冗长的命令行就可以完成最后的编译工作。make执行时,自动寻找Makefile(makefile)文件,然后执行编译工作。所以我们需要编写Makefile文件,这样可以提高实际项目的工作效率。

    在一个Makefile中通常包含下面内容:

1、需要由make工具创建的目标体(target),通常是目标文件或可执行文件。
2、要创建的目标体所依赖的文件(dependency_file)。
3、创建每个目标体时需要运行的命令(command)。

格式如下:

target:dependency_files
<TAB>command

target:规则的目标。通常是程序中间或者最后需要生成的文件名,可以是.o文件、也可以是最后的可执行程序的文件名。另外,目标也可以是一个make执行的动作的名称,如目标“clean”,这样的目标称为“伪目标”。

dependency_files:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。


command:规则的命令行。是make程序所有执行的动作(任意的shell命令或者可在shell下执行的程序)。一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行。make按照命令完成相应的动作。这也是书写Makefile中容易产生,而且比较隐蔽的错误。命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。一个目标可以没有依赖而只有动作(指定的命令)。比如Makefile中的目标“clean”,此目标没有依赖,只有命令。它所指定的命令用来删除make过程产生的中间文件(清理工作)。


在Makefile中“规则”就是描述在什么情况下、如何重建规则的目标文件,通常规则中包括了目标的依赖关系(目标的依赖文件)和重建目标的命令。make执行重建目标的命令,来创建或者重建规则的目标(此目标文件也可以是触发这个规则的上一个规则中的依赖文件)。规则包含了目标和依赖的关系以及更新目标所要求的命令。
Makefile中可以包含除规则以外的部分。一个最简单的Makefile可能只包含规则描述。规则在有些Makefile中可能看起来非常复杂,但是无论规则的书写是多么的复杂,它都符合规则的基本格式。

下面就可以写出第一个Makefile了。

main:main.o mytool1.o mytool2.o
         gcc
-o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
         gcc
-c main.c
mytool1.o:mytool1.c mytool1.h
         gcc
-c mytool1.c
mytool2.o:mytool2.c mytool2.h
         gcc
-c mytool2.c

clean:
         rm
-f *.o

在shell提示符下输入make,执行显示:

gcc-c main.c
gcc
-c mytool1.c
gcc
-c mytool2.c
gcc
-o main main.o mytool1.o mytool2.o

执行结果如下:

[armlinux@lqm makefile-easy]$ ./main
This
is mytool1 print : hello mytool1!
This
is mytool2 print : hello mytool2!

这里并不会执行Makefile文件里的clean : rm -f *.o语句,执行完make后,在执行make clean,则该命令得到执行。

这只是最为初级的Makefile,现在来对这个Makefile进行改进。

改进一:使用变量

一般在书写Makefile时,各部分变量引用的格式如下:
1. make变量(Makefile中定义的或者是make的环境变量)的引用使用“$(VAR)”格式,无论“VAR”是单字符变量名还是多字符变量名。
2. 出现在规则命令行中shell变量(一般为执行命令过程中的临时变量,它不属于Makefile变量,而是一个shell变量)引用使用shell的“$tmp”格式。
3. 对出现在命令行中的make变量同样使用“$(CMDVAR)” 格式来引用。

OBJ=main.o mytool1.o mytool2.o

make:$(OBJ)
         gcc
-o main $(OBJ)
main.o:main.c mytool1.h mytool2.h
         gcc
-c main.c
mytool1.o:mytool1.c mytool1.h
         gcc
-c mytool1.c
mytool2.o:mytool2.c mytool2.h
         gcc
-c mytool2.c

clean:
         rm
-f main $(OBJ)

改进二:使用自动推导

让make自动推导,只要make看到一个.o文件,它就会自动的把对应的.c文件加到依赖文件中,并且gcc -c .c也会被推导出来,所以Makefile就简化了。

CC= gcc
OBJ
= main.o mytool1.o mytool2.o

make: $(OBJ)
         $(CC)
-o main $(OBJ)

main.o: mytool1.h mytool2.h
mytool1.o: mytool1.h
mytool2.o: mytool2.h

.PHONY: clean
clean:
         rm
-f main $(OBJ)

改进三:自动变量($^ $< $@)的应用

Makefile 有三个非常有用的变量,分别是$@、$^、$<。代表的意义分别是:
$@--目标文件,
$^--所有的依赖文件,
$<--第一个依赖文件。

CC= gcc
OBJ
= main.o mytool1.o mytool2.o

main: $(OBJ)
         $(CC)
-o $@ $^

main.o: main.c mytool1.h mytool2.h
         $(CC)
-c $<                               #该行可以省略,为了说明符号“<”,所以保留  
mytool1.o: mytool1.c mytool1.h
         $(CC)
-c $<                              #该行可以省略,为了说明符号“<”,所以保留  
mytool2.o: mytool2.c mytool2.h
         $(CC)
-c $<                              #该行可以省略,为了说明符号“<”,所以保留  

.PHONY: clean
clean:
         rm
-f main $(OBJ)

     这些是最为初级的知识,现在至少可以减少编译时的工作量。细节方面的东西还需要在以后的工作和学习中不断的总结,不断的深化理解。可以 参考GNU Make手册,

这里讲解的比较全面。


原文地址:http://www.360doc.com/mymsg.aspx?app=2

(MAKE)手动建立makefile简单实例解析 - vim+gcc+gdb+make -...

转自http://www.360doc.com/content/09/0109/18/36491_2298945.shtml 假设我们有一个程序由5个文件组成,源代码如下: /*main.c*...
  • u012530451
  • u012530451
  • 2015年07月21日 12:40
  • 1271

手动建立makefile简单实例解析

假设我们有一个程序由5个文件组成,源代码如下:/*main.c*/#include "mytool1.h"#include "mytool2.h"int main(){        mytool1_...
  • piaoxiangxinling
  • piaoxiangxinling
  • 2006年09月22日 14:34
  • 1089

手动建立makefile简单实例解析!

假设我们有一个程序由5个文件组成,源代码如下: /*main.c*/ #include "mytool1.h" #include "mytool2.h" int main() {...
  • Bresponse
  • Bresponse
  • 2011年12月29日 10:19
  • 566

手动建立makefile简单实例解析(转载)

手动建立makefile简单实例解析(转载)  假设我们有一个程序由5个文件组成,源代码如下: [cpp] view plaincopyprint? /*main...
  • jipingyuan
  • jipingyuan
  • 2014年07月29日 08:24
  • 349

我所认识的GNU make(5) -- make是如何处理Makefile的

通常情况下Makefile的内容就是告诉make如何去编译和链接生成一个程序。并且默认情况下,make会以在Makefile中寻找到的目标作为这次执行make程序的最终目标,所以和最终目标不相干的规则...
  • Hydrazine
  • Hydrazine
  • 2015年01月11日 13:57
  • 765

Makefile管理工具与GDB调试工具学习笔记

一、Makefile项目管理工具:1、用途:①项目代码编译管理 ②节省编译项目时间 ③一次编写终身受益2、规则记录:(1)、三要素:目标、依赖、命令,格式如下:目标:依赖(条件) 命令 /...
  • Apollon_krj
  • Apollon_krj
  • 2017年02月18日 01:00
  • 549

使用autotools建立Makefile简单实例解析

本文中使用的实例仍为《手动建立makefile简单实例解析》中的5文件工程实例。对于一个较大的项目而言,完全手动建立Makefile是一件费力而又容易出错的工作。autotools系列工具只需用户输入...
  • delovery
  • delovery
  • 2009年05月01日 12:09
  • 298

makefile中伪目标详解

伪目标 下面的“clean”目标,是一个“伪目标”,     clean:             rm *.o temp 我们生成了许多文件编译文件,我们也应该提供一个清除它们的“目标”以备完整地重...
  • ming470612141
  • ming470612141
  • 2008年11月24日 20:31
  • 8126

从头开始写项目Makefile(八):模式规则

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】     上一节讲到目录创建成功,目标文件没有生产到对应目录下,这...
  • gentleliu
  • gentleliu
  • 2014年07月23日 21:16
  • 2893

make的使用和Makefile的编写

标签: Linux C/C++开发 简介 make使用 基本构成 流程 说明 文件的构成 说明 伪目标 特殊目标 搜索目录 使用变量 使用条件语句 使用库 make参数 命令行 简介 make:维护程...
  • u012510204
  • u012510204
  • 2016年12月29日 12:43
  • 1538
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:(MAKE)手动建立makefile简单实例解析
举报原因:
原因补充:

(最多只允许输入30个字)