Makefile 基本知识

Technorati 标签: Makefile 基本知识

 

最常见的书写方式:
CC          = gcc
LD        = ld
STRIP     = strip
CFLAGS      := -Os -static -DEZ_OS_LINUX
CLFLAGS     := -Os -static
all: main

EXEC = main
OBJS = main.o mytool1.o mytool2.o
INCS = mytool1.h mytool2.h

all: $(EXEC)
$(EXEC): $(OBJS)
    $(CC) $(CFLAGS) -o [email protected] $(OBJS)
    $(STRIP) [email protected]
clean:
    -rm -f $(EXEC) *.elf *.gdb *.o
%.o: %.c $(INCS)
    $(CC) $(CFLAGS) -c $< -o [email protected]

 

Makefile中允许使用简单的宏来指代源文件以及相关编译选项,引用宏时,必须在变量名称前加美元$,同时,使用圆括号括起来(变量名为两个字母以上时)

下面都是有效的宏引用:

    $(CFLAGS)

    $2

    $Z

    $(Z) 
其中最后两个引用是完全一致的。

    [email protected]      --  目标文件,  

    $^      --  所有的依赖文件,

    $<      --  第一个依赖文件。

# 这是简化后的Makefile

main:main.o mytool1.o mytool2.o

gcc -o [email protected] $^            //[email protected] 就是main, $^就是main.o mytool1.o mytool2.o

main.o:main.c mytool1.h mytool2.h

gcc -c $<               //$<就是main.c

mytool1.o:mytool1.c mytool1.h

gcc -c $<               //$<就是mytool1.c

mytool2.o:mytool2.c mytool2.h

gcc -c $<               //$<就是mytool2.c

 

常用字符串处理函数

1.$(subst FROM,TO,TEXT)

函数名称:字符串替换函数—subst。

函数功能:把字串“TEXT”中的“FROM”字符替换为“TO”。

返回值:替换后的新字符串。

2.$(patsubst PATTERN,REPLACEMENT,TEXT)

函数名称:模式替换函数—patsubst。

函数功能:搜索“TEXT”中以空格分开的单词,将否符合模式“TATTERN”替换为“REPLACEMENT”。参数“PATTERN”中可以使用模式通配符“%”来代表一个单词中的若干字符。

返回值:替换后的新字符串。

函数说明:参数“TEXT”单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。

3.$(strip STRINT)

函数名称:去空格函数—strip。

函数功能:去掉字串(若干单词,使用若干空字符分割)“STRINT”开头和结尾的空字符,并将其中多个连续空字符合并为一个空字符。

返回值:无前导和结尾空字符、使用单一空格分割的多单词字符串。

函数说明:空字符包括空格、[Tab]等不可显示字符。

4.$(sort LIST)

函数名称:排序函数—sort。

函数功能:给字串“LIST”中的单词以首字母为准进行排序(升序),并取掉重复的单词

返回值:空格分割的没有重复单词的字串。

函数说明:两个功能,排序和去字串中的重复单词。可以单独使用其中一个功能。

 

二、文件名处理函数

1.$(dir NAMES…)

函数名称:取目录函数—dir。

函数功能:从文件名序列“NAMES…”中取出各个文件名目录部分。文件名的目录部分就是包含在文件名中的最后一个斜线(“/”)(包括斜线)之前的部分。

返回值:空格分割的文件名序列“NAMES…”中每一个文件的目录部分。

函数说明:如果文件名中没有斜线,认为此文件为当前目录(“./”)下的文件。

2.$(notdir NAMES…)

函数名称:取文件名函数——notdir。

函数功能:从文件名序列“NAMES…”中取出非目录部分。目录部分是指最后一个斜线(“/”)(包括斜线)之前的部分。删除所有文件名中的目录部分,只保留非目录部分

返回值:文件名序列“NAMES…”中每一个文件的非目录部分。

3.$(addprefix PREFIX,NAMES…)

函数名称:加前缀函数—addprefix。

函数功能:为“NAMES…”中的每一个文件名添加前缀“PREFIX”。参数“NAMES…”是空格分割的文件名序列,将“SUFFIX”添加到此序列的每一个文件名之前。

返回值:以单空格分割的添加了前缀“PREFIX”的文件名序列。

4.$(wildcard PATTERN)

函数名称:获取匹配模式文件名函数—wildcard

函数功能:列出当前目录下所有符合模式“PATTERN”格式的文件名。

返回值:空格分割的、存在当前目录下的所有符合模式“PATTERN”的文件名。

函数说明:“PATTERN”使用shell可识别的通配符,包括“?”(单字符)、“*”(多字符)等。

 

三、其它函数

1.$(foreach VAR,LIST,TEXT)

函数功能:函数“foreach”不同于其它函数。它是一个循环函数。类似于Linux的shell中的循环(for语句)。这个函数的工作过程是这样的:如果必要(存在变量或者函数的引用),首先展开变量“VAR”和“LIST”;而表达式“TEXT”中的变量引用不被展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量“VAR”,然后执行“TEXT”表达式。重复直到“LIST”的最后一个单词(为空时结束)。“TEXT”中的变量或者函数引用在执行时才被展开,因此如果在“TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到的不同的值。

返回值:空格分割的多次表达式“TEXT”的计算的结果。

2.$(if CONDITION,THEN-PART[,ELSE-PART])

函数功能:函数“if”提供了一个在函数上下文中实现条件判断的功能。就像make所支持的条件语句—ifeq。第一个参数“CONDITION”,在函数执行时忽略其前导和结尾空字符并展开。“CONDITION”的展开结果非空,则条件为真,就将第二个参数“THEN_PATR”作为函数的计算表达式,函数的返回值就是第二表达式的计算结果;“CONDITION”的展开结果为空,将第三个参数“ELSE-PART”作为函数的表达式,返回结果为第三个表达式的计算结果。

返回值:根据条件决定函数的返回值是第一个或者第二个参数表达式的计算结果。当不存在第三个参数“ELSE-PART”,并且“CONDITION”展开为空,函数返回空。

函数说明:函数的条件表达式“CONDITION”决定了,函数的返回值只能是“THEN-PART”或者“ELSE-PART”两个之一的计算结果。

3.$(shell command arguments)

函数功能:函数“shell”所实现的功能和shell中的引用(``)相同。实现了命令的扩展。意味着需要一个shell命令作为它的参数,而返回的结果是此命令在shell中的执行结果。make仅仅对它的回返结果进行处理;make将函数的返回结果中的所有换行符(“\n”)或者一对“\n\r”替换为单空格;并去掉末尾的回车符号(“\n”)或者“\n\r”。函数展开式时,它所调用的命令(它的参数)得到执行。除了对它的引用出现在规则的命令行中和递归的变量定义引用以外,其它决大多数情况下,make在读取Makefile时函数shell就被扩展。

返回值:函数“shell”的参数在shell中的执行结果。

函数说明:函数本身的返回值是其参数的执行结果,没有进行任何处理。对结果的处理是由make进行的。当对函数的引用出现在规则的命令行中,命令行在执行时函数引用才被展开。展开过程函数参数的执行时在另外一个shell进程中完成的,因此对于出现在规则命令行的多级“shell”函数引用需要谨慎处理,否则会影响效率(每一级的“shell”函数的参数都会有各自的shell进程)。

时间: 2024-10-08 11:18:00

Makefile 基本知识的相关文章

Makefile相关知识

1. Makefile的编写: 1>. makefile的命名 1. makefile 2. Makefile 2>. makefile中的规则 三部分: 目标(app):依赖(main.c a.c b.c) 命令(gcc main.c a.c b.c -o app) gcc main.c a.c b.c -o app 执行 make 命令, 就会按照makefile中编写的规则编译整个项目 在makefile文件中可以有一个或多个规则 第一版本:  app:main.c sub.c mul.

makefile 基础知识

[email protected]    目标文件名 $< 第一个依赖文件名 $^ 规则所有依赖文件列表 如果不想让执行语句被打印出来,就在语句前面加上@符号 模式规则 %.o:%.c 后缀规则 .c.o 生成单进程的Makefile PHONY:clean OBJECTS = main.o add.o sub.oCFLAGS = -Wall -gCC = gcc app:$(OBJECTS) $(CC) $(CFLAGS) $^ -o [email protected] %.o:%.c$(CC

Makefile 理论知识

一个完整的Makefile中,包含有:显示规则.隐式规则.变量定义.指示符.注释.伪目标. 显示规则:它描述了在何种情况下如何更新一个或者多个目标文件.书写Makefile是需要明确的给出目标文件.目标依赖文件列表以及更新目标文件需要的命令(有些规则没有命令,这样的规则只是描述文件之间的依赖关系) 隐式规则:它是make根据目标文件(典型的是根据文件名的后缀)而自动推导出来的规则.make根据目标文件名,自动产生目标的依赖文件并使用默认的命令来对目标进行更新(建立一个规则). 变量定义:使用一个

使用makefile编译nodejs模块

使用过node-gyp编译nodejs的addon插件的人,一定很好奇,node-gyp到底帮你做了什么事情,还有,如果我们自己做,难度到底如何.本文不作makefile文件语法的讲解,如果你不懂, 没关系,能看懂基本流程就好.抛开node-gyp,你会发现,有些复杂的东西其实是基于很简单的原理. 环境 操作系统为centos7,已经安装了nodejs,版本为0.10.36,其实差不多新的版本就行.编译链也已经准备好,g++命令啦. 编写代码 源文件hello.cc,很简单,基本和官网的hell

Makefile学习与进阶之Makefile.am和$$(M)的意思

(1)makefile 中,出现$$(M) 是什么意思,发现还是看实际的Makefile长知识啊 在makefile中,会经常使用shell命令,也经常见到$var 和 $$var的情况,有什么区别呢,区别大了.不要认为在makefile的规则的命令行中使用$var就是将makefile的变量和shell共享了,这里仅仅是读取makefile的变量然后扩展开,将其值作为参数传给了一个shell命令.而$$var是在访问一个shell命令内定义的变量,而非makefile的变量.此外,如果某规则有

【转】Kconfig,Makefile 和 .config

原文网址:http://blog.csdn.net/nxh_love/article/details/11846861 最新在做Sensor驱动移植的时候,发现了Android driver 中有Kconfig,Makefile文件.在查看编译后的文件时,又发现还存在.config文件.自己对这几个文件不明白,用度娘来整理下网友对这几个文件的理解. 分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单.在内核配置make m

【转】朱兆祺带你一步一步学习嵌入式(连载)

原文网址:http://bbs.elecfans.com/jishu_357014_2_1.html#comment_top  从最初涉及嵌入式Linux开始到现在,深深的知道嵌入式的每一步学习都是举步维艰.从去年11月份开始,我就着手整理各种学习资料,希望推动嵌入式学习的前进贡献自己微不足道的一份力量.从去年到现在,将C语言的学习经验整理成<攻破C语言笔试与机试陷阱及难点>(现在仍在更新),这份资料已经在电子发烧友论坛的单片机论坛连载(http://bbs.elecfans.com/jish

前辈们的话--大疆技术总监的金玉良言

今天在发烧友看到一篇很好的文章,有很大的启发和震撼,这就是别人一毕业就能进大疆,而我们还在为找工作发愁的原因吗?!! 当然文中说的很多东西都不是我们大多数人都能实现的,人家大一就开始接触嵌入式,入手Linux,学习python,而大一的很多人还沉浸在高考后的喜悦,开学后的迷茫中呢!这就是差距. 还是那句话,兴趣是最好的老师.要是 一开始我们就对机器人,电子技术感兴趣的话,这些其实都不用别人说的,自己就会想尽办法去寻找合适的学习路径. 遇山开山,遇水架桥.兴趣会指导我们找到该找到的一切的.所以,还

浅谈kernel的结构图及生成过程-----(1)

当今,我们身边如此多的服务器,工作站都运行着linux,因此也有不少的朋友想了解linux内的核心机理.但是由于kernel过于庞大,以致让一些朋友望而却步.(我在大二的时候也有过此经历,当时看到一些人在看kernel,自己也想进去一探究竟,但进去没多久就乱了头绪,从而转去看uboot源码).今天我就以我个人的视角来展示kernel的结构图(先申明下,这里并不是讲目录结构图的,因为从目录的名字就知道里面放的是何种文件,我如果讲目录结构的话,相信很多同学会开挂骂我了),以及kernel是如何生成的