hi3559 C/C++混编 makefile(基于官方sample)

简介: 由于个人需要想做海思的C++和C混编,好像不认真学一学makefile不行了本人博客,csdn搬运main函数是卸载cpp里面的,写在c里面的就是给你们提供一个思路了弄明白了有空自己写呐,海思的makefile感觉嵌套的太冗余了,正常开发一个片子用不到呐

由于个人需要想做海思的C++和C混编,好像不认真学一学makefile不行了

hi3559 C/C++混编

3559给的SDK的makefile是嵌套的,想用官方的SDK的话,如果对makefile 不熟悉,就只能用官方给的Makefile,在上面修改,如果你很厉害,能看得懂,层层嵌套也得花个一天半天的整理一个自己用着舒服的Makefile模板,这里先说直接在他的sample下改,如果之后有时间我再做一个自用版本的makefile

上来先说解决方案

我是在2.0.3.0的版本上面改的,但是根据个人经验,不同版本的SDK的sample嵌套差距不大

  1. 在"/Hi3559AV100_SDK_V2.0.3.0/mpp/sample/"路径下,把vio copy一份出来,细节不说了,这里主要是要改他的Makefile,.c文件、.cpp文件可以删了自己写
  2. 修改"/Hi3559AV100_SDK_V2.0.3.0/mpp/sample/vio_2"路径下的Makefile,增加如下几行
CFLAGS += -I$(PWD)
SRCPPS :=  $(wildcard *.cpp)
TARGETCPP :=  $(SRCPPS:%.cpp=%)
  1. 按照他的嵌套,修改"Hi3559AV100_SDK_V2.0.3.0/mpp/Makefile.linux.param",找到[export CC:=$(CROSS)gcc]这句话,在后面加上一句,加完了之后大概是下面这样
export CC:=$(CROSS)gcc
export AR:=$(CROSS)ar
export CXX:=$(CROSS)g++
  1. 最后按照他的嵌套规则,修改"Hi3559AV100_SDK_V2.0.3.0/mpp/sample/linux.mak"在前面修改和增加下面几行
OBJS  := $(SRCS:%.c=%.o) 
OBJCPPS  := $(SRCPPS:%.cpp=%.o)

.PHONY : clean all

all: $(TARGETCPP) 
# all: $(TARGET) 

CXXFLAGS :=$(CFLAGS) 

$(TARGETCPP):$(OBJS) $(OBJCPPS) $(COMM_OBJ) 
    $(CXX) $(CFLAGS) $(LIBS_LD_CFLAGS) -lpthread -lm -o $@ $^ -Wl,--start-group $(MPI_LIBS) $(SENSOR_LIBS) $(AUDIO_LIBA) $(REL_LIB)/libsecurec.a -Wl,--end-group
# $(TARGET): $(COMM_OBJ) $(OBJS)
#     $(CC) $(CFLAGS) $(LIBS_LD_CFLAGS) -lpthread -lm -o $@ $^ -Wl,--start-group $(MPI_LIBS) $(SENSOR_LIBS) $(AUDIO_LIBA) $(REL_LIB)/libsecurec.a -Wl,--end-group
clean:
    @rm -f $(TARGET)
    @rm -f $(OBJS)
    @rm -f $(COMM_OBJ)
    @rm -f $(TARGETCPP)
    @rm -f $(OBJCPPS)

5.如果正常编译纯c目标,应该把all: $(TARGETCPP) 注释,把4中的注释打开,防止日后我自己看不懂,在这里多说一嘴

另外如果要用NNIE

增加下面一句

MPI_LIBS += $(REL_LIB)/libnnie.a

另外如果要用opencv

增加下面两句

CFLAGS += -I$(PWD)  -I/home/xxx/Hisi3559A_Yolov5-master/third_party/opencv4/include/opencv4 -lopencv_highgui -lopencv_features2d -lopencv_flann -lopencv_calib3d -lopencv_objdetect -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core -fpermissive 
LIBS_LD_CFLAGS += -L/home/xxx/Hisi3559A_Yolov5-master/third_party/opencv4/lib 

其中
home/xxx/Hisi3559A_Yolov5-master/third_party/opencv4/include/opencv4:opencv的包含文件
/home/xxx/Hisi3559A_Yolov5-master/third_party/opencv4/lib:opencv4编译出来的.so文件的位置
-lopencv_highgui -lopencv_features2d -lopencv_flann -lopencv_calib3d -lopencv_objdetect -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core:你可能用到的opencv的动态链接库

后面说一下原理
想看原理点个关注吧,最近想冲数据,而且确实弄了好几天

原理

也不是特别好解释,我也了解的不太深,就通俗易懂的说说我的理解
海思的makefile 是层层嵌套的,你看vio的makefile,上来就先载入了参数,最后又载入了一个mak

include ../Makefile.param
include $(PWD)/../$(OSTYPE).mak 

然后我们再看Hi3559AV100_SDK_V2.0.3.0/mpp/sample/Makefile.param
这个参数文档里面入了给一堆编译参数赋值之外最醒目亮眼的就是下面这句

ifeq ($(PARAM_FILE), )
     PARAM_FILE:=../../Makefile.param
     include $(PARAM_FILE)
endif

他在判空PARAM_FILE,如果这个变量是空,那么给他赋值并include,可能和.h文件的#ifndf是一个意思,怕重复调用,然后他有嵌套出来了一个关联文件Hi3559AV100_SDK_V2.0.3.0/mpp/Makefile.param
这个文件除了指定一堆编译指令,路径,环境之外,我们主要就是找嵌套。也就是这两句

include $(PARAM_DIR)/cfg.mak
include $(MPP_PATH)/Makefile.$(OSTYPE).param

这两句
之后如果有什么参数想改,也是要来这些地方ctrl+F的
其中Hi3559AV100_SDK_V2.0.3.0/mpp/cfg.mak,暂时没什么卵用,我们主要看Hi3559AV100_SDK_V2.0.3.0/mpp/Makefile.linux.param,因为我的目标平台是linux
在这个文件里面能找到$(CC),相关的赋值,这个东西是export CC:=$(CROSS)gcc,然后捋着我们来时的路可以发现,这句话相当于CC:=aarch64-himix100-linux-gcc
然后全局手工遍历CXX,我没找到,就给他加了一句export CXX:=$(CROSS)g++
能这么干的前提是你在命令行里输入aarch64-himix100-linux-g++这个指令是不报错的

至此,他载入参数这条线结束了,然后我们看include $(PWD)/../$(OSTYPE).mak,这个mak文件
直接全贴上来,逐句解析,下面的应该很贴近原始文件了

# target source
OBJS  := $(SRCS:%.c=%.o) # [1]目标文件从SRCS正则生成,SRCS中含有.c的字符串去掉.c 加一个.o,空格分开,生成OBJS目标文件

.PHONY : clean all# [2]指定两个伪目标,clean、all
# 其中all 的目标是生成target ,target是在vio下的makefile指定的,我这里是.c文件去了.c,也有可能是一个指定名字
all: $(TARGET) 
# [3]TARGET的依赖有COMM_OBJ,OBJS,在这两个玩意都生成了之后再执行本语句包含的下面那一行指令
$(TARGET): $(COMM_OBJ) $(OBJS)
    # [5]在隐式生成.o文件之后,调用下面的语句,下面这条语句的大多数相信你已经能猜出来是什么了,麻烦的是这两个玩意$@ $^
    # $@ : 规则的目标所定义的文件名 
    # $^ : 规则中的第一个文件名
    # 经过个人发现,这个target如果有多个的话,是会遍历完所有的生成目标项的,也就是$^位置,每次填充一个target
    # 至于这个东西,$@ ,应该是$(COMM_OBJ) $(OBJS)中的所有.o文件,空格隔开
     $(CC) $(CFLAGS) $(LIBS_LD_CFLAGS) -lpthread -lm -o $@ $^ -Wl,--start-group $(MPI_LIBS) $(SENSOR_LIBS) $(AUDIO_LIBA) $(REL_LIB)/libsecurec.a -Wl,--end-group
    # [6] 原始文件的这句话前面应该有个@ ,放在指令前面的@是用于说明本条语句不输出的,为了方便观察他的语句执行效果,我给去了,也没加回来。
# [4]这里说一下$(COMM_OBJ) $(OBJS)这俩玩意是怎么生成的,makefile有隐式生成规则
# 就是你的目标文件如果没有说是怎么来的,他就自动在你的文件夹下给你找同名文件编译,编译的指令,如果是C,就$(CC)编译,编译指令是$(CFLAGS),链接的库在$(LIBS_LD_CFLAGS),C++的话就是$(CXX)编译$(CXXFLAGS)
# 也就是说,这里列举了两个目标文件,这两个目标文件都采用默认的语句自动生成,生成结果是对应的.o文件

clean:
    @rm -f $(TARGET)
    @rm -f $(OBJS)
    @rm -f $(COMM_OBJ)

cleanstream:
    @rm -f *.h264
    @rm -f *.h265
    @rm -f *.jpg
    @rm -f *.mjp
    @rm -f *.mp4

编译通过基本就没问题了

相关实践学习
使用CLup和iSCSI共享盘快速体验PolarDB for PostgtreSQL
在Clup云管控平台中快速体验创建与管理在iSCSI共享盘上的PolarDB for PostgtreSQL。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
4天前
|
算法 API 计算机视觉
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
31 0
|
4天前
|
人工智能 Shell 编译器
C/C++编译工具:makefile | AI工程化部署
Makefile是一种用于管理和组织源代码的工具,通常用于构建和编译软件项目。它由一系列规则组成,每个规则指定如何生成一个或多个目标文件。Makefile也包括变量和注释,使得用户能够灵活地配置和定制构建过程。【1月更文挑战第3天】
141 3
|
4天前
|
JSON NoSQL C++
VScode调试C/C++项目调试多个C++程序makefile
VScode调试C/C++项目调试多个C++程序makefile
83 0
|
6月前
|
IDE 开发工具 C++
C++项目实战-makefile
C++项目实战-makefile
33 0
|
12月前
|
安全 编译器 测试技术
C/C++项目构建指南:如何使用Makefile提高开发效率
Makefile是一个常用的自动化构建工具,它可以为开发人员提供方便的项目构建方式。在C/C++项目中,Makefile可以用来编译、链接和生成可执行文件。使用Makefile的好处是可以自动执行一系列命令,从而减少手动操作的复杂性和出错的可能性。此外,Makefile还可以根据源代码的修改情况,自动更新目标文件,从而提高了构建的效率和准确性
120 0
|
C++
C/C++混编“未定义的引用”的解决一例
C/C++混编“未定义的引用”的解决一例
172 0
|
算法 C++
LeetCode两数之和-初学C++ 官方哈希解法代码注释-C++代码
LeetCode两数之和-初学C++ 官方哈希解法代码注释-C++代码
|
Java 编译器 Linux
【CMake】CMake 引入 ( Android Studio 创建 Native C++ 工程 | C/C++ 源码编译过程 | Makefile 工具 | CMake 引入 )(二)
【CMake】CMake 引入 ( Android Studio 创建 Native C++ 工程 | C/C++ 源码编译过程 | Makefile 工具 | CMake 引入 )(二)
273 0
【CMake】CMake 引入 ( Android Studio 创建 Native C++ 工程 | C/C++ 源码编译过程 | Makefile 工具 | CMake 引入 )(二)