初学MAKEFILE

入门Makefile

一:概述
Makefile是一个命令工具,是一个解释 makefile 中指令的命令
工具,一般来说,大多数的 IDE 都有这个命令,比如:Delphi 的 make,Visual C++的 nmake,
Linux 下 GNU 的 make。可见,makefile 都成为了一种在工程方面的编译方法。
是否具备Makefile编程也从侧面说明了一个人是否具备做项目的基本能力。

二:关于程序的编译和链接


在程序编译中,无论是在C或者C++,首先要把源文件编译成一个中间代码文件,在windows下也就是.obj文件。
UNIX下也是.o文件,即Object File,这个动作叫做编译,然后再把大量的Object File 合成执行文件。
这个动作叫做链接。编译时候,编译器需要的是语法的正确,函数与变量的声明正确,对于后者,通常是
你需要告诉编译器头文件的所在位置,(头文件中应该是声明,定义放在C/C++文件中)只要所有的语法正确,
编译器就可以编译出中间目标文件,一般来说,每个源文件都应该对应一个中间目标文件(.o或者OBJ文件)
链接的时候,主要链接函数和全局变量,所以我们要使用这些中间目标文件来连接我们的应用程序,链接器
不管函数所在的源文件,只管函数的中间目标文件(Object file)在大多数时候,由于源文件太多,编译生成
的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件
打个包,在 Windows 下这种包叫“库文件”(Library File),也就是 .lib 文件,在 UNIX
下,是 Archive File,也就是 .a 文件。 
总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译
时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出
一个警告,但可以生成 Object File。而在链接程序时,链接器会在所有的 Object File 中
找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在 VC 下,这种错
误一般是:Link 2001 错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的
Object File.


三:简单的Makefile

简单的Makefile语法格式:
方式1:
        标签1:
                指令1
        标签2:
                指令2

        例:
        all:
            gcc main.c -o app
        clean:
            rm app
 
执行Makefile :
在工程目录下直接执行make 就会在当前路径下找对应的Makefile文件执行
如果当前路径有多个Makefile文件时,Make —f makefile文件名,来执行
对应的makefile文件。


例2:   
      目标   依赖
        |     |
        app:main.o
            gcc main.o -o app
        main.o:main.s   //这种写法的main.o叫目标  是要生成对应的main.o文件的
            gcc -c main.s -o main.o
        main.s:main.i
            gcc -S main.i -o main.s
        main.i:main.c
            gcc -E main.c -o main.i

        clean:    //这种写法的clean 叫做伪目标,是不生成对应文件的
            rm app main.o main.i main.s

在执行make的时候,makefile会自动推导依赖关系。
app->main.o->main.s->main.i->main.c
所以最终的顺序是:
            

gcc -E main.c -o main.i
            gcc -S main.i -o main.s
            gcc -c main.s -o main.o
            gcc main.o -o app


这是最简单的makefile格式,已经实现了自动编译的流程,但是看起来可能很low,
所以我们可以用一些makefile中的变量去替换一下,让他们变得更加简洁。

四:Makefile中的变量

Makefile可以使用变量,让它变得更加精简。
使用的变量和方式基本和shell脚本一样。
如:
    $() 引用变量。
        Makefile中变量赋值的问题:
        =  :会将变量在Makefile中所有的赋值都找到
           :将最后一次赋值的结果赋值给新的变量
        .eg:
            var=abc
            var1=$(var)
            var=def

            #@表示取消命令执行的回显
            all:
                @echo $(var)    #def
                @echo $(var1)   #def                                                             

        :=  :立即赋值
            .eg:
            var2:=abc
            var3:=$(var2)
            var2:=def    
            #@表示取消命令执行的回显
            all:                                                       
                @echo $(var2)  #def
                @echo $(var3)  #abc

        +=  附加赋值
            var4=abc
            var4+=def
            all:
                @echo $(var4)  #abc def

        ?= 询问?前的变量之前是否被赋值过,如果被赋值过
           本次赋值不成立,否者本次赋值成立
           var5=www.hqyj.com
           var5 ?=www.farsight.com
           all:
               @echo $(var5) #www.csdn.com

Makefile中的特殊变量:
    $@  :目标文件
    $^  :所有的依赖文件
    $<  :第一个依赖文件

Makefile中的通配符:
% :在makefile中代表任意长度的的字符。
* :在引用shell命令的时候代表shell中的通配符。

Makefile引用文件:
        -include 路径/文件名

    
所以我们的Makefile根据特殊变量的优化版本就是:

OBJ=main.o func1.o func2.o func3.o 
INCLUDE= -I ../include 
CC=gcc
FLAG= -c -o
 
app:$(OBJ)
    $(CC) $(OBJ) $(INCLUDE) -o $@
%.o%.cabs
    $(CC)$^ $(INCLUDE) $(FLAG) =$@
    
clean:
    rm $(OBJ)
 
        


    rm $(OBJ)
 
        

    


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值