多文件夹下的Makefile自动编译
2015-07-07 10:25
246 查看
很多时候我们可能会遇到这样的情况:要编译多个目录下的代码,然后要将中间文件和执行文件分别放到不同的文件夹下面。好吧,贴图的排版第一次用,将就看一下。下面的图是我练习用的一个项目文件结构图。其中bin用来存放最后生成的可执行文件,f1,f2分别是用到的两个模块(函数),而且两个文件夹下分别对应自己的Makefile编译文件,include包含的是头文件,main.c包含的是主函数,其对应文件夹下也有一个Makefile文件,而obj是用来存放中间文件。然后是根目录下有一个全局的Makefile编译文件。
我们通过在根目录下,键入make,系统会自动到main,f1,f2文件夹下去编译文件,最后将生成的可执行文件放到myapp下面。
下面我从根目录开始,重新回忆并记录下实现的过程。首先看下根目录下的Makefile。
#设置编译器
CC=gcc
#参考资料http://www.cnblogs.com/Shirlies/p/4282182.html
#debug文件夹里的makefile文件需要最后执行,
#所以这里需要执行的子目录要排除debug文件夹,
#这里使用awk排除了debug文件夹,读取剩下的文件夹
#SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "cur_dir") print $$9}')
SUBDIRS=f1 \
f2 \
main \
obj
OBJS=f1.o f2.o main.o
#最终bin文件的名字,可以更改为自己需要的
BIN=myapp
#bin文件所在的目录
BIN_DIR=bin
#目标文件所在的目录
OBJS_DIR=obj
#记住当前工程的根目录路径ROOT_DIR=$(shell pwd)
#获取当前目录下的c文件集,放在变量CUR_SOURCE中CUR_SOURCE=${wildcard *.c}
#将对应的c文件名转为o文件后放在下面的CUR_OBJS变量中CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
#将以下变量导出到子shell中,本次相当于导出到子目录下的makefile中
export CC OBJS BIN OBJS_DIR BIN_DIR
#注意这里的顺序,需要先执行CHECK_DIR最后才能是SUBDIRS
all:CHECK_DIR $(SUBDIRS)
CHECK_DIR:
#mkdir -p 可以一次生成多级目录
mkdir -p $(BIN_DIR)
#递归执行子目录下的makefile文件,这是递归执行的关键
$(SUBDIRS):ECHO
#直接去根目录下的其他目录下执行子makefile文件
make -C $@
ECHO:
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
@echo $(SUBDIRS)
@echo begin compile
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
#$(CUR_OBJS):%.o:%.c
# $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
clean:
@$(RM) $(OBJS_DIR)/*.o
@rm -rf $(BIN_DIR) f1文件夹下面的f1.c和Makefile分别如下:
f1.c如下:
#include "../include/myinclude.h"
void print_f1()
{
printf("Message from f1.c\n");
} Makefile如下:
f2.c如下:
#include "../include/myinclude.h"
void print_f2()
{
printf("Message from f2.c\n");
} Makefile如下:
include文件夹下面的头文件include.h如下:
main文件夹下面的文件.
main.c如下:
#include <stdio.h>
int main()
{
print_f1();
print_f2();
return 0;
}
Makefile如下:
感觉根据学过的一些shell命令,还是可以看懂整个流程,不过说实在的,要是真正让我写的话,我还是写不出来,只能对照着例子来写。不过我想这样子的程序应该就够了,毕竟用的时候是可以查找资料的。模仿的功力还是得学的~~
我们通过在根目录下,键入make,系统会自动到main,f1,f2文件夹下去编译文件,最后将生成的可执行文件放到myapp下面。
下面我从根目录开始,重新回忆并记录下实现的过程。首先看下根目录下的Makefile。
#设置编译器
CC=gcc
#参考资料http://www.cnblogs.com/Shirlies/p/4282182.html
#debug文件夹里的makefile文件需要最后执行,
#所以这里需要执行的子目录要排除debug文件夹,
#这里使用awk排除了debug文件夹,读取剩下的文件夹
#SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "cur_dir") print $$9}')
SUBDIRS=f1 \
f2 \
main \
obj
OBJS=f1.o f2.o main.o
#最终bin文件的名字,可以更改为自己需要的
BIN=myapp
#bin文件所在的目录
BIN_DIR=bin
#目标文件所在的目录
OBJS_DIR=obj
#记住当前工程的根目录路径ROOT_DIR=$(shell pwd)
#获取当前目录下的c文件集,放在变量CUR_SOURCE中CUR_SOURCE=${wildcard *.c}
#将对应的c文件名转为o文件后放在下面的CUR_OBJS变量中CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
#将以下变量导出到子shell中,本次相当于导出到子目录下的makefile中
export CC OBJS BIN OBJS_DIR BIN_DIR
#注意这里的顺序,需要先执行CHECK_DIR最后才能是SUBDIRS
all:CHECK_DIR $(SUBDIRS)
CHECK_DIR:
#mkdir -p 可以一次生成多级目录
mkdir -p $(BIN_DIR)
#递归执行子目录下的makefile文件,这是递归执行的关键
$(SUBDIRS):ECHO
#直接去根目录下的其他目录下执行子makefile文件
make -C $@
ECHO:
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
@echo $(SUBDIRS)
@echo begin compile
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
#$(CUR_OBJS):%.o:%.c
# $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
clean:
@$(RM) $(OBJS_DIR)/*.o
@rm -rf $(BIN_DIR) f1文件夹下面的f1.c和Makefile分别如下:
f1.c如下:
#include "../include/myinclude.h"
void print_f1()
{
printf("Message from f1.c\n");
} Makefile如下:
../$(OBJS_DIR)/f1.o:f1.c $(CC) -c $^ -o $@ #OBJS=f1.o f2.o main.o #$@ 表示规则中的目标文件集。 #$^ 所有的依赖目标的集合f2文件夹下类似:
f2.c如下:
#include "../include/myinclude.h"
void print_f2()
{
printf("Message from f2.c\n");
} Makefile如下:
../$(OBJS_DIR)/f2.o:f2.c $(CC) -c $^ -o $@
include文件夹下面的头文件include.h如下:
#ifndef _MY_INCLUDE_H_ #define _MY_INCLUDE_H_ #include <stdio.h> #endif
main文件夹下面的文件.
main.c如下:
#include <stdio.h>
int main()
{
print_f1();
print_f2();
return 0;
}
Makefile如下:
../$(OBJS_DIR)/main.o:main.c $(CC) -c $^ -o $@
感觉根据学过的一些shell命令,还是可以看懂整个流程,不过说实在的,要是真正让我写的话,我还是写不出来,只能对照着例子来写。不过我想这样子的程序应该就够了,毕竟用的时候是可以查找资料的。模仿的功力还是得学的~~
相关文章推荐
- Linux/Unix环境下的Make和Makefile详解
- Python实现生成简单的Makefile文件代码示例
- (转)自动生成 Makefile 的全过程详解
- u-boot的Makefile分析
- 关于linux模块驱动简单的Makefile
- 编译单个驱动的Makefile文件。
- makefile完全教程
- Linux内核Makefile文件
- Linux内核的Makefile
- Makefile 文件的相关知识(2)
- 使用AutoMake轻松生成Makefile
- 学习写 Makefile
- makefile之环境变量MAKEFILES
- 一起写 Makefile
- u-boot的Makefile分析435557749
- MakeFile详解
- Linux内核makefile解析
- linux 2.6内核makefile分析
- makefile经典实例
- Makefile详解(一)