代码编织梦想

Makefile基础 

通配符:

%.o:表示所用的.o文件

%.c:表示所有的.c文件

$@:表示目标

$<:表示第1个依赖文件

$^:表示所有依赖文件

变量类型:

:=         即时变量        值即刻确定,在定义时即确定
=          延时变量        ​​​​​​​  值使用到时才确定

?=          延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+=          附加, 它是即时变量还是延时变量取决于前面的定义
?=:         如果这个变量在前面已经被定义了,这句话就会不会起效果,

 Linux驱动编译Makefile

 通过指定内核路径来编译ko文件,Makefile domo程序。

ifeq ($(KERNELRELEASE), )
KERNELDIR := /home/linux-4.19.y
PWD :=$(shell pwd)
ARCH=arm64
CROSS_COMPILE=aarch64-xxx-linux-
MK_PARAM=ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE}
default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) $(MK_PARAM)
clean:
	rm -rf *.mk .tmp_versions Module.symvers *.mod.c *.o *.ko .*.cmd Module.markers modules.order *.a *.mod
else
	obj-m := ch343.o
endif

参数说明

  • ifeq ($(KERNELRELEASE), ):首次编译内核路径为空
  • PWD:当前目录
  • ARCH:平台架构
  • CROSS_COMPILE:指明交叉编译工具
  • -C:指明跳转到内核源码目录下读取那里的Makefile
  • -M:表明然后返回到当前目录继续读入、执行当前的Makefile

 通用Makefile

主要有三个文件,分别是Makefile Makefile.build 说明.txt 这三个文件的内容如下:

Makefile:

CROSS_COMPILE =
AS              = $(CROSS_COMPILE)as
LD              = $(CROSS_COMPILE)ld
CC              = $(CROSS_COMPILE)gcc
CPP             = $(CC) -E
AR              = $(CROSS_COMPILE)ar
NM              = $(CROSS_COMPILE)nm

STRIP           = $(CROSS_COMPILE)strip
OBJCOPY         = $(CROSS_COMPILE)objcopy
OBJDUMP         = $(CROSS_COMPILE)objdump

export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP

CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include

LDFLAGS :=

export CFLAGS LDFLAGS

TOPDIR := $(shell pwd)
export TOPDIR

TARGET := test


obj-y += xxx.o
obj-y += yyy/


all : start_recursive_build $(TARGET)
        @echo $(TARGET) has been built!

start_recursive_build:
        make -C ./ -f $(TOPDIR)/Makefile.build

$(TARGET) : built-in.o
        $(CC) -o $(TARGET) built-in.o $(LDFLAGS)

clean:
        rm -f $(shell find -name "*.o")
        rm -f $(TARGET)

distclean:
        rm -f $(shell find -name "*.o")
        rm -f $(shell find -name "*.d")
        rm -f $(TARGET)

Makefile.build

PHONY := __build
__build:


obj-y :=
subdir-y :=
EXTRA_CFLAGS :=

include Makefile

# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y))   : c/ d/
# __subdir-y  : c d
# subdir-y    : c d
__subdir-y      := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y        += $(__subdir-y)

# c/built-in.o d/built-in.o
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)

# a.o b.o
cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)
  include $(dep_files)
endif


PHONY += $(subdir-y)


__build : $(subdir-y) built-in.o

$(subdir-y):
        make -C $@ -f $(TOPDIR)/Makefile.build

built-in.o : $(cur_objs) $(subdir_objs)
        $(LD) -r -o $@ $^

dep_file = .$@.d

%.o : %.c
        $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<

.PHONY : $(PHONY)

说明.txt

本程序的Makefile分为3类:
1. 顶层目录的Makefile
2. 顶层目录的Makefile.build
3. 各级子目录的Makefile

一、各级子目录的Makefile:
   它最简单,形式如下:

EXTRA_CFLAGS  := 
CFLAGS_file.o := 

obj-y += file.o
obj-y += subdir/
   
   "obj-y += file.o"  表示把当前目录下的file.c编进程序里,
   "obj-y += subdir/" 表示要进入subdir这个子目录下去寻找文件来编进程序里,是哪些文件由subdir目录下的Makefile决定。
   "EXTRA_CFLAGS",    它给当前目录下的所有文件(不含其下的子目录)设置额外的编译选项, 可以不设置
   "CFLAGS_xxx.o",    它给当前目录下的xxx.c设置它自己的编译选项, 可以不设置

注意: 
1. "subdir/"中的斜杠"/"不可省略
2. 顶层Makefile中的CFLAGS在编译任意一个.c文件时都会使用
3. CFLAGS  EXTRA_CFLAGS  CFLAGS_xxx.o 三者组成xxx.c的编译选项

二、顶层目录的Makefile:
   它除了定义obj-y来指定根目录下要编进程序去的文件、子目录外,
   主要是定义工具链前缀CROSS_COMPILE,
   定义编译参数CFLAGS,
   定义链接参数LDFLAGS,
   这些参数就是文件中用export导出的各变量。

三、顶层目录的Makefile.build:
   这是最复杂的部分,它的功能就是把某个目录及它的所有子目录中、需要编进程序去的文件都编译出来,打包为built-in.o
   详细的讲解请看视频。

四、怎么使用这套Makefile:
1.把顶层Makefile, Makefile.build放入程序的顶层目录
   在各自子目录创建一个空白的Makefile

2.确定编译哪些源文件
   修改顶层目录和各自子目录Makefile的obj-y : 
    obj-y += xxx.o
	obj-y += yyy/
	这表示要编译当前目录下的xxx.c, 要编译当前目录下的yyy子目录	

3. 确定编译选项、链接选项
   修改顶层目录Makefile的CFLAGS,这是编译所有.c文件时都要用的编译选项;
   修改顶层目录Makefile的LDFLAGS,这是链接最后的应用程序时的链接选项;
   
   修改各自子目录下的Makefile:
   "EXTRA_CFLAGS",    它给当前目录下的所有文件(不含其下的子目录)设置额外的编译选项, 可以不设置
   "CFLAGS_xxx.o",    它给当前目录下的xxx.c设置它自己的编译选项, 可以不设置
   
4. 使用哪个编译器?
   修改顶层目录Makefile的CROSS_COMPILE, 用来指定工具链的前缀(比如arm-linux-)
   
5. 确定应用程序的名字:
   修改顶层目录Makefile的TARGET, 这是用来指定编译出来的程序的名字

6. 执行"make"来编译,执行"make clean"来清除,执行"make distclean"来彻底清除

参考路径:

手把手教你写嵌入式Linux中的Makefile(一)_makefile 嵌入式_果果小师弟的博客-CSDN博客

嵌入式Linux应用开发基础知识(七)——通用Makefile使用_韦东山通用makefile sub_零涂的博客-CSDN博客

3.驱动模块开发(下)_CSDN_Xian的博客-CSDN博客

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41882586/article/details/129675031

makefile常见选项说明-爱代码爱编程

1、定位输出文件目录 编译makefile后,会在各个目录下产生很多中间文件,如*.o,makefile支持将这些文件重定向输出 支持两种语法格式。 (1)O= O为大写,后面紧跟重定向目录,如O=out (2) KBUILD_OUTPUT 通过设置环境变量KBUILD_OUTPUT来指定编译输出目录。 如:export KBUILD_

使用makefile编译不同平台目标文件方法_善见致知的博客-爱代码爱编程

使用Makefile编译不同平台目标文件方法 一、源码autoconf、automake生成软件包 1、基础概念 configure.in 这是最重要的文件,整个安装过程都靠它来主导。 Makefile.am auto

makefile-爱代码爱编程

一、概述 1、make:是一个非常重要的编译命令,本质上它是一个程序。利用make工具,可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而

Makefile常用调试方法-爱代码爱编程

转载自 陈皓《跟我一起写 Makefile》《GNU Make项目管理》   GNU make 提供了若干可以协助调试的内置函数以及命令行选项。 1、warning函数 $(warning string)函数可以放在makefile 中的任何地方,执行到该函数时,会将string输出,方便定位make执行到哪个位置。war

Makefile中常见的函数总结归纳-爱代码爱编程

                                                                    Makefile中常见的函数总结归纳 函数调用语法 $(<function> <arguments>) function:函数名 arguments:参数   1.字符串替换函数 $(

mac linux makefile,Makefile简单入门-爱代码爱编程

最近工作编译程序一直在用别人写的Makefile,但是没有系统的学习过,趁着放假学一波 makefile 0x00 Makefile 概述 一个企业级项目,通常会有很多源文件,有时也会按功能、类型、模块分门别类的放在不同的目录中,有时候也会在一个目录里存放了多个程序的源代码。 这时,如何对这些代码的编译就成了个问题。Makefile 就是为

makefile —— 变量赋值 深入窥探 Makefile 变量(1)-爱代码爱编程

文章目录 前言一、变量引用基础二、变量的两个特色三、变量引用高级技术3.1 替换引用3.2 嵌套变量引用(计算的变量名)3.3 设置变量3.4 为变量值追加文本 前言 变量,是在 makefile 中定义的名字,其用来代替一个文本字符串,该文本字符串称为该变量的值。在具体要求下,这些值可以代替目标、依赖、命令以及 makefile 文件中

Makefile语法基础-爱代码爱编程

文章目录 1.Makefile基础1.1Makefile的作用和意义1.2目标、依赖、命令1.3通配符%和Makefile自动推导(规则)1.4Makefile中定义和使用变量1.5伪目标(.PHONY)1.6Makefile的文件名1.7Makfile中引用其他Makefile(include指令)2.Makefile补充知识点2.1Makefi

Makefile教程-爱代码爱编程

工程实例 工程目录 automake.sh #前面可以创建一些目录啥的 # 获取第一个参数,可以删除所有的中间件重新编译 One_Flag=$1 if [ "clean" == "$One_Flag" ]; then rm -rf $PrjDir/Output/Exe/* rm -rf $PrjDir/Output/Obj/*.o

makefile 学习笔记 四:makefile 函数-爱代码爱编程

详细内容见 《GNU make》 8 Functions for Transforming Text 章节。 函数允许您在 makefile 中进行文本处理,以计算要操作的文件或配方中要使用的命令。函数调用中使用函数,在函数调用中,您可以提供函数的名称和一些文本(参数),以便函数进行操作。函数的处理结果在调用时被替换到 makefile 中,就

makefile 学习笔记 二:makefile变量-爱代码爱编程

一、变量定义语法 变量的名称 = 值列表 变量的名称可以由大小写字母、阿拉伯数字和下划线构成。 等号左右的空白符没有明确的要求,因为在执行 make 的时候多余的空白符会被自动的删除。 至于值列表,既可以是零项,又可以是一项或者是多项。 变量使用可以用 $( ) 或 ${ } 二、变量赋值 1、赋值符 简单赋值 ( := ) 编程语言中

makefile 学习笔记 九:makefile中使用隐式规则-爱代码爱编程

详细内容见 《GNU make》 10 Using Implicit Rules 章节。 某些重制目标文件的标准方法经常被使用。例如,创建目标文件的一种习惯方法是使用 C 编译器 cc 从 C 源文件中获取目标文件。 隐式规则告诉 A 如何使用习惯技巧,这样当你想要使用它们时,就不必详细地指定它们。例如,有一个用于C编译的隐式规则。文件名确定

make的使用和makefile的编写-爱代码爱编程

make的使用和makefile的编写什么是makemake机制概述make工具的最初设计目的是为了维护C程序文件,防止不必要的重新编译。make工具对于维护一些具有相互依赖关系的文件特别有用,其对,文件和命令的联系提供一套编码方法。在使用过程中只告诉make需要做什么,即提供一些规则,其他工作由make完成。make工具的工作是自动确定工程的那部分源程序

【Makefile 文件,gcc常见编译参数说明】-爱代码爱编程

1.【$<】【$@】 【$?】【$^】参数说明 $@ 表示目标文件 $^ 表示所有的依赖文件 $< 表示第一个依赖文件 $? 表示比目标还要新的依赖文件列表 详细说明链接:https://www.bbsmax.com/A/RnJWOrpBJq/ 2.【-O0 】【-O1】【-O2 】【 -O3】【 -OS】 -O0: 不做任何

makefile的规则和写法常见使用说明_genson丶tan的博客-爱代码爱编程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Makefile 语法Makefile规则格式Makefile变量Makefile模式规则Makefile伪目标Makefile条件判断Makefile函数使用常见的Makefile函数总结 Makefile 语法 Makefile规则格式 规则格式如下

makefile 常用 详解_6kkk的博客-爱代码爱编程

1)Makefile基本格式如下: target ... : prerequisites ...     command     ...     ... target         //目标文件, 可以是 Object File, 也可以是可执行文件 prerequisites  //生成 target 所需要的文件或者目标 command      

hadoop集群---方便的脚本-爱代码爱编程

目录 为什么编写脚本? myhadoop.sh 群起集群、关闭集群脚本 1、配置 2、启用 jpsall 查看三台主机进程脚本 1、配置 2、启用 xsync 分发脚本 1、配置 2、启用 为什么编写脚本? 方便 myhadoop.sh 群起集群、关闭集群脚本 1、配置 在 root/bin 目录下创建脚本 (在