Makefile的简单编写

当咱们的工程愈来愈大的之后,每次都使用命令编译显得很是的麻烦.因此咱们须要一个自动化编译的工具来帮助咱们编译.在咱们使用源码安装软件的时候都会有make,make install等操做,这个就是使用Makefile来进行自动化编译的工做的.shell

Makefile也是一个脚本文件和shell脚本很是的类似,可是也有不少的地方不同.工具

程序编译一般会有一下几个步骤,先是预编译,而后将C语言代码编译成汇编,而后在将汇编编译成二进制文件.o文件,而后将全部的.o文件链接起来就获得了可执行文件.xml

在编写Makefile时,咱们先将全部的c语言代码编译成二进制文件,而后将全部二进制文件连接起来.文档

和shell相似的,里面有变量,有命令,有循环,判断等语句,全部的命令都须要另起一行,并且开始必须是tab键(全部开头是tab键的行都会被认为是命令,哪怕不能执行),变量等必须顶行不能有空格等.源码

简单的Makefile格式(不涉及循环,选择等语句):自动化

TARGET... : PREREQUISITES...
  COMMAND编译

a:main.othread

  gcc -o main.o变量

main.o:main.cgcc

  gcc -c main.c

这样就是一个最简单的Makefile

固然咱们若是是文件多的话这样写就很是的麻烦,咱们就可使用 变量名 += .....来进行编辑,使用时直接$(变量名)来使用.(和shell同样)

咱们也经常会使用make clean的命令等,这个叫作伪目标,直接

clean:

  rm *.o

install:

  cp .. /bin

 

Makefile文件也能够应用其余的Makefile文件

include 文件名

 

在咱们写了.o文件名之后,当.o和.c文件是同名时,咱们也能够不用.c文件,make会自动查找同名的文件,例如%.o:%.c.

如下是一些自动化变量:

$@
表示规则的目标文件名。若是目标是一个文档文件(Linux中,通常称.a文件为文档文件,也称为静态库文件) ,那么它表明这个文档的文件名。在多目标模式规则中,它表明的是哪一个触发规则被执行的目标文件名。

$%
当规则的目标文件是一个静态库文件时,表明静态库的一个成员名。例如,规则的目标是 “foo.a(bar.o)” , 那么, “$%” 的值就为 “bar.o” , “$@” 的值为“foo.a” 。
若是目标不是静态库文件,其值为空。

$<
规则的第一个依赖文件名。 若是是一个目标文件使用隐含规则来重建, 则它表明由隐含规则加入的第一个依赖文件。

$?
全部比目标文件更新的依赖文件列表,空格分割。若是目标是静态库文件名,表明的是库成员(.o文件) 。

$^
规则的全部依赖文件列表,使用空格分隔。若是目标是静态库文件,它所表明的只能是全部库成员(.o文件)名。一个文件可重复的出如今目标的依赖中,变量“$^”只记录它的一次引用状况。就是说变量“$^”会去掉重复的依赖文件。

$+
相似“$^” ,可是它保留了依赖文件中重复出现的文件。主要用在程序连接时库的交叉引用场合。

$*
在模式规则和静态模式规则中,表明“茎” 。 “茎”是目标模式中“%”所表明的部分 (当文件名中存在目录时, “茎” 也包含目录 (斜杠以前) ) 。例如:文件“dir/a.foo.b” ,当目标的模式为“a.%.b”时,“$*”的值为“dir/a.foo” 。 “茎”对于构造相关文件名很是有用

 

如下是通常的简单的Makefile写法:

COBJS += main.o

#CFLAGS += -O2 -Wall -DDEBUG
CFLAGS += -I./

LDFLAGS += -lmxml -lpthread

CROSS_COMPILE ?=

CC = $(CROSS_COMPILE)gcc

TARGET = tag

all:$(TARGET)
$(TARGET):$(COBJS)
$(CC) -o $@ $^ $(LDFLAGS)

%.o:%.c $(CC) $(CFLAGS) -c -o $@ $^ $(LDFLAGS) .PHONY:cleanclean: rm -f $(COBJS)

相关文章
相关标签/搜索