15.物联网学习之makefile

Makefile概述

  1. makefile的概述
  1. 在提供人工方便方面: “自动化编译”:一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
    1. ”自动编译管理器”自动体现在哪里?

根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入makefile文件的内容来执行大量的编译工作。用户只需编写一次简单的编译语句就可以了。

(2)在提升机器效率方面: 提升编译效率:再次编译,只编译修改的文件

  1. 如何编译多个文件?

  1. 方法一:暴力法

Gcc add/add_int.c add/add_float.c sub/sub_int.c sub/sub_float.c -o test

  1. 方法二:makefile

步骤:

<1>vi makefile //创建makefile文件

<2>在内件写make

模板:

目标:依赖

<TAB>命令

内容1:

test:add.c sub.c test.c

gcc add.c sub.c test.c -o test

<3>make

这时候会自动执行mainfile的内容

其中的问题:

(1)当我们修改文件时,make之后会全部编译,主要是我们没有把命令分开写,导致会把所有命令重新运行一遍,降低效率.

解决方式:把make命令分开写

<3> 替代上述<3>

这样写会有问题,只运行第一个命令,后面命令不做

问题原因:系统默认只运行第一个命令,认为命令有缺失才会补全命令

解决方法:最后一条链接命令写到第一个

test:add.o sub.o test.o

gcc add.o sub.o test.o -o test

add.o:add.c

gcc -c add.c -o add.o

sub.o:sub.c

gcc -c sub.c -o sub.o

test.o:test.c

gcc -c test.c -o test.o

2.如何删除多个.o文件

(1)方法一:暴力法

rm *.o

(2)方法二:make

步骤

<1>在文件中补充

clean:

rm *.o

<2>make clean

可能出现的问题

当我们有一个叫clean文件时,会出错

解决方法:

<1> 替代上述的<1>

#伪目标

.PHONY:clean

clean:

rm *.o

  1. makefile创建变量的目的

简言之:方便代码

 用来代替一个文本字符串:

  1. 系列文件的名字  

   2. 传递给编译器的参数

   3. 需要运行的程序

   4. 需要查找源代码的目录

   5. 你需要输出信息的目录  

   6. 你想做的其它事情。

3.自定义变量的方法

x = a //变量在声明时需要给予初值

$(x)或${x} //取值 小括号或者中括号都可以

如果你要使用真实的 $ 字符,那么你需要用 $$ 来表示。

<1>例子

test:add.c sub.c test.c

gcc add.c sub.c test.c -o test

问:如何修改成自定义变量?

(1)方法一: 一口气定义法:

SRC = add.c sub.c test.c

test:$(SRC)

gcc ${SRC} -o test

(2)方法二: 逐次定义法

SRC=add.c

SRC+=sub.c

SRC+=test.c

test:$(SRC)

gcc ${SRC} -o test

补充:

 

上述我们用的是 +=

4.makefile自动变量

$*   不包含扩展名的目标文件名称

$+   所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件

$<    第一个依赖文件的名称

$?    所有时间戳比目标文件晚的的依赖文件,并以空格分开

$@       目标文件的完整名称

$^    所有不重复的目标依赖文件,以空格分开

$%       如果目标是归档成员,则该变量表示目标的归档成员名称

<1>使用自动变量例子

(目的:展示使用方式与使用内容)

(如何查看:echo $..展示代表命令+结果)

test:add.o sub.o test.o

gcc add.o sub.o test.o -o test

添加打印:

  1. 第一种:

echo $+ //打印所有依赖文件,可重复

echo $^ //打印所有不重复文件

echo $< //打印第一个依赖文件,第一个变量?

  1. 第二种:上述命令运行时会吧echo$+命令也写上去,取消前加@

@echo $+

@echo $^

@echo $< //只打印结果,不打印echo命令

  1. 第三种:添加运行时的提醒标识

@echo $$+ = $+ //打印前加上($+ =)

@echo $^

@echo $<

add.o:add.c

gcc -c add.c -o add.o

  1. $* 与 $@

echo $* //命令+结果不包含扩展名的目标文件名称

echo $@ //命令+结果目标文件的完整名称

sub.o:sub.c

gcc -c sub.c -o sub.o

test.o:test.c

gcc -c test.c -o test.o

4.1为什么要使用自动变量?
<方式一:不用自动变量>

#变量的定义和赋值

SRC = add.o sub.o test.o

test:$(SRC)

gcc ${SRC} -o test

add.o:add.c

gcc -c add.c -o add.o

sub.o:sub.c

gcc -c sub.c -o sub.o

test.o:test.c

gcc -c test.c -o test.o

#伪目标

.PHONY:clean

clean:

rm *.o

-----------------------------------------------------------------------------------------------------

<方式二:使用自动变量>

#自动变量SRC = add.o sub.o test.o

test:$(SRC)

gcc ${SRC} -o $@

add.o:add.c

gcc -c $^ -o $@

sub.o:sub.c

gcc -c $^ -o $@

test.o:test.c

gcc -c $^ -o $@

#伪目标

.PHONY:clean

clean:

rm *.o

-----------------------------------------------------------------------------------------------------

在使用自动变量的时候,方便

  1. Makefile的隐含变量

作用:是对上述的进一步优化.

#变量的定义和赋值

#SRC = add.o sub.o test.o

SRC = add.o

SRC += sub.o

SRC += test.o

#两步编译.c->.o->exe

test:$(SRC)

gcc ${SRC} -o test

add.o:add.c

gcc -c add.c -o add.o

sub.o:sub.c

gcc -c sub.c -o sub.o

test.o:test.c

gcc -c test.c -o test.o

--------------------------------------------------------------------------------------------------------

#隐含变量

SRC = add.o sub.o test.o

CC = gcc //CC替代gcc

#CC = arm-linux-gcc  //不同编译器时用的这个

CFLAGS = -c -g -Wall -I /home/linux/Makefile/include/<绝对目录>

<也可以直接写include前面不写/,这是相对目录>

#两步编译.c->.o->exe

test:$(SRC)

$(CC) ${SRC} -o $@

%.o:%.c

$(CC) $(CFLAGS) $^ -o $@

<注意>

  1. 下面是上面的极简化版
  2. SRC替代依赖文件,CC替代gcc,CFLAGS替代-c/-g等指令
  3. CFLAGS    C编译器的选项,无默认值。

 

6.Makefile条件判断

(1)例子: 如果我们当前架构是否为x86,如果是,赋值CC=gcc

ARCH = x86

ifneq ($(ARCH),X86)

#不干事

else

CC = gcc

Endif

使用变量:

$(CC) ${SRC} -o $@

(2)例子等价上面,只是ifneq<判断不相等>换成ifdef<判断定义>

ifdef ARCH

CC = gcc

else

#不干事

endif

7.Makefile函数

 

例子:

#函数

SRC = $(wildcard *.c) //返回当前目录下所有.c源文件列表

OBJ = $(patsubst %.c, %.o<前两个参数意义.c文件替换成.o文件>, $(SRC))

//当前目录所有.c文件替换成.o文件

CC = gcc

CFLAGS = -c -g -Wall -I /home/linux/Makefile/include/

#两步编译.c->.o->exe

test:$(OBJ)

$(CC) $^ -o $@

%.o:%.c

$(CC) $(CFLAGS) $^ -o $@

  1. make的-l-f之类使用

  1. -f例子

make -f makefile2

//自定义运行makefile文件,默认makefile

  1. -i例子

make -f makefile2 -i

//编译时,忽略错误,继续运行,这样在大型项目时候可以一次找出更多错误

  1. -n例子

make -n //打印执行的命令,但不执行命令

  1. -s例子

make -s //不打印命令,只执行命令

  1. -w例子

make -w //显示执行的目录地址,如/home/linux/include

  1. -C例子

问题背景:

像工程文件一样,文件放在自己的目录下

(1)在home文件下的makefile

-----------------------------------------------------------------------------------------------------------

CC = gcc

CFLAGS = -c -g -Wall -I /home/linux/Makefile/include/

SRCDIR = ./src

OBJDIR = $(shell pwd)/obj

SRC = $(wildcard $(SRCDIR)/*.c)

OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC)))

<1>以上是建立的变量

CFLAGS 替代参数

SRCDIR OBJDIR 地址替代,注意:下面SRCDIR 作为依赖,不可用$(shell pwd)shell命令

SRC 返回指定目录全部.c

OBJ  .c替换到指定文件的.o

-----------------------------------------------------------------------------------------------------------

export CC CFLAGS OBJ OBJDIR

<2>以上是变量分享给其他目录下,就是加上这个,src下也可以使用此类变量

-----------------------------------------------------------------------------------------------------------

all:$(SRCDIR) ECHO test

$(SRCDIR):ECHO

make -C $@

ECHO:

@echo "begin......."

#两步编译

test:$(OBJ)

$(CC) $^ -o $@

<3>以上是伪目标all,加上两个参数$(SRCDIR),ECHO test

<问题:$(SRCDIR):ECHO为什么必须要加上ECHO?>

必须加上依赖才会满足命令定义

<3.1>$(SRCDIR):ECHO

make -C $@ 运行obj文件下makefile,根据内容生成obj文件下.o

<3.2>test:$(OBJ)

$(CC) $^ -o $@ 运行obj文件下.o生成test文件

-----------------------------------------------------------------------------------------------------------

#伪目标

.PHONY:clean

clean:

$(RM) *.o

-----------------------------------------------------------------------------------------------------------

(2)在src文件下的makefile

all:$(OBJ)

$(OBJDIR)/%.o:%.c

$(CC) $(CFLAGS) $^ -o $@

似乎是有%.c%.o时要写一个伪目标,不然找不到.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值