最近在做一个项目时对makefile有了一个简单的认识,于是自己写了一个简单的编译框架,留待后用。下边是一个demo示例,附上所有的源文件,移植工程时搬过来应该就可以用了。
-
├── app
-
│ ├── api
-
│ │ ├── api.c
-
│ │ └── Makefile
-
│ ├── include
-
│ │ └── app.h
-
│ ├── Makefile
-
│ └── src
-
│ ├── app.c
-
│ └── Makefile
-
├── main
-
│ ├── include
-
│ │ └── main.h
-
│ ├── Makefile
-
│ └── src
-
│ ├── main.c
-
│ └── Makefile
-
├── Makefile
-
├── make.rules
-
│ ├── config.in
-
│ ├── make.obj
-
│ ├── make.src
-
│ └── rules.mk
-
└── sdk
-
├── Makefile
-
├── sdk1
-
│ ├── include
-
│ │ └── sdk1.h
-
│ ├── Makefile
-
│ └── src
-
│ ├── Makefile
-
│ ├── sdk1_1.cpp
-
│ └── sdk1_2.c
-
└── sdk2
-
├── Makefile
-
├── sdk2_1
-
│ ├── include
-
│ │ └── sdk2_1.h
-
│ ├── Makefile
-
│ └── src
-
│ ├── Makefile
-
│ └── sdk2_1.c
-
└── sdk2_2
-
├── include
-
│ └── sdk2_2.h
-
├── Makefile
-
└── src
-
├── Makefile
-
└── sdk2_2.c
二、使用说明
1.编译帮助,在主目录中输入make help,可以得到编译的帮助信息。
2.user_debug目标是留给用户打印变量使用的。只要在该目标下调用$(call PRINT,变量),就能在执行makefile时打印出指定的变量的值。编译时需要指明打印等级,0-打印所有变量,1-打印内部变量,2-打印用户定义的变量。只打印用户变量使用make all DEBUG_LEVEL=2。
3.user_clean目标是留给用户做清理工作的,在make clean之前会调用到。
4.user目标是留给用户编译时使用的。比如可以在编译完成之后自动清理掉生成的不需要的.o文件,可以直接在user后边加上一个依赖clean。
5.主目录中编译整个工程直接使用make all,只清理.o和可执行文件使用make clean,清理掉所有生成的文件使用make distclean。也可以指定单个目录进行编译,比如make –C app就会只编译app目录,make –C app clean就会单独清理掉app目录。
6.非主目录编译需要先在主目录中成功make all一次,只有生成了配置文件rules.conf才能找到编译时需要依赖的规则文件。所以要在非主目录中编译,不能使用make distclean命令。在非主目录中编译直接使用make 就可以了,清理使用make clean,打印变量使用make DEBUG_LEVEL=2。
三、编译框架说明
1. 整个编译过程用到了三种makefile文件。
(1)第一种是将各个子目录中的.o文件链接成一个.o目标文件。如下,./sdk/Makefile文件。
-
# 需要编译的子目录
-
obj-y = sdk1
-
obj-y += sdk2
-
-
# 编译所需参数
-
# EXTRA_LDFLAGS:链接时需要的参数
-
EXTRA_LDFLAGS =
-
-
# 加载make.obj文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
user_debug:
-
$(call PRINT,MAKE_OBJ)
这个makefile几乎不用修改任何地方,除了必须指定需要编译的子目录obj-y。其中的所有链接工作是在./make.rules/make.obj文件中完成的。
(2)第二种是将子目录中的源文件编译成.o文件,然后将所有.o文件连接成一个目标.o文件。如下,./sdk/sdk1/Makefile文件。
-
# 目标文件夹
-
src-y = src
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS += -I$(CURR_DIR)/include
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
-
user_debug:
-
$(call PRINT,CURR_DIR)
这个文件需要指定源文件目录src-y和需要编译的源文件类型source_type,还有编译的头文件目录。其主要编译规则在./make.rules/make.src中。
(3)第三种makefile是在源文件中,主要是用来进行清理工作的,比如./sdk/sdk1/src/Makefile,如下
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
2. 关于./make.rules目录中的规则或配置文件。
config.in:提供编译时需要的全局变量,比如make.rules的位置,环境变量,编译工具链,一些通用的编译参数。
rules.mk: 提供具体的编译规则,打印函数,打印等级,打印颜色。
make.obj: 将多个.o文件连接成一个.o文件。
make.src: 将源文件编译成.o文件,并链接成一个.o文件。
四、一些实现细节
1. 打印函数
-
PRINT = @echo -e "$(BABYBLUECOLOR)$(1): $($(1)) $(ENDCOLOR)\n";
-
$(call PRINT,变量)
使用call会将PRINT视为一个函数调用,而后边的变量则视为函数的参数。$(1)变量的名称,$($(1))变量中的内容。
2. 自动编译,彩色警告和错误,去掉c中的__FILE__的绝对路径
-
COLORING=sed -e "s/[Ee]rror[: ]/$(CCERROR)\0$(CCEND)/g" -e "s/[Ww]arning[: ]/$(CCWARNING)\0$(CCEND)/g"
-
%.o: %.c
-
$(CC) $(EXTRA_CFLAGS) $(CFLAGS) -MD -c $< -o $@ -D__NOTDIR_FILE__=$(notdir $<) 2>&1 | $(COLORING)
%.o: %c是一种指定泛型的目标与依赖方式,在同一个makefile中,只要其他目标有依赖后缀为.o目标,那么执行到该目标时,就会执行%.o: %.c。这时-D__NOTDIR_FILE__=$(notdir
$<)中的$<就代表源文件的路径,它可能和源文件名一样,也可能在文件名前边带了路径,所以使用$(notdir $<)
可以除掉路径,只留下文件名。那么这里为何要定义一个-D__NOTDIR_FILE__的宏呢,因为如果这里的$<带了路径,那么__FILE__宏一定带有路径,我想很多人在打印文件名时也遇到过这样的问题,只是没有深究。因此,在打印文件名时就可以直接使用__NOTDIR_FILE__宏了,而不使用__FILE__宏。为何不直接替换掉__FILE__的内容,因为__FILE__是gcc自带的内部定义宏,尽量不要修改。还有一种方法是调用basename(__FILE__)函数,这样可以得到不带路径的文件名,但是没有前一种高效,因为每次打印都要调用一次basename函数。
关于彩色警告和错误的打印其实就是使用sed在打印的字符串前后加了颜色编码。
3. 循环函数
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) clean || exit "$$?";)
Makefile中可以直接调用foreach循环函数,例如上边的dir,循环一次就会从SUBDIRS中取出下一个值,然后在执行的shell代码中使用该值。
4. 遇到错误后停止编译,直接退出
-
$(LD) -r $(EXTRA_LDFLAGS) -o $(MODULE) $(SUB_OBJS) || exit "$$?"
在shell命令后直接加上一句|| exit "$$?,执行失败立即退出。
5. VPATH变量
这个变量会指定编译时寻找的目录,如果当前目录没有要找的文件,那么就会跳到VPATH指定的路径下边去查找。
五、demo中所有的文件
./app/api/api.c
-
#include <stdio.h>
-
-
void api_print(void)
-
{
-
DEBUG_1("api.c\n");
-
}
./app/api/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./app/include/app.h
-
#ifndef APP_H
-
#define APP_H
-
-
#ifdef __NOTDIR_FILE__
-
#define M2STR(x) #x
-
#define M2STR_IMPL(x) M2STR(x)
-
#define __BFILE__ M2STR_IMPL(__NOTDIR_FILE__)
-
#else
-
#define __BFILE__ __FILE__
-
#endif
-
-
#define LIGHT_BLUE "\033[1;34m"
-
#define FMT_NONE "\033[m"
-
-
#if 1
-
#define DEBUG(fmt, arg...) do { \
-
fprintf(stdout, "[ %s ] [ %d ] [ %s ]:" \
-
LIGHT_BLUE fmt FMT_NONE, __BFILE__, __LINE__, __FUNCTION__, ##arg); \
-
} while(0)
-
-
#define DEBUG_1(fmt, arg...) do { \
-
fprintf(stdout, "[ %s ] [ %d ] [ %s ]:" \
-
LIGHT_BLUE fmt FMT_NONE, __FILE__, __LINE__, __FUNCTION__, ##arg); \
-
} while(0)
-
-
#else
-
#define DEBUG(fmt, arg...)
-
#endif
-
-
#endif
./app/Makefile
-
# 目标文件夹
-
src-y = src
-
src-y += api
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS +=
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
-
user_debug:
-
$(call PRINT,CURR_DIR)
./app/src/app.c
-
#include "app.h"
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
void app_print(void)
-
{
-
DEBUG("app.c\n");
-
}
./app/src/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./main/include/main.h
-
#ifndef MAIN_H
-
#define MAIN_H
-
-
#endif
./main/Makefile
-
# 目标文件夹
-
src-y = src
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS +=
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
-
user_debug:
-
$(call PRINT,CURR_DIR)
./main/src/main.c
-
#include "main.h"
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
int main()
-
{
-
api_print();
-
app_print();
-
sdk1_1_print();
-
sdk1_2_print();
-
sdk2_1_print();
-
sdk2_2_print();
-
return 0;
-
}
./main/src/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./make.rules/config.in
-
# 编译规则的文件路径
-
# MAKE_RULES:编译规则路径
-
-
MAKE_RULES := $(shell pwd)/make.rules
-
export MAKE_RULES
-
-
# 环境变量添加编译工具链路径
-
PATH := /usr/local/bin:$(PATH)
-
export PATH
-
-
# 指定编译工具名称
-
# CROSS_COMPILE:不同平台的交叉编译工具的前缀
-
CROSS_COMPILE :=
-
-
export AS = $(CROSS_COMPILE)as
-
export LD = $(CROSS_COMPILE)ld
-
export CC = $(CROSS_COMPILE)gcc
-
export CPP = $(CROSS_COMPILE)g++
-
export AR = $(CROSS_COMPILE)ar
-
export NM = $(CROSS_COMPILE)nm
-
export STRIP = $(CROSS_COMPILE)strip
-
export OBJCOPY = $(CROSS_COMPILE)objcopy
-
export OBJDUMP = $(CROSS_COMPILE)objdump
-
export RANLIB = $(CROSS_COMPILE)ranlib
-
-
# c c++ 编译的通用编译参数
-
COMMON_CFLAGS :=
-
COMMON_CXXFLAGS :=
-
-
export CFLAGS += $(COMMON_CFLAGS)
-
export CXXFLAGS += $(COMMON_CXXFLAGS)
-
-
# 打印帮助信息
-
help:
-
@echo "Usage: make [ target ] [ DEBUG_LEVEL = 0,1,2 ]"
-
@echo "Compile a project."
-
@echo "The following targets are support:"
-
@echo
-
@echo " all - compile and link"
-
@echo " clean - clean target"
-
@echo " distclean - clean target and otherinformation"
-
@echo " DEBUG_LEVEL LEVEL - print the variable, LEVEL can be 0, 1, 2"
-
@echo " -- 0 print all of the variables"
-
@echo " -- 1 print the debug variables"
-
@echo " -- 2 print the user_debug variables"
-
@echo " help - print help information"
-
@echo
-
@echo "To compile an entire project, do 'make all'"
./make.rules/make.obj
-
# 加载rules.mk文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/rules.mk
-
endif
-
-
# 编译子目录
-
SUBDIRS = $(obj-y)
-
-
# 目标
-
# MODULE:最终生成的目标
-
# SUB_OBJS:链接时需要用到的子目标
-
SUB_OBJS = $(join $(SUBDIRS), $(patsubst %, /obj-%.o, $(SUBDIRS)))
-
MODULE = obj-$(shell pwd | sed "s/.*\///" ).o
-
-
# 编译入口
-
all: $(DEBUG_TAG) $(MODULE) user msg_done save_env
-
-
# 编译生成目标
-
$(MODULE): subdir
-
$(LD) -r $(EXTRA_LDFLAGS) -o $@ $(SUB_OBJS)
-
-
# 编译子目录
-
subdir:
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) || exit "$$?";)
-
-
# 循环清除下一级目录的所有生成文件
-
clean: user_clean
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) clean || exit "$$?";)
-
rm -rf *.[od]
-
-
# 清除当前和下一级目录生成的文件
-
distclean:
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) distclean || exit "$$?";)
-
rm -rf *.[od] rules.conf
-
-
# 保存一些环境变量
-
# MAKE_RULES: 保存make规则文件的路径
-
save_env:
-
@if [ ! -f ./rules.conf ]; then \
-
if [ -n "${MAKE_RULES}" ]; then \
-
echo "MAKE_RULES=${MAKE_RULES}" > ./rules.conf; \
-
fi \
-
fi
-
-
# 编译完成打印
-
msg_done:
-
$(call PRINT_DONE,MODULE)
-
-
# 打印内部变量
-
debug:
-
$(call PRINT_IN,SUBDIRS)
-
$(call PRINT_IN,MODULE)
-
$(call PRINT_IN,SUB_OBJS)
-
$(call PRINT_IN,DEBUG_TAG)
-
$(call PRINT_IN,EXTRA_LDFLAGS)
./make.rules/make.src
-
# 加载rules.mk文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/rules.mk
-
endif
-
-
# 路径
-
# CURR_DIR:当前路径
-
# SUBDIRS:源文件路径
-
# VPATH:指定源文件搜索路径到路径SUBDIRS中
-
CURR_DIR = $(shell pwd)
-
SUBDIRS = $(src-y)
-
VPATH = $(patsubst %,$(CURR_DIR)/%, $(SUBDIRS))
-
-
# 目标
-
# MODULE: 最终生成的.o目标
-
# SUB_OBJS: 源文件生成的.o目标
-
MODULE = obj-$(shell pwd | sed "s/.*\///" ).o
-
find_source_objs = $(subst $(type),.o,$(wildcard $(patsubst %,%/*$(type), $(SUBDIRS))))
-
SUB_OBJS = $(foreach type,$(source_type),$(find_source_objs))
-
-
# 编译入口
-
all: $(DEBUG_TAG) $(MODULE) user msg_done save_env
-
-
# 编译
-
$(MODULE): $(SUB_OBJS)
-
$(LD) -r $(EXTRA_LDFLAGS) -o $(MODULE) $(SUB_OBJS) || exit "$$?"
-
-
# 循环清除下一级目录的所有生成文件
-
clean: user_clean
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) clean || exit "$$?";)
-
rm -rf *.[od]
-
-
# 清除当前和下一级目录生成的文件
-
distclean:
-
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) distclean || exit "$$?";)
-
rm -rf *.[od] rules.conf
-
-
# 保存一些环境变量
-
# MAKE_RULES: 保存make规则文件的路径
-
save_env:
-
@if [ ! -f ./rules.conf ]; then \
-
if [ -n "${MAKE_RULES}" ]; then \
-
echo "MAKE_RULES=${MAKE_RULES}" > ./rules.conf; \
-
fi \
-
fi
-
-
# 编译完成打印
-
msg_done:
-
$(call PRINT_DONE,MODULE)
-
-
# 打印内部变量
-
debug:
-
$(call PRINT_IN,CURR_DIR)
-
$(call PRINT_IN,SUBDIRS)
-
$(call PRINT_IN,VPATH)
-
$(call PRINT_IN,MODULE)
-
$(call PRINT_IN,SUB_OBJS)
-
$(call PRINT_IN,DEBUG_TAG)
-
$(call PRINT_IN,EXTRA_LDFLAGS)
-
$(call PRINT_IN,EXTRA_CFLAGS)
-
$(call PRINT_IN,EXTRA_CXXFLAGS)
-
$(call PRINT_IN,CFLAGS)
-
$(call PRINT_IN,CXXFLAGS)
./make.rules/rules.mk
-
# 定义打印色彩值
-
REDCOLOR=\033[31m
-
GREENCOLOR=\033[32m
-
BROWNCOLOR=\033[33m
-
BLUECOLOR=\033[34m
-
PURPLECOLOR=\033[35m
-
BABYBLUECOLOR=\033[34;1m
-
WHITECOLOR=\033[37;1m
-
YELLOWCOLOR=\033[32;1m
-
ENDCOLOR=\033[0m
-
-
# 编译时警告和错误添加颜色和闪烁
-
CCDONE=$$(echo -e "\033[5;33m")
-
CCERROR=$$(echo -e "\033[5;31m")
-
CCWARNING=$$(echo -e "\033[1;35m\033[5m")
-
CCEND=$$(echo -e "\033[0m")
-
COLORING=sed -e "s/[Ee]rror[: ]/$(CCERROR)\0$(CCEND)/g" -e "s/[Ww]arning[: ]/$(CCWARNING)\0$(CCEND)/g"
-
-
# 编译源文件为.o和.d文件
-
%.o: %.c
-
$(CC) $(EXTRA_CFLAGS) $(CFLAGS) -MD -c $< -o $@ -D__NOTDIR_FILE__=$(notdir $<) 2>&1 | $(COLORING)
-
-
%.o: %.cpp
-
$(CPP) $(EXTRA_CXXFLAGS) $(CXXFLAGS) -MD -c $< -o $@ -D__NOTDIR_FILE__=$(notdir $<) 2>&1 | $(COLORING)
-
-
# 打印变量
-
# PRINT: 用户(user_debug)打印函数
-
# PRINT_IN: 内部(debug)打印函数
-
# PRINT_DONE: 编译目标完成时的打印,有闪烁
-
-
PRINT = @echo -e "$(BABYBLUECOLOR)$(1): $($(1)) $(ENDCOLOR)\n";
-
PRINT_IN = @echo -e "$(GREENCOLOR)$(1): $($(1)) $(ENDCOLOR)\n";
-
PRINT_DONE = @echo -e "$(CCDONE) make $($(1)) done $(ENDCOLOR)\n";
-
-
# 打印等级
-
# DEBUG_LEVEL: 打印等级,0表示打印用户和系统变量,1表示打印系统变量,2表示打印用户变量
-
-
ifdef DEBUG_LEVEL
-
ifeq ($(DEBUG_LEVEL), 0)
-
DEBUG_TAG = debug user_debug
-
endif
-
-
ifeq ($(DEBUG_LEVEL), 1)
-
DEBUG_TAG = debug
-
endif
-
-
ifeq ($(DEBUG_LEVEL), 2)
-
DEBUG_TAG = user_debug
-
endif
-
endif
-
-
.PHONY: debug user_debug clean distclean user help
./sdk/Makefile
-
# 需要编译的子目录
-
obj-y = sdk1
-
obj-y += sdk2
-
-
# 编译所需参数
-
# EXTRA_LDFLAGS:链接时需要的参数
-
EXTRA_LDFLAGS =
-
-
# 加载make.obj文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
user_debug:
-
$(call PRINT,MAKE_OBJ)
./sdk/sdk1/include/sdk_1.h
-
#ifndef SDK1_H
-
#define SDK1_H
-
-
-
#endif
./sdk/sdk1/Makefile
-
# 目标文件夹
-
src-y = src
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS += -I$(CURR_DIR)/include
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
-
user_debug:
-
$(call PRINT,CURR_DIR)
./sdk/sdk1/src/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./sdk/sdk1/src/sdk1_1.cpp
-
#include "sdk1.h"
-
#include <stdio.h>
-
-
extern "C" void sdk1_1_print(void)
-
{
-
printf("sdk1_1.cpp\n");
-
}
./sdk/sdk1/src/sdk1_2.c
-
#include "sdk1.h"
-
#include <stdio.h>
-
-
void sdk1_2_print(void)
-
{
-
printf("sdk1_2.c\n");
-
}
./sdk/sdk2/Makefile
-
# 编译子目录
-
obj-y = sdk2_1
-
obj-y += sdk2_2
-
SUBDIRS = $(obj-y)
-
-
# 编译所需参数
-
# EXTRA_LDFLAGS:链接时需要的参数
-
EXTRA_LDFLAGS =
-
-
# 加载make.obj文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.obj
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
user_debug:
-
$(call PRINT,MAKE_OBJ)
./sdk/sdk2/sdk2_1/include/sdk2_1.h
-
#ifndef SDK2_1_H
-
#define SDK2_1_H
-
-
-
#endif
./sdk/sdk2/sdk2_1/Makefile
-
# 目标文件夹
-
src-y = src
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS +=
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
user_debug:
-
$(call PRINT,CURR_DIR)
-
$(call PRINT,VPATH)
-
$(call PRINT,SUB_OBJS)
./sdk/sdk2/sdk2_1/src/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./sdk/sdk2/sdk2_1/src/sdk2_1.c
-
#include "sdk2_1.h"
-
#include <stdio.h>
-
-
void sdk2_1_print(void)
-
{
-
printf("sdk2_1.c\n");
-
}
./sdk/sdk2/sdk2_2/include/sdk2_2.h
-
#ifndef SDK2_2_H
-
#define SDK2_2_H
-
-
-
#endif
./sdk/sdk2/sdk2_2/Makefile
-
# 目标文件夹
-
src-y = src
-
-
# 目标文件类型
-
source_type = .cpp .c
-
-
# 编译所需参数
-
# EXTRA_CFLAGS:c编译参数
-
# EXTRA_CXXFLAGS:cpp编译参数
-
# EXTRA_LDFLAGS:链接成目标.o时的参数
-
EXTRA_CFLAGS += -I$(CURR_DIR)/include
-
EXTRA_CXXFLAGS +=
-
EXTRA_LDFLAGS =
-
-
# 加载make.src文件
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
else
-
include ./rules.conf
-
ifdef MAKE_RULES
-
include $(MAKE_RULES)/make.src
-
endif
-
endif
-
-
# 用户编译配置处
-
# clean: 清除掉源文件生成的目标文件
-
# distclean: 清除当前和子目录所有的目标文件
-
# 编译时在这里可以做其它事情
-
user:
-
-
# 用户清理
-
user_clean:
-
-
# 打印变量
-
# $(call PRINT,变量):调用该函数可以打印编译时变量的值,该函数定义在rules.mk文件中
-
# DEBUG_LEVEL = 2时,才会有打印
-
user_debug:
-
$(call PRINT,CURR_DIR)
./sdk/sdk2/sdk2_2/src/Makefile
-
clean:
-
rm -rf *.[od]
-
-
distclean: clean
-
-
.PHONY: clean distclean
./sdk/sdk2/sdk2_2/src/sdk2_2.c
-
#include "sdk2_2.h"
-
#include <stdio.h>
-
-
void sdk2_2_print(void)
-
{
-
printf("sdk2_2.c\n");
-
}