文档章节

Makefile中用foreach,eval,call实现将目标文件编译到指定目录

临峰不畏
 临峰不畏
发布于 2016/08/10 22:22
字数 565
阅读 701
收藏 3
点赞 0
评论 0

博主要创建一个工程目录,希望将所有的.c文件都编译成.o并存放到out/目录下。如下:

.
├── d1
│   ├── aa.c
│   └── dd.c
├── main.c
├── Makefile
└── out

经过一晚上的尝试,最终使用了foreach函数实现了这个目标:

TARGET=test
ALL_SOURCES=$(shell find -name "*.c")

SOURCE_TO_OBJECT = ./out/$(subst .c,.o,$(notdir $(1)))
ALL_OBJECTS=$(foreach src,$(ALL_SOURCES),$(call SOURCE_TO_OBJECT,$(src)))

define CREATE_OBJECT_TARGET
$(call SOURCE_TO_OBJECT,$(1)) : $(1)
	gcc -c -o $$@ $$^
endef

all: $(TARGET)

clean:
	-rm $(ALL_OBJECTS)
	-rm $(TARGET)

$(TARGET):$(ALL_OBJECTS)
	gcc -o $@ $^

$(foreach src,$(ALL_SOURCES),$(eval $(call CREATE_OBJECT_TARGET,$(src))))

大概思路是这样的:
首先,ALL_SOURCES=$(shell find -name "*.c"),我将当前目录下的所有.c文件找到并赋值给ALL_SOURCE变量。
然后,ALL_OBJECTS=$(foreach src,$(ALL_SOURCES),$(call SOURCE_TO_OBJECT,$(src))),对每个一ALL_SOURCE中的源文件进行处理,将每个文件名去除路径,并将后缀.c替换成.o,再加上./out前缀就成了目标文件名。注意:函数调用中不能随意地加空格!!
SOURCE_TO_OBJECT是一个将源文件名转换成目标文件名的函数。上面用$(call ...) 对它进行调用。

然后,我想为每个目标文件建立依赖关系,如下:

./obj/main.o : main.c
    gcc -c -o $@ $^

./obj/aa.o : d1/aa.c
    gcc -c -o $@ $^

./obj/bb.o : d1/bb.c
    gcc -c -o $@ $^

文件个数少还好说,如果工程大了,上百个文件维护起来很吃力。于是想到要用 $(foreach ...) 函数来实现。创建这么一个函数,用于生成目标与文件依赖关系:

define CREATE_OBJECT_TARGET
$(call SOURCE_TO_OBJECT,$(1)) : $(1)
	gcc -c -o $$@ $$^
endef

转入的一个参数$(1)是源文件全路径。
注意:其中的 gcc -c -o $$@ $$^,是双 $ 符号。

再用如下的$(foreach ...)函数达到对每一个源文件都建立一个目标的目的:
$(foreach src,$(ALL_SOURCES),$(eval $(call CREATE_OBJECT_TARGET,$(src))))

其中用到的命令有:

  • notdir,从全路径的文件名,提取出文件名称。相当于shell的basename
  • subst,字符串替换
  • foreach,对数组中的每一个元数做处理
  • call,调用自定义宏
  • eval,将字串应用到Makefile上下文
  • shell,执行shell脚本

其它常用的函数还有:

  • dir
  • addprefix
  • patsubst
  • strip
  • sort
  • wildcard

如果大家还有别的什么更好的方法,欢迎留言。

© 著作权归作者所有

共有 人打赏支持
临峰不畏
粉丝 211
博文 183
码字总数 96576
作品 0
深圳
技术主管
[转]Makefile 使用总结

Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之间的依赖关系不知会多复杂. Makefil...

四彩
2016/02/28
119
0
一个通用的makefile写法,自动推导文件的依赖关系

今天看了一天的makefile的写法,东拼西凑,好不容易写出了一个makefile,颇有成就感,记录下来,以备温习之用。 假设有两个头文件目录 header1,header2;两个cpp文件目录,src1,src2,一个lib目...

AlphaJay
2010/11/23
0
0
makefile 一看就懂了

前言:没接触Linux下编译之前,觉得很神秘,特别是makefile,一个简单的make命令就能编译一个大型项目生成一个可执行文件,接下来跟大家分享下学习的makefile的知识。 目录: 1.makefile简介...

小小实习生
2016/10/22
39
0
makefile(04)_函数

9.函数定义及调用 Makefile中支持函数的概念,make解析器提供了一系列函数供Makefile使用。同时可以自定义函数。 9.1.自定义函数 在Makefile中支持自定义函数的实现,并调用执行,通过defin...

三九感冒灵
04/26
0
0
内核模块编译 makefile入门

转自http://blog.csdn.net/zqixiao_09/article/details/50838043 一、模块的编译 我们在前面内核编译中驱动移植那块,讲到驱动编译分为静态编译和动态编译;静态编译即为将驱动直接编译进内核...

u012142460
2017/12/19
0
0
Android系统镜像文件的打包过程分析

在前面一篇文章中,我们分析了Android模块的编译过程。当Android系统的所有模块都编译好之后,我们就可以对编译出来的模块文件进行打包了。打包结果是获得一系列的镜像文件,例如system.img、...

sflfqx
2015/02/09
0
0
linux设备驱动makefile入门解析

(点击上方蓝字,快速关注) 对于一个普通的linux设备驱动模块,以下是一个经典的makefile代码,使用下面这个makefile可以 完成大部分驱动的编译,使用时只需要修改一下要编译生成的驱动名称即...

t146lla128xx0x
2017/12/27
0
0
C/C++ 通用 Makefile

Generic Makefile for C/C++ Program ================================================== Keywords: Makefile, make, Generic, C/C++ Author: whyglinux (whyglinux AT hotmail DOT com) D......

wdliming
2011/11/23
0
0
uboot源码——主Makefile分析

以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。 一、配置编译初体验 1、uboot来源于官方(uboot官网下载),或者SoC官方(研发s5pv210芯片的公司推出的开发板,SMDKV210),或...

oqqHuTu12345678
2017/04/03
0
0
Makefile 书写

文章转载自陈皓的《跟我一起写Makefile》 概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professio...

li_wen01
2017/09/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

全新内存布局Android5 for one x

众所周知Android5.0默认ART模式,运行速度加倍,软件占用内存也加倍,我们one x这种元老机采用旧的内存布局,data空间2g ART模式下安装几个软件也就不够用了。最近逛国外的xda论坛,发现有大...

CrazyManDF
10分钟前
0
0
web3j转账

 web3 转账功能   为了完成以太坊交易,必须有几个先决条件   1、对方的以太坊地址   2、确定要转账的金额   3、自己地址的转账权限   4、大于转账金额的以太币,以太币转账其实就...

智能合约
11分钟前
0
0
10.28 rsync工具介绍 , rsync常用选项, rsync通过ssh同步

rsync远程同步 重点!重点!!重点!!! 例子 • rsync -av /etc/passwd /tmp/1.txt • rsync -av /tmp/1.txt 192.168.188.128:/tmp/2.txt rsync格式 • rsync [OPTION] … SRC DEST • rs......

Linux_老吴
24分钟前
0
0
iis php 环境搭建,非常详细的教程

准备篇 一、环境说明: 操作系统:Windows Server 2016 PHP版本:php 7.1.0 MySQL版本:MySQL 5.7.17.0 二、相关软件下载: 1、PHP下载地址: http://windows.php.net/downloads/releases/ph...

T_star
27分钟前
0
0
Day35 rsync通过服务同步

rsync通过服务同步 rsyncd.conf配置文件详解 port:指定在哪个端口启动rsyncd服务,默认是873端口。 log file:指定日志文件。 pid file:指定pid文件,这个文件的作用涉及服务的启动、停止等...

杉下
32分钟前
1
0
【最新最全】为 iOS 和 Android 的真机和模拟器编译 Luajit 库

编译 Luajit 库,的确是一个挑战。因为官网的教程,在当前版本的 Xcode 和 NDK 环境中,已经不适用了。以前只是编译了适用于真机的 Luajit 库。最近在尝试编译模拟器 Luajit 库,就顺便梳理了...

ios122
32分钟前
0
0
rsync至ssh同步

rsync: 文件同步工具,可实现“增量拷贝”;使用yum安装rsync包 常用选项:-a=-rtplgoD (-r同步目录,-t保持文件的时间属性,-p保持文件的权限属性,-l保持软连接,-g保持文件的属组,-o保持...

ZHENG-JY
38分钟前
0
0
TradingView 学习笔记

#前言 公司最后需要使用TradingView展示K线图走势。由于之前没接触过,拿到文档时一脸蒙逼。还好找到二篇文章+Demo代码,直接改改就行了。 #被批 由于上面的懵懂,有个问题困扰4个小时没解决...

hihubs
38分钟前
0
0
10.28 rsync工具介绍~10.31 rsync通过ssh同步

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而...

洗香香
40分钟前
1
0
卷积为什么要旋转180度

参考《最容易理解的对卷积(convolution)的解释》 https://blog.csdn.net/bitcarmanlee/article/details/54729807 这篇博客详细讲解了“卷积”,提及了为什么要反转180度,我简述下。 1.卷积的...

datadev_sh
49分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部