Makefile解析(ARM LINLON V5/V7 VPU firmware tools例)

根目录Makefile

初始化一些变量
TARGETS := model executiontb cpu
ROOT_DIR?=$(abspath $(CURDIR))
OUT_DIR?=$(abspath $(CURDIR))
ADDR_FILE:=$(ROOT_DIR)/build/mmu_addr.txt

make all 执行 make help
all: help

.PHONY后面跟的目标都被称为伪目标,也就是说我们 make 命令后面跟的参数如果出现在.PHONY 定义的伪目标中,那就直接在Makefile中就执行伪目标的依赖和命令。不管Makefile同级目录下是否有该伪目标同名的文件,即使有也不会产生冲突。另一个就是提高执行makefile时的效率
.PHONY: session_dump_file
session_dump_file:
ifndef SESSION_DUMP
        $(error No SESSION_DUMP file provided)
endif
echo和@echo的区别
  make 在执行命令之前会把要执行的命令进行输出,称之为回显
  如果要执行的命令以字符 @ 开始,则不会回显,例如:
1. @echo XXX
  在执行命令时,将输出  
   XXX
2. echo XXX
  在执行命令时,将输出    
   echo XXX    
   XXX
        @echo "Binarizing $(SESSION_DUMP) -> ${OUT_DIR}/src/session_dump.c"
        build/bin2a.sh -l $(SESSION_DUMP) g_session_dump > ${OUT_DIR}/src/session_dump.c

.PHONY: self_check
self_check:
ifdef SELF_CHECK
        @echo "SELF_CHECK enabled: Binarizing $(SELF_CHECK) -> ${OUT_DIR}/src/self_check_reference.c"
        build/bin2a.sh -i $(SELF_CHECK) g_self_check_reference > ${OUT_DIR}/src/self_check_reference.c
endif

define
endef
定义一个函数
可以通过$(call xxx)来进行调用
define target_rule
$(1): session_dump_file self_check
ifeq ($(PRE_CONVERT_PTABLE), 1)
        $$(MAKE) -f build/compile-$(1).mk ROOT_DIR=$(ROOT_DIR) OUT_DIR=$(OUT_DIR) ADDR_FILE=$(ADDR_FILE) 
        python $(ROOT_DIR)/build/mmu_restore.py -i $(SESSION_DUMP) -s $(ADDR_FILE) -b 0
        /bin/rm -rf obj bin
        /bin/rm $(ADDR_FILE)
        /bin/mv $(SESSION_DUMP).tmp $(SESSION_DUMP)
        build/bin2a.sh -l $(SESSION_DUMP) g_session_dump > ${OUT_DIR}/src/session_dump.c
endif
顶层Makefile使用make -f调用子目录中的文件(文件名可以随意,不一定用Makefile作为文件名)作为Makefile,经测试,在顶层Makefile中使用-f选项,例如make -f ./xxx/xx/build.mk 此时make命令的工作目录仍然是顶层目录,即CUDIR变量依然是./目录而不是./xxx/xx/目录
        $$(MAKE) -f build/compile-$(1).mk ROOT_DIR=$(ROOT_DIR) OUT_DIR=$(OUT_DIR)

.PHONY: $(1)
endef

$(foreach target,$(TARGETS),$(eval $(call target_rule,$(target))))

clean: realclean

realclean:
        @echo "Removing obj & bin"
        /bin/rm -rf obj bin

TARBALL = $(abspath $(CURDIR)/../$(notdir $(CURDIR)).tar.bz2)

tarball: realclean
        @echo "Packaging $(TARBALL)"
        cd ..; \
        tar cjf $(TARBALL) $(notdir $(CURDIR))

help:
        @echo "==============================="
        @echo ""
        @echo "make SESSION_DUMP=session_dump.mvedump"
        @echo "     [AFBC=1]"
        @echo "     [ARCH=MVE550] [CPU=8-A.32] [MCPU=a53] [OPTS=\"<extra compile flags>\"]"
        @echo "     [START_ADDRESS=0x80008000] [HEAP_ADDRESS=0x86000000] [UNCACHED_BUFFER=0x88000000]"
        @echo "     [MODEL_LIB=<model library>]"
        @echo "     [SELF_CHECK=<reference_output_file>]"
        @echo "     [ $(foreach target,$(TARGETS),$(target) |) tarball | clean | realclean ]"
        @echo ""
        @echo "SESSION_DUMP     : Dump file created with mve_decode/mve_encode with option --save_session"
        @echo "START_ADDRESS    : Binary image entry point"
        @echo "HEAP_ADDRESS     : Heap & stack address. Please see generated scatter file"
        @echo "UNCACHED_BUFFER  : Uncached memory region where output buffers are allocated"
        @echo "OPTS             : Extra compile flags passed to the source."
        @echo "                       -DMVEVERBOSE - extra verbose"
        @echo "                       -DMVEDEBUG   - extra debug"
        @echo "                       -DDHEAP_SIZE - size of memory pool for dynamic allocation. If not specified"
        @echo "                                      160MB (0xA000000) is used. Please note that aprox. 6.5MB"
        @echo "                                      (6.7MiB) and 25MB (25.9MiB) is needed per HD and UHD frame"
        @echo "                                      respectively."
        @echo "SELF_CHECK       : Enable built-in comparison with output reference file, instead of saving output"
        @echo "NO_UART          : UART is not present in the testbench"
        @echo "NO_GIC           : GIC is not present in the testbench"
        @echo "clean            : Clean all binary and object files"
        @echo "realclean        : Clean all binary and object files"
        @echo ""
        @echo "==============================="

.PHONY: clean realclean tarball help

common.mk

检查变量
ifeq ($(ROOT_DIR),)
$(error "ROOT_DIR is not defined")
endif

ifeq ($(OBJ_DIR),)
$(error "OBJ_DIR is not defined")
endif

ifeq ($(BIN_DIR),)
$(error "BIN_DIR is not defined")
endif

ifeq ($(SESSION_DUMP),)
$(error "SESSION_DUMP is not defined")
endif

ifdef SELF_CHECK
CHECK=1
else
CHECK=0
endif

CREATE_VARIOUS_DIRS__EVAL_FOR_SIDE_EFFECTS := $(shell mkdir -p $(OBJ_DIR) && mkdir -p $(BIN_DIR))

# Case
upper_case = $(shell echo $(1) | tr a-z A-Z)
lower_case = $(shell echo $(1) | tr A-Z a-z)

# Hash
# $(1) : Prefix
# $(2) : String
hash = $(1)_$(shell echo $(2) | md5sum | cut -d ' ' -f1)

ARCH ?= MVE550

# Top main source file
TOP_MAIN := src/miniplayer.c
TEST_OBJS := $(OBJ_DIR)/$(subst .c,.o,$(notdir $(TOP_MAIN)))

# User CFLAGS
COMMON_OPTS := $(OPTS)
COMMON_OPTS += $(if $(MVE_BASE), -DMVE_BASE=$(MVE_BASE),)
COMMON_OPTS += $(if $(MVE_IRQ),  -DMVE_IRQ=$(MVE_IRQ),)
COMMON_OPTS += $(if $(IN_FILE),  -DIN_FILE=\"$(IN_FILE)\",)
COMMON_OPTS += $(if $(OUT_FILE), -DOUT_FILE=\"$(OUT_FILE)\",)
COMMON_OPTS += $(if $(filter 1, $(SAVE_SESSION_V2)), -DSAVE_SESSION_V2,)
COMMON_OPTS += -DMEM_MAPPING_INFO

# 64/32 bit builds
ifndef SYSTEM
ifeq ($(shell uname -m),x86_64)
SYSTEM := 64
else
SYSTEM := 32
endif
$(info "SYSTEM is not defined. Using SYSTEM=$(SYSTEM)")
endif

# Generate source file from binary
# $(1) : Source binary dir
# $(2) : Source binary file variable name
# $(3) : Int array
# $(4) : Target C array name
define bin2a_rule
$(2)_C := $(OBJ_DIR)/$(call hash,auto_gen_$(call lower_case,$(2)),$(1)/$($(2))).c
$$($(2)_C): ./build/bin2a.sh $(1)/$($(2))
        @echo "Generating $$@"
        rm -rf $(OBJ_DIR)/auto_gen_$(call lower_case,$(2))_*
        $$< $(if $(3),-i,-c) $(1)/$($(2)) $(4) > $$@
endef

# Generate this rule to track CFLAGS and embedded file name changes
# $(1) : All concerned objects
# $(2) : CFLAGS variable
define cflags_rule
$(1): $(OBJ_DIR)/CFLAGS
.PHONY: force
$(OBJ_DIR)/CFLAGS: force
        test -e $$@ || touch $$@
        echo "$(2)" > $$@.tmp
        cmp -s $$@ $$@.tmp || cp $$@.tmp $$@
        rm $$@.tmp
endef

compile-module.mk

初始化变量
TARGET_DIR := model
OBJ_DIR ?= $(ROOT_DIR)/obj/$(TARGET_DIR)
BIN_DIR ?= $(ROOT_DIR)/bin/$(TARGET_DIR)


# Build testbench by default
all: model

include $(ROOT_DIR)/build/common.mk

CC := gcc
LD := gcc
AR := ar

###############################################################################
#
# Model
#

定义编译出来的执行文件
model: $(BIN_DIR)/model_test

定义要编译的源文件
MODEL_SRCS := src/mve_communication.c \
                         src/mve_core.c \
                         src/mve_fw_manager.c \
                         src/mve_hw.c \
                         src/mve_mmu.c \
                         src/mve_port_linux_emul.c \
                         src/mve_port_linux_emul_utils.c \
                         src/session_dump.c \
                         $(TOP_MAIN)

#ifdef SELF_CHECK
#CHECK=1
#else
#CHECK=0
#endif

addprefix 是makefile中的函数,是添加前缀的函数
例如:
$(addprefix src/,foo bar)
返回值为“src/foo src/bar”
SRCS_ABS := $(addprefix $(ROOT_DIR)/,$(MODEL_SRCS))

MODEL_DIR := $(ROOT_DIR)/../model

MODEL_LIB ?= $(MODEL_DIR)/libmvemodel$(SYSTEM).so

wildcard, $(wildcard 指定文件类型), 显示指定路径下指定文件类型的所有文件
ifeq ($(wildcard $(MODEL_LIB)),)
$(error "Can't find $(MODEL_LIB)")
endif

MODEL_CFLAGS  := -D_POSIX_C_SOURCE=199309L -O2 -m$(SYSTEM) -std=c99 -pthread -DTARGET_LINUX$(SYSTEM) 
$(dir <names...> )
名称:取目录函数——dir。
功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。返回:返回文件名序列<names>的目录部分。示例: $(dir src/foo.c hacks)返回值是“src/ ./”
$(if $(filter 1,$(CHECK)),-DMVE_SELF_CHECK=1,) -I$(dir $(MODEL_LIB)) $(INC_COMMON) $(COMMON_OPTS)
MODEL_LDFLAGS := -m$(SYSTEM) -pthread $(COMMON_OPTS)
MODEL_LDLIBS  := -lm -lrt

notdir
名称:取文件函数——notdir。包括后缀,去除文件夹路径
功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“/”
)之后的部分。
返回:返回文件名序列<names>的非目录部分。
示例: $(notdir src/foo.c hacks)返回值是“foo.c hacks”
get_model_obj = $(addprefix $(OBJ_DIR)/,$(notdir $(patsubst %.c,%.o,$(1))))

define model_rule
$(call get_model_obj,$(1)): $(1) $(OMX_DIR)
        @echo "Compiling $1"
        $(CC) -MM -MG $(MODEL_CFLAGS) $$< | sed -e 's,^\([^:]*\)\.o[ ]*:,$$(@D)/\1.o $$(@D)/\1.d:,' >$$(@:.o=.d)
        $(CC) -c -o $$@ $1 $(MODEL_CFLAGS)
endef

$(foreach file,$(SRCS_ABS),$(eval $(call model_rule,$(file))))

OBJS := $(call get_model_obj,$(SRCS_ABS))

$(BIN_DIR)/model_test: $(OBJS) $(MODEL_LIB)
        @echo " >> Building $@"
        $(LD) -o $@ $(MODEL_LDFLAGS) $^ $(MODEL_LDLIBS)

###############################################################################
#
# CFLAGS
#
#
$(eval $(call cflags_rule,$(OBJS),$(MODEL_CFLAGS) $(MODEL_LDFLAGS) $(MODEL_LIB)))

###############################################################################
#
# Dependencies
#

DEPS := $(OBJS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/606177.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RS485空调系统到BACnet江森楼宇系统的高效整合攻略

智慧城市的每一栋建筑都在追求更高的能效与更佳的居住体验&#xff0c;而这一切的实现离不开强大且灵活的楼宇自动化系统。其中&#xff0c;协议转换网关作为连接不同设备的纽带&#xff0c;扮演着至关重要的角色。本文将以一个典型的商业综合体为例&#xff0c;揭秘BACnet协议…

北交所佣金费率标准是多少?北交所相关信息科普

北交所的佣金费率并非固定不变&#xff0c;而是可以根据投资者的需求和证券公司的政策进行调整。目前北交所的佣金费率最低是万分之二。 一般来说&#xff0c;北交所的佣金费率默认在万分之三左右&#xff0c;但这不是固定的费率。根据证券公司的不同&#xff0c;佣金费率可以…

语义分割——前列腺分割数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

微服务学习笔记

微服务学习笔记 文章目录 微服务学习笔记认识微服务微服务技术栈微服务学习要点微服务远程调用1)注册RestTemplate2) 服务远程调用RestTemplate Eureka注册中心简介操作过程搭建EurekaServer注册user-service在order-service完成服务拉取 Ribbon负载均衡IRule负载均衡策略饥饿加…

Electron学习笔记(二)

文章目录 相关笔记笔记说明 三、引入现代前端框架1、配置 webpack&#xff08;1&#xff09;安装 webpack 和 electron-webpack&#xff1a;&#xff08;2&#xff09;自定义入口页面 2、引入 Vue&#xff08;1&#xff09;安装 Vue CLI &#xff08;2&#xff09;调试配置 -- …

【Micropython Pitaya Lite教程】烧录固件

文章目录 前言一、编译固件源码二、烧录固件总结 前言 MicroPython是一种精简的Python 3解释器&#xff0c;可以在微控制器和嵌入式系统上运行。Pitaya Lite是一款基于ESP32的微控制器开发板&#xff0c;它结合了低功耗、Wi-Fi和蓝牙功能。结合MicroPython和Pitaya Lite&#…

Python AI库pandas读写数据库的应用操作——以sqlite3为例

Python AI库pandas读写数据库的应用操作——以sqlite3为例 本文默认读者具备以下技能&#xff1a; 熟悉python基础知识&#xff0c;vscode或其它编辑工具 已阅读Pandas基础操作文章,了解pandas常见操作 具备自主扩展学习能力 在数据分析和人工智能领域&#xff0c;pandas库和s…

Ruby中的字符串转换方法

在Ruby中&#xff0c;你可以使用各种方法来转换字符串。下面是一些常用的方法&#xff0c;当然选择哪种适用的方法还得更具具体项目来做调整。日常使用中下面的错误也是比较常见的&#xff0c;看看我们怎么处理哈。 1、问题背景 在Python中&#xff0c;内置的数据结构都有一个…

VMware 虚拟机打开一段时间后卡死,VNX进程CPU占比高

一、问题描述 打开虚拟机后可以正常运行 运行几分钟后突然卡死 然后通过任务管理器可以观察到VMware Workstation VMX应用进程的CPU占比高&#xff0c;CPU也出现异常 关闭虚拟机重新开启&#xff0c;还是一样卡死 二、系统环境 系统: Windows10 VMware: Workstation 17 Pro …

visa/masterCard虚拟信用卡可以用于欧洲亚马逊店Amazon铺吗?欧洲亚马逊Amazon店铺扣租金

亚马逊是网络上最早开始经营电子商务的公司之一&#xff0c;亚马逊成立于1995年&#xff0c;一开始只经营网络的书籍销售业务&#xff0c;现在则扩及了范围相当广的其他产品&#xff0c;已成为全球商品品种最多的网上零售商和全球互联网企业。 很多小伙伴需要开多个站点店铺&a…

软胶囊硬度计:QC部门保障药品质量的精准工具

软胶囊硬度计&#xff1a;QC部门保障药品质量的精准工具 一、引言 随着医药行业的快速发展和药品监管力度的加强&#xff0c;制药企业对于药品质量的要求越来越高。在药品的生产过程中&#xff0c;软胶囊作为一种常见的剂型&#xff0c;其硬度的控制对于药品质量至关重要。软胶…

数组进了多个obj,但是 在修改某个num值时,导致别的num值也发生了变化如何解决?

问题如下&#xff1a; 遇到的问题&#xff0c;数组monthArr1 push进了多个obj,但是 在修改某个num值时&#xff0c;导致别的num值也发生了变化。 而这就是深拷贝浅拷贝的问题。 解决浅拷贝使用深拷贝最简单方法 &#xff1a;JSON.parse(JSON.stringify(obj)) 或者: 使用深拷…

学习Java的日子 Day44 HTML基础

Day44 HTML 学习路线&#xff1a; 前端&#xff1a;展示页面、与用户交互 — HTML 后端&#xff1a;数据的交互和传递 — JavaEE/JavaWeb 1.网页的组成部分(HTMLCSSJavaScript) 前端开发的工作模式&#xff1a;开发输出htmlcssjs HTML&#xff1a;页面结构 CSS&#xff1a;页面…

【linux】——日志分析

1. 日志文件 1.1 日志文件的分类 日志文件&#xff1a; 是用于记录Linux系统中各种运行消息的文件&#xff0c;相当于Linux主机的“日记". 日志文件对于诊断和解决系统中的问题很有帮助&#xff0c;系统一旦出现问题时及时分析日志就会“有据可查”。此外。当主机遭受攻…

JVM的垃圾回收

JVM简介 JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机。 虚拟机:是指通过软件模拟的具有完整硬件功能、运行在一个完全隔离的环境中完整计算机系统 1.JVM的内存区域划分 jvm是一个java进程 每一个java进程就是一个jvm实例 一个进程运行过程中 就要从操作系…

uniapp0基础编写安卓原生插件之编写安卓页面在uniapp上显示(摄像头调用)

前言 如果你对安卓插件开发部分不熟悉你可以先看uniapp0基础编写安卓原生插件和调用第三方jar包和编写语音播报插件之零基础编写安卓插件 效果 开始 dcloud_uniplugins.json {"nativePlugins": [{"hooksClass": "","plugins": [{&…

软件试运行方案,试运行报告(word原件获取)

一、 试运行目的 &#xff08;一&#xff09; 系统功能、性能与稳定性考核 &#xff08;二&#xff09; 系统在各种环境和工况条件下的工作稳定性和可靠性 &#xff08;三&#xff09; 检验系统实际应用效果和应用功能的完善 &#xff08;四&#xff09; 健全系统运行管理体制&…

Pspice for TI学习

Pspice for TI中PSpice Part Search空白解决方法 配置环境变量 Cad_PSpice_TI_Regr_Srvr https://software-dl.ti.com/pspice/S009 重新安装2023版的Pspice Pspice安装链接 打开新安装的软件即可发现PSpice Part Search可以正常使用了 VSIN各参赛的含义 VOFF直流偏置VAMPL…

JavaEE企业级开发中常用的Stream流

介绍 在Java编程中&#xff0c;Stream流是Java 8引入的一个重要概念&#xff0c;它提供了一种新的处理集合的方式&#xff0c;可以更加简洁、高效地进行数据操作。Stream流支持各种常见的操作&#xff0c;比如过滤、映射、排序、聚合等&#xff0c;同时也支持并行处理&#xf…

Vue 项目 尚品汇(二)(暂停进行)

一、Home 模块组件拆分 基本流程 先写静态页面 拆分静态组件 获取服务器的数据进行展示 动态业务 &#xff08;一&#xff09;三级联动组件 如果一个组件在很多模块之间都在使用&#xff0c;我们就拆分成成一个全局组件 只需注册一次 在全局的项目都能使用 三级联动在 …