您的位置:首页 > 其它

多文件夹下的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如下:
../$(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命令,还是可以看懂整个流程,不过说实在的,要是真正让我写的话,我还是写不出来,只能对照着例子来写。不过我想这样子的程序应该就够了,毕竟用的时候是可以查找资料的。模仿的功力还是得学的~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息