Makefile简介

总流程:
可执行文件生成过程: .c --> .o --> .exe
当有多个.c时,需要进行打包处理,则:  .c(多个) --> .o (多个)--> .a --> .exe

详细步骤:
1.  读入所有的Makefile。
2.  读入被include的其它Makefile。
3.  初始化文件中的变量。
4.  推导隐晦规则,并分析所有规则。
5.  为所有的目标文件创建依赖关系链。
6.  根据依赖关系,决定哪些目标要重新生成。
7.  执行生成命令。

目标文件依赖
格式: 目标文件 :所依赖文件1 所依赖文件2 ...
如:target... : prerequisites ...         
    command
     ...
target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

变量定义: $
格式:  变量: $(被定义的内容),且变量可以累加,
如:
CFLAGS += -I../PUB/include
CFLAGS += -I../PUB/include/libxml

make 自动推导
GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来
utils.o : utils.c defs.h

           cc -c utils.c
可以省略去   cc -c utils.c ,而 简写成 utils.o : defs.h


makefile 文件名
默认情况下,makefile文件命名为makefile或者Makefile, 也可以使用其他名字,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“--file”参数,如:make -f Make.Linux或make --file Make.AIX。

makefile间互相引用
在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。include的语法是:
include<filename>
filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符),在include前面可以有一些空字符,但是绝不能是[Tab]键开始。include和可以用一个或多个空格隔开。

通配符
" ~ "   波浪号(“~”)字符在文件名中也有比较特殊的用途。如果是“~/test”,这就表示当前用户的$HOME目录下的test目录
" * "   通配符代替了你一系列的文件,如“*.c”表示所以后缀为c的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符“\”,如“\*”来表示真实的“*”字符,而不是任意长度的字符串。

$(patsubst %.c,%.o,$(wildcard *.c ./sub/*.c) )     
patsubst表示替换,wildcard表示通配符,整个含义即是将当前目录所有.c文件和sub目录所有.c文件替换为.o文件

三种常用变量: $@,$^,$<  
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:
# 这是简化后的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
gcc -c $<
mytool1.o:mytool1.c mytool1.h
gcc -c $<
mytool2.o:mytool2.c mytool2.h
gcc -c $<
经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点。这里我们学习一个Makefile的缺省规则
.c.o:
gcc -c $<
这个规则表示所有的 .o文件都是依赖与相应的.c文件的。例如mytool.o依赖于mytool.c这样Makefile还可以变为:
.c.o:
gcc -c $<

伪目标
clean:
           rm *.o temp
我们生成了许多文件编译文件,我们也应该提供一个清除它们的“目标”以备完整地重编译而用。 (以“make clean”来使用该目标)
因为,我们并不生成“clean”这个文件。“伪目标”并不是一个文件,只是一个标签,由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有通过显示地指明这个“目标”才能让其生效。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。
当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。
   .PHONY : clean
只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样。于是整个过程可以这样写:
    .PHONY: clean
   clean:
           rm *.o temp
其他伪目标:
“all” 这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
 “install” 这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
  "print” 这个伪目标的功能是例出改变过的源文件。
“tar” 这个伪目标功能是把源程序打包备份。也就是一个tar文件。
“dist” 这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。

文件搜索
在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。
VPATH = src:../headers  
vpath < pattern> < directories>    为符合模式< pattern>的文件指定搜索目录<directories>。

Makefile 使用总结    ===  http://www.cnblogs.com/wang_yb/p/3990952.html
Makefile常用万能模板(包括静态链接库、动态链接库、可执行文件)===  https://www.cnblogs.com/cyyljw/p/8137015.html

######################################
#
######################################
#source file
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
OBJS    := $(patsubst %.c,%.o,$(wildcard *.c))
  
#target you can change test to what you want
#目标文件名,输入任意你想要的执行文件名
TARGET  := test
  
#compile and lib parameter
#编译参数
CC      := gcc
LIBS    := -lpthread -lxml
LDFLAGS := -L../pub/debug
DEFINES := -D_PRODUCT_VERSION=\"2018.05.06"\
INCLUDE := -I../pub/inc -I./inc
CFLAGS  := -g -Wall -fno-strict-aliasing -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS)  
    
#i think you should do anything here
#下面的基本上不需要做任何改动了
  
all : $(TARGET)
  
clean :
    rm -fr *.o
    
 $(TARGET) : $(OBJS)
    $(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
	
#交叉编译
ifdef powerpc
	CC: = /opt/powerpc-linux-gnu-gcc
endif

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值