复杂多⽬录的Makefile模板及⽰例
⼤约⼀年多以前,还在移植u-boot,当时参考了u-boot的Makefile,做了⼀个多⽬录的Makefile模板。如今,⼀年过去了,本篇⽂章还是折腾Makefile模板,本⼈的⽔平由此可见⼀斑。当时的模板没有考虑很多东西,⽐如将源代码⽂件及⽬标⽂件分离。此次再写⼀个相对复杂的Makefile模板,⾃此之后,估计不想再折腾了。
本⽂的Makefile跟以往的模板⼀样,都是参考u-boot的做法(u-boot项⽬⽆论代码还是⽂件组织,都有很多值得学习的地⽅)。由下列⽂件组成:
1、配置⽂件config.mk,主要是编译器、编译选项、头⽂件路径、⽬标⽂件、源⽂件路径,等等;
2、依赖规则rules.mk,主要是产⽣depend⽂件,有了depend⽂件,当修改了头⽂件后,包含该头⽂件的源⽂件都会被重新编译。
3、主Makefile,或称为总Makefile,此⽂件调⽤其它⽬录的Makefile以及上述⽂件,以产⽣库及可执⾏⽂件。
4、⼦⽬录Makefile,各模块的Makefile,主要是⽣成静态库。
除⼦⽬录Makefile在各个模块⽬录中外,其它⽂件都在项⽬的当前⽬录。
Makefile模板应⽤场合及特点缺点说明如下:
1、头⽂件统⼀在include⽬录(或其它⾃定义的⽬录),⼦模块分布于各⼦⽬录,该⽬录的Makefile将模块编译成静态库,主代码(包括main 函数及其它的代码)⽂件在独⽴⽬录,该⽬录的Makefile为总Makefile(或称主Makefile)。
2、修改头⽂件后,所有依赖该⽂件者均重新编译。
3、可指定编译后的⽂件所在⽬录,如不指定,则在原⽬录下⽣成⽬标⽂件(.o、.out⽂件)。指定⽅式如下:
1)、命令⾏:$ make O=../build
2)、$ export BUILD_DIR=../build ; make
3)、直接在主Makefile指定⽬录
4、⾃动识别编译C、C++⽂件。
下⾯分别解释⼀下各个⽂件
1、配置⽂件config.mk
模板如下:
#
# (C) Copyleft 2011
# Late Lee from
#
# A simple file to specify compier and macros and flags
# and ways to compile .c & .cpp
#
#
CROSS_COMPILE =
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
ARFLAGS = cr
RM = -rm -rf
MAKE = make
CFLAGS = #-Wall
debug = y
ifeq ( $(debug), y)
CFLAGS += -g
else
CFLAGS += -O2 -s
CFLAGS += -O2 -s
endif
DEFS =
CFLAGS += $(DEFS)
LDFLAGS = $(LIBS)
# include path here
INCDIRS = $(SRCTREE)/./include/
CFLAGS += -I $(INCDIRS)
>>>>>>>>>>>>>>>####
ifneq ( $(OBJTREE), $(SRCTREE))
ifeq ( $(CURDIR), $(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,, $(CURDIR))
endif
obj := $( if$(dir), $(OBJTREE)/ $(dir)/, $(OBJTREE)/)
src := $( if$(dir), $(SRCTREE)/ $(dir)/, $(SRCTREE)/)
$(shell mkdir -p $(obj))
else
obj :=
src :=
endif
suffix = $(notdir $(CURDIR))
makefile phonyexport suffix
# test of shell script
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
# export to other Makefile
export CC
export CFLAGS
export INCDIRS
export AR
export ARFLAGS
export RM
>>>>>>>>>>>>>>>####
# make all .c or .cpp
$(obj)%.o: %.c
@echo"Compling: " $(addsuffix .c, $(basename $(notdir $@)))
@ $(CC)$(CFLAGS) -c $< -o $@
$(obj)%.o: %.cpp
@echo"Compling: " $(addsuffix .cpp, $(basename $(notdir $@)))
@ $(CXX)$(CFLAGS) -c $< -o $@
主要分3部分:
第⼀部分指定编译器及编译选项,可以选择交叉编译器,头⽂件路径由INCDIRS 宏指定,这⾥有的编译选项CFLAGS处理得不太好,⽐如debug版本及release版本是通过“-g”和“-O2 -s”来区别的,但这⾥是直接指定,并不能在make时指定。
第⼆部分指定了源代码⽬录及⽬标⽂件⽬录,这些⽬录由主Makefile给出,或者在make时给出。
第三部分是编译c或c++源代码的规则。
实际使⽤中,此⽂件需要根据实际情况修改编译器及编译选项。
2、依赖规则rules.mk
内容如下:
#
# (C) Copyleft 2011
# Late Lee from
#
# A simple way to generate depend file(.depend) for .c & .cpp,
# so you change the head file, it will recompile the
# file(s) which include the head file.
#
_depend: $(obj).depend
$(obj).depend: $(SRCTREE)/config.mk $(SRC_C)$(SRC_CPP)
@rm -f $@
@for f in$(SRC_C); do \
g= `echo $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \
$(CC) -MM $(CFLAGS) -E -MQ $(obj)$ $g $ $f >> $@ ; \
done
@for f in$(SRC_CPP); do \
g= `echo $$f | sed -e 's/\(.*\)\...\w/\1.o/'`; \
$(CC) -MM $(CFLAGS) -E -MQ $(obj)$ $g $ $f >> $@ ; \
done
该⽂件主要是产⽣.depend依赖⽂件,依赖⽂件的作⽤在前⾯已经说过,此处不再提及。实际使⽤中,经⽂件⽆需修改。
3、主Makefile
内容如下:
#
# (C) Copyleft 2011
# Late Lee from
#
# A simple Makefile for multi-directory
# Most idea comes from U-boot project
#
# object file directory, eg
# $ make O=../build
# $ export BUILD_DIR=../build ; make
# or modify BUILD_DIR here
ifdef O
ifeq ( "$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ( $(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$( if$(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif# ifneq ($(BUILD_DIR),)
OBJTREE := $( if$(BUILD_DIR), $(BUILD_DIR), $(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
export TOPDIR SRCTREE OBJTREE
include $(TOPDIR)/config.mk
>>>>>>>>>>>>>>>#### # libs
### your libs here
LIBS :=
LIBS := $(addprefix $(obj), $(LIBS))
LDFLAGS = $(LIBS)
# source file(s), including c file(s) cpp file(s)
# you can also use $(wildcard *.c), etc.
### main source here
MAIN_DIR = #main/
SRC_C :=
SRC_CPP := $(wildcard $(MAIN_DIR)*.cpp)
$( if$(MAIN_DIR), $(shell mkdir -p $(addprefix $(obj), $(MAIN_DIR))),)
# object file(s)
OBJ_C := $(addprefix $(obj),$(patsubst %.c,%.o, $(SRC_C)))
OBJ_CPP := $(addprefix $(obj),$(patsubst %.cpp,%.o, $(SRC_CPP)))
# executable file here
target = $(obj)a.out
>>>>>>>>>>>>>>>#### all: config $(target)
config:
@ hello.h"
@ $(MKCONFIG)
$(target): $(LIBS) exe
exe: $(OBJ_CPP)
@echo"Generating " $(notdir $(target))
@echo"Generating " $(notdir $(target))
@ $(CXX)$(CFLAGS)$(OBJ_CPP) -o $(target)$(LIBS)
$(LIBS):
$(MAKE) -C $(dir $(subst $(obj),, $@))
clean:
@"
@ $(RM)$(target)
@ $(RM) hello.h
@find$(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*.o' -o -name '*.a' -o -name '*.exe' -o -name '.depend' \) -print \
| xargs rm -f
distclean:
@"
@ $(RM)$(target)
@ $(RM) hello.h
@find$(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*.o' -o -name '*.a' -o -name '*.exe' -o -name '.depend' \) -print \
| xargs rm -f
@ $(RM)$(obj)
.PHONY: all clean distclean $(LIBS) exe
该⽂件也可分为三部分。第⼀部分指定源代码⽬录及⽬标⽂件⽬录,第⼆部分指定了⼯程所需的静态库以及主代码所在⽬录,第三部分编译规则,包括make all,make clean,等等命令的规则。实际使⽤中,需要根据实际情况添加⼦模块静态库名称、主代码名称。
4、⼦⽬录Makefile
内容如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
makefile编写、GDB调试、so库文件生成
« 上一篇
Makefile编译生成多个可执行文件
下一篇 »
推荐文章
热门文章
-
随机森林算法的改进方法
2024-10-02 -
基于随机森林算法的风险预警模型研究
2024-10-02 -
Python中的随机森林算法详解
2024-10-02 -
随机森林发展历史
2024-10-02 -
如何使用随机森林进行时间序列数据模式识别(八)
2024-10-02 -
随机森林回归模型原理
2024-10-02 -
如何使用随机森林进行时间序列数据模式识别(六)
2024-10-02 -
如何使用随机森林进行时间序列数据预测(四)
2024-10-02 -
如何使用随机森林进行异常检测(六)
2024-10-02 -
随机森林算法和grandientboosting算法 -回复
2024-10-02 -
随机森林方法总结全面
2024-10-02 -
随机森林算法原理和步骤
2024-10-02 -
随机森林的原理
2024-10-02 -
随机森林 重要性
2024-10-02 -
随机森林算法
2024-10-02 -
机器学习中随机森林的原理
2024-10-02 -
随机森林算法原理
2024-10-02 -
使用计算机视觉技术进行动物识别的技巧
2024-10-02 -
基于crf命名实体识别实验总结
2024-10-02 -
transformer预测模型训练方法
2024-10-02
最新文章
-
随机森林算法介绍及R语言实现
2024-10-02 -
基于随机森林优化的神经网络算法在冬小麦产量预测中的应用研究_百度文 ...
2024-10-02 -
基于正则化贪心森林算法的情感分析方法研究
2024-10-02 -
随机森林算法和grandientboosting算法
2024-10-02 -
基于随机森林的图像分类算法研究
2024-10-02 -
随机森林结合直接正交信号校正的模型传递方法
2024-10-02
发表评论