快速使用makefile

来源:互联网 发布:linux文件复制命令 编辑:程序博客网 时间:2024/05/22 12:43

一个makefile模板

  在linux平台下,除去使用IDE软件进行开发项目,大部分的软件项目都是需要自己写makefile的。其实自从我使用linux平台进行c,c++的开发后,就没有再像windows上面的vs那样,让IDE工具帮助我组织代码结构以及编译环境了。一开始还怀恋工具软件的方便快捷,讨厌手动管理的麻烦。到后来就觉得当时的自己浅显无知。如今,从只在一个文件中做代码修改到独立做一个项目的makefile,终于感受到makefile的强大和方便之处。编写makefile可以帮助我们对代码组织结构,的理解,甚至阅读makefile也有此帮助。
   今天要说的不是谈论makefile的好处,而是给大家看一个比较通用的makefile模板。这个makefile模板可以方便的组织代码,库和目标文件。也许你在后面做项目开发时也可以用的上。

  makefile的语法规则这里不做详解,下面先放出一个模板。
  
  假如代码组织结构是下面这样的。

moduleA
  a.c
  a.h
moduleB
  b.c
  b.h
include
  common.h
  type.h
libs
  libxshare.so
  libystatic.a
Makefile
Readme.md

我们可以使用下面这样的makefile文件

.PHONY: all #CROSS_COMPILE = arm-linux-gnueabihf-VERSION = debugifeq ($(VERSION), debug)     DEBUG = -DDEBUG=1 -gelse    DEBUG = -O2endifCC = $(CROSS_COMPILE)gccCPP = $(CROSS_COMPILE)g++CFLAGS =-Wall  $(DEBUG) CXXFLAGS =-Wall  $(DEBUG)LDFLAGS = -lpthread -lxshare -L./libsSTATICFLAGS = ./libs/libystatic.aTARGET = target.outBUILDPATH=.SRCDIRS:=. \    moduleA \    moduleB SRCCS=$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))SRCCXXS=$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.cpp))SRCFILES=$(SRCCS) $(SRCCXXS)INCLUDES:=$(foreach dir,$(SRCDIRS),-I$(dir)) \    -Iinclude LIBOBJ=$(addprefix $(BUILDPATH)/, $(addsuffix .o, $(basename $(SRCFILES)))) all: $(TARGET)$(BUILDPATH)/%.o:%.c    $(CC) $(CFLAGS) ${INCLUDES} -o $@ -c $<$(BUILDPATH)/%.o:%.cpp    $(CPP) $(CXXFLAGS) ${INCLUDES} -o $@ -c $<$(TARGET):$(LIBOBJ)    $(CPP) $(LDFLAGS) -o $@ $^ $(STATICFLAGS)    @echo  "-----------------build OK-------------------"clean:    rm -f $(TARGET) $(LIBOBJ)install:    cp $(TARGET) ../$(TARGET)

从头开始说起这个makefile。
  .PHONY : all 定义一个伪目标,目标并非实际的文件名,有两种情况可以使用.PHONY目标:避免和同名文件冲突,改善性能。这里的这一行不是必需的。
  #CROSS_COMPILE = arm-linux-gnueabihf- 这里注释掉了,只是因为我工作的平台不一样,这里是编译器的前缀,一般也可以不需要。
  VERSION=debug 定义版本,方便release和debug版本的编译,比如是使用make VERSION=release 就不会用到“-g”参数了,版本的编译参数控制在下面ifeq那几行。
   “CC” “CPP” “CFLAGS” 是一些变量来控制make时候的执行命令。这个地方很容易理解,但也很重要。这里设置了gcc, g++这两种编译器,然后还设置了编译过程中的动态库和静态库。例如文件目录lib下面存放着库文件,这里设置参数让动态库libxshare.so 和静态库libystatic.a参与到编译过程中。
   SRCCS=$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)) 这里使用了makefile内置的控制函数, $(widldcard *.c) 列出目录下的.c文件。$(foreach var, list, body) 从list里面提取出每一个字符串,并将其赋值给var,然后执行body的动作 。这里就是遍历目录下的c文件。
   下面就是找到目录下的所有源文件,并根据依赖关系执行相应的命令了。还是记一下make脚本的内置符号,这符号真的很不人性,太容易忘。但是却非常方便,而且这样使用就对了,也不需要怎么记。
   $@ :target的名称
   $* :和target类似 只是不包含target的后缀
   $^ :所有先决条件名称,以空格(space)分隔,如果先决条件有重复,自动去重。
   $? :先决条件更新表,比如4个先决条件,更新了2个文件,就代表那两个文件,make是按文件更新时间来确定是否执行命令的嘛。
   $< :第一个先决条件名称。

  配置好各种变量参数,下面的内容都可以是一样的了,make install 什么的,可以安装自己的需要进行更改。
  

0 0
原创粉丝点击