文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

跟着小白一起学鸿蒙 [四]移植一个开源库

2024-12-01 14:01

关注

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

本节我们讨论下如果引用一个开源三方库,引入OpenHarmony编译并在设备上运行。

1、开源库结构

我们选取比较简单的linux-logo开源库(库地址为:https://github.com/deater/linux_logo)。

.
├── configure
├── contrib
├── libsysinfo-0.3.0
├── linux_logo.c
├── LINUX_LOGO.FAQ
├── linux_logo.h
├── ll_asm
├── load_logo.c
├── load_logo.h
├── load_logos.h
├── logo_config
├── logo_config.BSD
├── logo_config.Irix
├── logo_config.Solaris
├── logos
├── logo_types.h
├── parse_logos
├── parse_logos.c
├── po
├── tests

2、在linux下的运行步骤和结果

3、移植到鸿蒙系统下进行编译运行

移植到鸿蒙需要在三方库里增加文件夹和gn文件。OpenHarmony里三方库的位置在[代码目录]/third_party位置。

我们可以在三方库里创建文件夹:linuxlogo,然后在linuxlogo里创建BUILD.gn文件。接下来我们需要拷贝第三方linuxlog文件到此文件夹内。然后我们需要阅读三方库的Makefile文件。以下是基本的makefile的规则:

target... : prerequisites ...
command
...
-----------------------------------------------------------------

这是一个文件的依赖关系,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。这就是整个make的依赖性。

1. 读入所有的Makefile。

2. 读入被include的其它Makefile。

3. 初始化文件中的变量。

4. 推导隐晦规则,并分析所有规则。

5. 为所有的目标文件创建依赖关系链。

6. 根据依赖关系,决定哪些目标要重新生成。

7. 执行生成命令。

Makefile 会告诉make 命令做什么(通常是如何编译和链接程序)。

路径: /../Makefile
-include Makefile.default
PROGNAME = linux_logo
#ifeq ($(OS),IRIX64)
# LDFLAGS += -lintl
#endif
ifeq ($(OS),FreeBSD)
LDFLAGS += -lintl
endif
#
# Installation location
#
INSTALL_BINPATH = $(DESTDIR)$(PREFIX)/bin
INSTALL_MANPATH = $(DESTDIR)$(PREFIX)/share/man
INSTALL_DOCPATH = $(DESTDIR)$(PREFIX)/share/doc
#
# Libsysinfo location
#
LIBSYSINFO_INCLUDE = -I$(LIBSYSINFO)
LIBSYSINFO_LIBRARY = -L$(LIBSYSINFO)
ifneq ($(XGETTEXT),)
TRANSLATIONS = translations
endif
all: Makefile.default parse_logos linux_logo $(TRANSLATIONS)
Makefile.default:
ifneq($(CONFIGURE_RAN),1)
$(error Please run configure first)
endif
translations:
cd po && $(MAKE)
logos-all: logo_config
find ./logos -type f -a ! -name banner.logo -a ! -name classic.logo | sort >> logo_config
$(MAKE) all
logo_config:
echo "./logos/banner.logo" > logo_config
echo "./logos/classic.logo" >> logo_config

clean: Makefile.default
rm -f *.o
rm -f linux_logo linux_logo-dyn parse_logos load_logos.h
rm -f *~
cd $(LIBSYSINFO) && $(MAKE) clean
cd po && $(MAKE) clean
distclean: clean
cd $(LIBSYSINFO) && $(MAKE) distclean
rm -f Makefile.default logo_config
# rm -f po/linux_logo.pot
#此处即为我们最终生成的linux_logo二进制文件,他依赖linux_logo.o,load_logo.o两个中间文件和libsysinfo.a这个库
linux_logo: linux_logo.o load_logo.o ./$(LIBSYSINFO)/libsysinfo.a
$(CROSS)$(CC) $(LDFLAGS) -o linux_logo linux_logo.o load_logo.o $(LIBSYSINFO_LIBRARY) ./$(LIBSYSINFO)/libsysinfo.a

linux_logo_shared: linux_logo.o load_logo.o ./$(LIBSYSINFO)/libsysinfo.a
$(CROSS)$(CC) $(CFLAGS) -o linux_logo-dyn linux_logo.o load_logo.o $(LIBSYSINFO_LIBRARY) -lsysinfo

#此处为libsysinfo.a库的编译脚本,他会进入$(LIBSYSINFO)目录再执行make命令
./$(LIBSYSINFO)/libsysinfo.a:
cd $(LIBSYSINFO) && $(MAKE)

parse_logos: parse_logos.o load_logo_native.o
$(CC) $(LDFLAGS) -o parse_logos parse_logos.o load_logo_native.o

parse_logos.o: parse_logos.c logo_config
$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c parse_logos.c

load_logos.h: logo_config parse_logos
./parse_logos

load_logo.o: load_logo.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c load_logo.c

load_logo_native.o: load_logo.c
$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -o load_logo_native.o -c load_logo.c
#此处即为我们最终生成的linux_logo文件的main函数
linux_logo.o: linux_logo.c defaults.h load_logos.h
@echo Compiling for $(OS)
@echo Edit defaults.h to change Default Values
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) \
-DLOCALE_DIR=\"$(PREFIX)/share/locale\" -DUSE_I18N=$(USE_I18N) \
-c linux_logo.c
install: linux_logo
$(INSTALL) -c -m755 $(PROGNAME) -D $(INSTALL_BINPATH)/$(PROGNAME)
$(INSTALL) -c -D -m644 $(PROGNAME).1.gz $(INSTALL_MANPATH)/man1/$(PROGNAME).1.gz
cd po && $(MAKE) install
install-doc:
$(INSTALL) -c -d -m 755 $(INSTALL_DOCPATH)/$(PROGNAME)
$(INSTALL) -c -p -m 644 *[A-Z] $(INSTALL_DOCPATH)/$(PROGNAME)
# The old way of installing
install-by-copying:
cp linux_logo $(PREFIX)/bin

进而查看libsysinfo.a静态库下的makefile。

路径:/../libsysinfo-0.3.0/Makefile
include Makefile.default
all: libsysinfo.a
clean:
rm -f *.o *~
rm -f libsysinfo.a libsysinfo.so config.h
cd AIX && $(MAKE) clean
cd Linux && $(MAKE) clean
cd FreeBSD && $(MAKE) clean
cd Irix && $(MAKE) clean
cd SunOS && $(MAKE) clean
cd w32 && $(MAKE) clean
cd all && $(MAKE) clean
distclean: clean
rm -f Makefile.default
install:
#选择一种系统类型,本文选用的是arm
libsysinfo.a: Linux/cpuinfo_alpha.c \
Linux/cpuinfo_ia64.c \
Linux/cpuinfo_ppc.c \
Linux/cpuinfo_vax.c \
Linux/cpuinfo_arm.c \
Linux/cpuinfo_m68k.c \
Linux/cpuinfo_s390.c \
Linux/cpuinfo_avr32.c \
Linux/cpuinfo_mips.c \
Linux/cpuinfo_sh3.c \
Linux/cpuinfo_x86.c \
Linux/cpuinfo_cris.c \
Linux/cpuinfo_parisc.c \
Linux/cpuinfo_sparc.c \
Linux/sysinfo_linux.c
#进入all目录进行编译
cd all && $(MAKE)
#进入$(OS)目录进行编译
cd $(OS) && $(MAKE)
$(CROSS)$(AR) crus libsysinfo.a ./$(OS)/*.o ./all/*.o
#此处为libsysinfo.a库的链接命令,此处也依赖了$(OS)和all文件夹里的内容
shared: libsysinfo.a
ld -shared -o libsysinfo.so ./$(OS)/*.o ./all/*.o

查看all文件下的makefile。

路径: /../libsysinfo-0.3.0/all/Makefile
include ../Makefile.default
all: bogomips.o fix_mhz.o parsing.o string_truncate.o sysinfo_common.o uname.o
bogomips.o: bogomips.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c bogomips.c
fix_mhz.o: fix_mhz.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c fix_mhz.c
parsing.o: parsing.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c parsing.c
sysinfo_common.o: sysinfo_common.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c sysinfo_common.c
string_truncate.o: string_truncate.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c string_truncate.c
uname.o: uname.c
$(CROSS)$(CC) $(CFLAGS) $(LIBSYSINFO_INCLUDE) -c uname.c
clean:
rm -f *.o
rm -f *~

4、编译开源库

在BUILD.gn文件里增加以下内容。可以参考third-party/libuv/BUILD.gn里的内容。

ohos_executable("linuxlogo"){
include_dirs=[
"linux_logo-master",
"linux_logo-master/libsysinfo-0.3.0",
"linux_logo-master/libsysinfo-0.3.0/include",
]
sources=[
"linux_logo-master/linux_logo.c",
"linux_logo-master/load_logo.c",
"linux_logo-master/libsysinfo-0.3.0/Linux/cpuinfo_arm.c",
"linux_logo-master/libsysinfo-0.3.0/all/bogomips.c",
"linux_logo-master/libsysinfo-0.3.0/all/fix_mhz.c",
"linux_logo-master/libsysinfo-0.3.0/all/parsing.c",
"linux_logo-master/libsysinfo-0.3.0/all/string_truncate.c",
"linux_logo-master/libsysinfo-0.3.0/all/sysinfo_common.c",
"linux_logo-master/libsysinfo-0.3.0/all/uname.c",
"linux_logo-master/libsysinfo-0.3.0/Linux/sysinfo_linux.c",
]
}

完成后,这个开源库还需要有一个入口进行加载,在此文章中我们仍然选取graphic的BULID.gn进行依赖添加。

路径:test/xts/acts/grahpic/BUILD.gn
import("//build/ohos_var.gni")
group("graphic") {
testonly = true
if (is_standard_system) {
deps = [
"webGL:webGL_hap_test",
"windowstandard:window_hap_test",
//增加下面这行引入依赖
"//third_party/libuv:linuxlogo",
]
} else {
deps = [
"appaccount:appaccount_hap",
"osaccount:osaccount_hap",
]
}
}

同**《#跟着小白一起学鸿蒙# [二]编写一个Hello World文件》** 一样。

在源码根目录下执行。

./build.sh --product-name rk3568 --gn-args build_xts=true --build-target "acts" --gn-args is_standard_system=true

5、执行开源库

编译完成后生成的第三方库验证程序linuxlogo使用流程。

库文件会输出linuxlogo,路径为:out/rk3568/common/common。

hrt@ubuntu:~/oh31/out/rk3568/common/common$ ls
glcts libdeqp_ohos_platform.z.so libhmicui18n.z.so libphonenumber_standard.z.so librosen_context.z.so libc libgif.z.so libhmicuuc.z.so linuxlogo
libprotobuf_standard.z.so libsqlite.z.so

1. 拷贝linuxlogo到板子上
hdc_std.exe file send linuxlogo /data/local/tmp
//2. 登录板子,运行linuxlogo,如果第一次需要给权限
pc端:hdc_std.exe shell
板子:cd /data/local/tmp
板子:chmod +x runtest
板子:./linuxlogo

6、结果显示

补充

在此,想说关于程序编译的一些规范和方法,一般来说,C、C++代码要先把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,Linux下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

总结就是,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会报警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报Linker Error。

总结

本文主要介绍了在开源鸿蒙下如何移植一个开源库,手写一个BUILD.gn、编译运行。

来源:51CTO开源基础软件社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯