Linux嵌入式学习之Ubuntu入门(四)Makefile

系列文章内容

Linux嵌入式学习之Ubuntu入门(一)基本命令、软件安装、文件结构、编辑器介绍

Linux嵌入式学习之Ubuntu入门(二)磁盘文件介绍及分区、格式化等

Linux嵌入式学习之Ubuntu入门(三)用户、用户组及文件权限

Linux嵌入式学习之Ubuntu入门(四)Makefile

Linux嵌入式学习之Ubuntu入门(五)汇编语法学习

Linux嵌入式学习之Ubuntu入门(六)shell脚本详解



什么是Makefile

在Linux下,借助例如gcc编译器编译时,如果有很多的文件:

1、如果工程没有编译过,那么工程中的所有.c 文件都要被编译并且链接成可执行程序。
2、如果工程中只有个别 C 文件被修改了,那么只编译这些被修改的 C 文件即可。
3、如果工程的头文件被修改了,那么我们需要编译所有引用这个头文件的 C 文件,并且链接成可执行文件。

什么是GCC

gcc [选项] [文件名字]
主要选项如下:
-c: 只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
-o: <输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默认编译出来的可执行文件名字为 a.out。
-g: 添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编译的时候生成调试所需的符号信息。
-O: 对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进行优化,这样产生的可执行文件执行效率就高。
-O2: 比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。

在程序中,int main(int argc, char *argv[])是什么意思:
很多程序都是带参数运行的,如:del readme.txt,此时,运行的程序就是del.exe,而readme.txt就是它的参数,
argc = 1,(1个参数)
argv[0] = “readme.txt”(接收的字符串);
假设一个程序的main函数不带任何参数,那么很显然,它仍可以运行,只是,不接收参数。

Makefile文件规范

1.所有行首需要空出来的地方一定要使用“TAB”键!不要使用空格键!
2.make 命令会在当前目录下查找是否存在“Makefile”这个文件(小写也可以)

简单例子中的规范写法

在这里插入图片描述
makefile中,一般将第一行作为默认目标,所以clean不会执行,可以使用nake clean执行。(clean是伪目标)
同时make过程中,会自动输出这些命令,如果前面加上@,这些命令就不会输出。

Makefile变量写法

在这里插入图片描述

Makefile其他符号

打印输出

echo:相当printf
在这里插入图片描述

“=”

赋值符号:始终等于该变量

 name = jia
 curname = $(name)
 name = jiahj

print:
 @echo curname: $(curname)

这里输出结果是:curname:jiahj
使用的是最新赋值的变量

“:=”

赋值符号:只在执行该行时赋值

 name = jia
 curname  := $(name)
 name = jiahj

print:
 @echo curname: $(curname)

这里输出结果是:curname:jia
使用的前面定义好的

“+=”

变量追加符号

objects = main.o inpiut.o
objects += calcu.o

变量 objects 变成了“main.o input.o calcu.o”

“?=”

curname ?= jia

变量如果前面没有被赋值,那么该变量就是jia

Makefile模式规则

用%表示任意长度的非空字符串,例如:“%.c”就是所有的.c文件

Makefile自动化变量

在这里插入图片描述

上面的那个makefile例子可以变成下面形式:

objects = main.o input.o calcu.o
main: $(objects)
 gcc -o main $(objects)

%.o : %.c
 gcc -c $<

clean:
 rm *.o
 rm main

Makefile伪目标

像之前执行的make clean一样,当该目录下有一个clean文件的时候,就无法执行makefile的clean目标了

PHONY : clean

用如上命令将clean声明成伪目标就可以了
在这里插入图片描述
在这里插入图片描述

Makefile条件判断

语法:在这里插入图片描述

ifeq与ifneq

下面几种写法都可以
在这里插入图片描述
ifeq判断参数1与2是否相等,相等则为真。ifneq反之

ifdef与ifndef

在这里插入图片描述
变量名的值为非空即为真,否则为假。ifndef反之

Makefile函数

用法:
在这里插入图片描述
参数之间用逗号,函数名与参数之间用空格

函数名含义
$(subst < x1>,< x2>,< text>)将字符串< text>中的< x1>内容替换为< x2>,函数返回被替换以后的字符串
$(patsubst < pattern>,< replacement>,< text>)查找字符串< text>中的单词是否符合模式< pattern>,如果匹配就用< replacement>来替换掉,函数返回值就是替换后的字符串
$(dir <names…>)从文件名序列< names>中提取出目录部分,返回值是文件名序列< names>的目录部分
$(notdir <names…>)去除文件中的目录部分,也就是提取文件名,
$(foreach < var>, < list>,< text>)把参数< list>;中的单词逐一取出放到参数< var>;所指定的变量中,然后再执行< text>;所包含的表达式。
$(wildcard PATTERN…)通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,这个时候就要用到函数 wildcard

例子:
1.

$(patsubst %.c,%.o,a.c b.c c.c)

将字符串“a.c b.c c.c”中的所有符合“%.c”的字符串,替换为“%.o”,替换完成以后的字符串为“a.o b.o c.o”。

$(dir </src/a.c>)

提取文件“/src/a.c”的目录部分,也就是“/src”。

$(notdir </src/a.c>)

提取文件“/src/a.c”中的非目录部分,也就是文件名“a.c”。

names := a b c d
files := $(foreach n,$(names),$(n).o)

$ (name)中的单词会被挨个取出,并存到变量“n”中,“ $ (n).o”每次根据“$ (n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
5.

$(wildcard *.c)

获取当前目录下所有的.c 文件,类似“%”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值