Makefile语法规则

1、make工程管理器

工程管理器,就是管理较多的文件

make工程管理器:也就是“自动编译管理器”。

作用:

1)读取makefile文件编译内容来执行具体编译工作

2)根据文件时间戳自动发现更新过的文件

3)只编译改动的代码文件,而不用完全编译

更多资料见:

https://www.gnu.org/software/make/

2、Makefile语法

Makefile是make读取的唯一配置文件

target: dependency_files
<TAB> command

target: 编译的目标,目标文件或者可执行文件

dependency_files 依赖的文件

command 编译的命令

举个例子:

hello.o: hello.c hello.h
    gcc -c hello.c -o hello.o

命令行前面必须是一个“TAB键”,否则编译会报错。

就只对于上面的仅一个test.c文件,按照上面的语法规则我们需要下面的Makefile内容:

test:test.o
        gcc test.o -o test
test.o: test.c
        gcc -c -Wall test.c -o test.o

Makefile变量

Makef在Makefile中创建和使用变量。变量是在Makefile中定义的一些名字,用来替代一个文本字符串,该文本字符串称为该变量的值。

  • 用户自定义变量

  • 预定义变量

  • 自动变量

  • 环境变量

1)自定义变量:其值由用户自行设定

变量的值可以用来代替目标体、依赖文件、命令以及Makefile文件中的其他部分

2)自动变量:用来代表编译语句中出现的目标文件和依赖文件,具有本地含义。

常见自动变量:

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

$@ 目标文件的完整名称

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

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

3)预定义变量:预先定义好的常见编译器、汇编器的名称及编译选项

CC C编译器的名称,默认值为cc。

RM 文件删除程序的名称,默认值为rm -f

CFLAGS C编译器的选项,无默认值

AR 库文件维护程序的名称,默认为ar

CPP C预编译器的名称,默认值为$(CC) -E

CPPFLAGS C预编译的选项,无默认值

用户可以在一个Makefile中定义一些和编译无关的命令,比如程序的打包、备份和删除等。

注意:.PHONY 说明伪目标

例如:Makefile中添加如下

.PHONY: clean
clean:
    -rm f1.o f2.o main.o test

使用方法:make clean

补充规则:

1)隐含规则1:编译C程序的隐含规则

<n>.o 目标的依赖目标会自动推导为<n>.c

2)隐含规则2:链接object文件的隐含规则

<n> 目标的依赖目标会自动推导为<n>.o

@echo $(SUBDIRS)

让echo显示提示

@(RM)

预定义变量, rm -f

Make -C $@

读入指定目录下的Makefile

export CC OBJS BIN OBJS_DIR BIN_DIR

让子makefile可以找到使用这些变量

通过这些Makefile的语法规则,我们就可以变成下面的Makefile:

gcc -Wall 启动所有的gcc警报

gcc -c 生成.o文件

OBJS= test.o
CFLAGS= -c -O -g -Wall

test:$(OBJS)

.PHONY:clean
clean:
        -rm $(OBJS)

执行make clean就可以删除掉test.o,执行流程如下:

3、make工具的使用参数

make使用方法:

1)直接运行make

2)make带选项

-C        //dir读取指定目录下的Makefile
-f        //file读取当前目录下的fiLe作为Makefile
-i        //忽略所有的命令执行错误
-l        //dir指定被包含的Makefile所在目录
-n        //只打印要执行的命令,但不执行这些命令
-p        //显示make变量数据库和隐含规则
-s        //在执行命令时不显示命令
-w        //如果make执行时改变目录,打印当前目录名

4、生成驱动的Makefile

编写一个内核hello.c

#include <linux/module.h> //所有模块都需要的头文件
#include <linux/init.h>   // init&exit相关宏

static int __init hello_init(void){
      printk(KERN_ERR "hello world");
      return 0;
}

static void __exit hello_exit(void){
      printk(KERN_EMERG "hello exit!");
}

module_init(hello_init);
module_exit(hello_exit);
ifneq ($(KERNELRELEASE),)
obj-m :=hello.o        // 来指定模块名,注意模块名加.o而不是加.ko
else
KERNELDIR ?=/lib/modules/$(shell uname -r)/build    // 目标板linux内核源码顶层目录的绝对路径
all:
        make -C $(KERNELDIR) M=$(PWD) modules
clean:
        make -C $(KERNELDIR) M=$(PWD) clean
endif

obj-y := hello.o 表示将hello.o编译进内核,工程中按照规范来不要这样写。

Make -C表示存放到内核的目录执行其Makefile

“M=”的作用是:当模块需要以内核为基础编译一个外部模块时,需要在make modules命令中加入"M=dir",程序就会到dir目录下来找你的源文件进行编译,make clean也是类似的,到你当前目录下进行清除工作(删除所有编译生成的文件)。

通过make之后可以生成hello.ko文件,将该文件进行insmod(insert module)操作,就可以将hello.ko文件载入内核,通过dmesg就可以查看载入时的相关信息了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值