(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

相关文章推荐

Storm 单机环境的安装与配置

好久没写博客了,这一段时间一直被导师push着做毕业设计。由于目前的方向偏向于图像识别检索,毕设打算做一个基于分布式计算平台的图像检索系统,查阅相关资料发现Hadoop不适用于实时的计算环境,而Twi...

流式分布式系统Storm安装与部署-单机版

主要参考的网站资源: http://my.oschina.net/leejun2005/blog/147607(一篇对照一个例子讲storm原理和应用的不错文章) http://www.cnblo...

手动建立makefile简单实例解析

  • 2009年10月08日 08:44
  • 5KB
  • 下载

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

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

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

假设我们有一个程序由5个文件组成,源代码如下: /*main.c*/ #include "mytool1.h" #include "mytool2.h" int main() {...

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

http://blog.chinaunix.net/space.php?uid=9105154&do=blog&cuid=175235 本文中使用的实例仍为《手动建立makefile简单实例...
  • yzulq
  • yzulq
  • 2011年08月31日 15:41
  • 226

make and makefile 简单入门

  • 2012年09月16日 12:22
  • 498KB
  • 下载

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

Makefile       会不会写makele,从一个侧面说明了一个是否具备完成大型工程的能力。    一个工程中的源件不计数,其按类型、功能、模块分别放在若干个目录中,makele定义了一系列的...
  • Comedly
  • Comedly
  • 2016年08月01日 00:32
  • 4290

《GNU make项目管理》笔记--简单的makefile

make定义了一种语言,可用来描述源文件、中间文件以及可执行文件之间的关系。它还提供了一些功能,可用来管理各种 候选配置、实现可重用程序库的细节以及让用户自定义宏将过程参数化。简言之,make常被视为...
  • TODD911
  • TODD911
  • 2015年01月15日 21:56
  • 1611

“vim+make+GCC”编译C++简单实例

一、主线步骤为三步: 1、用vim编写程序源文件 2、用vim编写makefile命令文件 3、在终端里输入make命令 二、实例文件有:head.h、head.cc、main.cc ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:(MAKE)手动建立makefile简单实例解析
举报原因:
原因补充:

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