下面是网上找到的,思路很不错,当然也无法满足所有的需求,我执行又修改了一套。解决了下面的方法存在的问题:每次编译都是全编译的问题,解决思路是.o文件需要跟编译的makefile文件同目录。

首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的。

意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文件直接复制到相应目录即可方便编译出所有文件。这些makefile文件是通用的,只需根据自己的工程情况改动少许内容即可。下面会说。

总体思路是:把目标文件放在debug文件夹下的obj目录下,把最终的二进制文件放在debug文件夹下的bin目录下;如何递归编译所有除了debug目录下的makefile文件呢:获得当前目录下的所有子目录,执行子目录下的makefile文件;获取当前目录下的所有c文件,编译c文件并放到指定的目标文件夹下。最后再执行debug目录下的makefile文件生成bin文件。

注意:除了debug文件夹比较特殊外,其他的子目录下都需要有Makefile文件,而且这些Makefile是相同的,除了根目录下的makefile文件有些不同外。即除了bin和obj目录以外的其他目录都需要Makefile文件,即使目录下没有c文件或者其他目录。

过程:首先在根目录下新建一个debug文件夹,debug文件夹下有bin目录和obj目录和一个Makefile文件,结构如下图。(这个debug文件里的makefile文件需要最后执行)(tree工具需要自己安装的,ubuntu下直接输入sudo apt-get install tree即可,但有时可能需要先sudo apt-get update才行)

整个目录结果如下图:

然后在根目录下新建Makefile文件,根目录下也可能会有c文件,故也需处理根目录下的c文件,内容如下:

#设置编译器
CC=gcc
#debug文件夹里的makefile文件需要最后执行,所以这里需要执行的子目录要排除debug文件夹,这里使用awk排除了debug文件夹,读取剩下的文件夹
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "debug") print $$9}')
#无需下一行的注释代码,因为我们已经知道debug里的makefile是最后执行的,所以最后直接去debug目录下执行指定的makefile文件就行,具体下面有注释
#DEBUG=$(shell ls -l | grep ^d | awk '{if($$9 == "debug") print $$9}')
#记住当前工程的根目录路径
ROOT_DIR=$(shell pwd)
#最终bin文件的名字,可以更改为自己需要的
BIN=myapp
#目标文件所在的目录
OBJS_DIR=debug/obj
#bin文件所在的目录
BIN_DIR=debug/bin
#获取当前目录下的c文件集,放在变量CUR_SOURCE中
CUR_SOURCE=${wildcard *.c}
#将对应的c文件名转为o文件后放在下面的CUR_OBJS变量中
CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
#将以下变量导出到子shell中,本次相当于导出到子目录下的makefile中
export CC BIN OBJS_DIR BIN_DIR ROOT_DIR
#注意这里的顺序,需要先执行SUBDIRS最后才能是DEBUG
all:$(SUBDIRS) $(CUR_OBJS) DEBUG
#递归执行子目录下的makefile文件,这是递归执行的关键
$(SUBDIRS):ECHOmake -C $@
DEBUG:ECHO#直接去debug目录下执行makefile文件make -C debug
ECHO:@echo $(SUBDIRS)
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
$(CUR_OBJS):%.o:%.c$(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
CLEAN:@rm $(OBJS_DIR)/*.o@rm -rf $(BIN_DIR)/*

上面的注释很详细了,具体的命令如果不清楚,自己可以google一下,譬如:wildcard patsubst awk等

读者可以根据自己的需要更改自己的debug目录和目标文件目录和bin文件目录

其他子目录下的Makefile文件的内容如下:

 1 #子目录的Makefile直接读取其子目录就行
 2 SUBDIRS=$(shell ls -l | grep ^d | awk '{print $$9}')
 3 #以下同根目录下的makefile的相同代码的解释
 4 CUR_SOURCE=${wildcard *.c}
 5 CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
 6 all:$(SUBDIRS) $(CUR_OBJS)
 7 $(SUBDIRS):ECHO
 8     make -C $@
 9 $(CUR_OBJS):%.o:%.c
10     $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
11 ECHO:
12     @echo $(SUBDIRS)

debug目录下的Makefile文件如下:

1 OBJS=*.o
2 ODIR=obj
3 $(ROOT_DIR)/$(BIN_DIR)/$(BIN):$(ODIR)/$(OBJS)
4     $(CC) -o $@ $^

最后只需在根目录下,我的是我的根目录makefile目录下,执行make命令即可:

结果目录结果为:

然后执行". debug/bin/myapp"即可;最后可以执行make CLEAN清楚掉所有的目标文件和bin文件。

转载自:http://www.cnblogs.com/Shirlies/p/4282182.html

多文件目录下makefile文件递归执行编译所有c文件 很不错相关推荐

  1. Java文件是如何编译成Dex文件的?如何执行Dex文件?

    Dex文件介绍 Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件. 为什么要使用dex文件来存储呢? Java源码经过编 ...

  2. 成功解决:将后缀.pyx格式文件(linux环境)编译成pyd文件(windows环境下)实现python编程加载或导入

    成功解决:将后缀.pyx格式文件(linux环境)编译成pyd文件(windows环境下)实现python编程加载或导入 目录 解决问题 解决思路 解决方法 解决问题 .pyx格式文件,在window ...

  3. Java的class文件批量反编译成Java文件

    Java的class文件批量反编译成java文件 Class文件是java文件编译后产生的一个文件,class文件便于在软件上运行,但是我们无法阅读中间的程序,所以我们需要将class文件转换成jav ...

  4. linux下Makefile中包含有shared library动态链接库文件时候的简单例子

    如果不知道什么是makefile,可以首先看我的另一篇博客: linux下Makefile的简单例子及解释 http://www.cnblogs.com/lihaozy/archive/2012/08 ...

  5. Linux下如何将源文件逐步编译成目标文件的过程

    前言 请讲一下linux如何源文件逐步编译成可执行文件. 解答 首先先上图对编译的整个过程有个感性的认识,然后再逐步分析各个过程.  以hello.c 程序为例 # include <stdio ...

  6. 计算机错误2 找不到指定文件,无法执行目录中的文件 错误2系统找不到指定文件怎么办?...

    也遇到这个问题了,不过 是windows系统--前几天都没这个问题的... 补充还有一句话:错误2,系统找不到指定的文件 这几天幻想所有下载的游戏 都不能安装,包括之间保留的曾经玩过的游戏安装文件也不 ...

  7. glibc的头文件 linux_求助,编译glibc头文件时出错

    我用的软件包如下: binutils-2.16.tar.gz gcc-3.4.4.tar.bz2 glibc-2.3.5.tar.gz glibc-linuxthreads-2.3.5.tar.gz ...

  8. mysql执行文件脚本文件_MySQL执行外部sql脚本文件的命令

    sql脚本是包含一到多个sql命令的sql语句,我们可以将这些sql脚本放在一个文本文件中(我们称之为"sql脚本文件"),然后通过相关的命令执行这个sql脚本文件.基本步骤如下: ...

  9. android编译终止,android - Android NDK-没有此类文件或目录编译终止-头文件导出问题 - 堆栈内存溢出...

    我正在尝试使用NDK将TagLib C ++库( http://taglib.github.io/ )导入Android. 通过按如下所示将所有源代码放在/jni/taglibroot/下,我能够成功 ...

最新文章

  1. 返回一个二维整数数组中的最大的子数组和
  2. Windows下VTK6.0.0安装详解(CMake使用说明)
  3. 云化要求下,数据库架构如何演进?
  4. Java 遍历HashTable
  5. ODBC、OLE DB、 ADO的区别
  6. Jmeter-Beanshell
  7. TFT-LCD显示屏工作原理图文解析
  8. CryEngine技术讲解
  9. 网站建设多少钱(做一个网站需要多少钱)
  10. 计算机毕业设计Java馥郁花艺网站mp4(源码+系统+mysql数据库+lw文档)
  11. android源码下载(下)
  12. 【syslog】搭建日志服务器
  13. ElasticSearch之HTTP索引操作和文档操作
  14. 11:C语言之求sn=a+aa+aaa+aaaa+......的值
  15. GitHub协作开发项目
  16. linux 命令行获取时间,linux - 以毫秒为单位获取时间的命令
  17. 助推国产基础软硬件建设,巨杉数据库与湘江鲲鹏完成产品兼容认证
  18. 手机遥控器代码,教你变成遥控大师
  19. 【张宇2021考研】数学一(样卷)扫描版
  20. 阿里云服务器漏洞修复

热门文章

  1. python内置数据结构_Python基础知识2-内置数据结构(下)
  2. dubbo 无法访问消费端_Dubbo最佳实践,我整理了以下9点
  3. 从零开始搭建spring-cloud(5) ----config
  4. 安装 elasticsearch-head
  5. 三十四、数据仓库的建模
  6. 收藏 | 500页阿里、滴滴、快手等公司的大数据最佳实践!PDF限时下载
  7. hadoop的python框架指南_Python之——用Mrjob框架编写Hadoop MapReduce程序(基于Hadoop 2.5.2)...
  8. camvid数据集介绍_深度学习图像数据集介绍(MSCOCO)
  9. python scikit learn 封装_python的scikit-learn的主要模块和基本使用
  10. android控件属性文档,1.Android控件属性收集