想了解更多开源请访问:开源基础软件社区https://ost.51cto.com本节我们讨论如何参考第三方开源库,引入OpenHarmony在设备上编译运行。1.开源库结构我们选择一个比较简单的linux-logo开源库(库地址:https://github.com/deater/linux_logo)。.├──配置├──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├──tests2,linuxls配置下的运行步骤和结果目录./configure编译,运行make&./linux_logo3,移植到鸿蒙系统编译运行移植到鸿蒙需要添加文件夹和gn文件.第三方库在OpenHarmony中的位置在【代码目录】/third_party位置。我们可以在三方库中新建一个文件夹:linuxlogo,然后在linuxlogo中新建一个BUILD.gn文件。接下来我们需要将第三方的linuxlog文件复制到这个文件夹中。然后我们需要读取三方库的Makefile。以下是基本的makefile规则:makefileruletarget...:prerequisites...command...-----------------------------------------------------------------target为目标文件,可以是ObjectFile,也可以是可执行文件。也可以是动作/伪目标/标签(Label),比如clean。先决条件是生成该目标所需的文件或目标。command是make需要执行的命令。(任意shell命令)。这是一个文件依赖。目标的一个或多个目标文件依赖于先决条件中的文件,其生成规则在命令中定义。依赖关系定义好后,下面一行定义了操作系统如何生成目标文件的命令,make会逐层查找文件的依赖关系,直到最终编译出第一个目标文件。这就是整个make依赖。GNUmake的执行步骤如下:(我觉得其他make也差不多)。1.阅读所有的Makefile。2.阅读包含的其他Makefile。3.初始化文件中的变量。4.推导隐含规则,分析所有规则。5.为所有目标文件创建依赖链。6.根据依赖关系,决定重建哪些目标。7.执行构建命令。步骤1-5是第一阶段,步骤6-7是第二阶段。在第一阶段,如果定义的变量被使用,那么make会在使用的位置展开它。但是make不会马上展开,如果这个变量出现在依赖规则中,那么只有当这个依赖确定要用到的时候,才会在里面展开这个变量。规则由两部分组成,一部分用于依赖项,一部分用于生成目标的方法。查看makefile(里面有一些关键命令的注释)。Makefile告诉make命令要做什么(通常是如何编译和链接程序)。·路径:/../Makefile-includeMakefile.defaultPROGNAME=linux_logo#ifeq($(OS),IRIX64)#LDFLAGS+=-lintl#endifeq($(OS),FreeBSD)LDFLAGS+=-lintlenif##安装位置#INSTALL_BINPATH=$(DESTDIR)$(PREFIX)/binINSTALL_MANPATH=$(DESTDIR)$(PREFIX)/share/manINSTALL_DOCPATH=$(DESTDIR)$(PREFIX)/share/doc##Libsysinfo位置#LIBSYSINFO_INCLUDE=-I$(LIBSYSINFO)LIBSYSINFO_LIBRARY=-L$(LIBSYSINFO)ifneq($(XGETTEXT),)TRANSLATIONS=translationsendifall:Makefile.defaultparse_logoslinux_logo$(TRANSLATIONS)Makefile.default:ifneq($(CONFIGURE_RAN),1)$(error请先运行配置)endiftranslations:cdpo&&$(MAKE)logos-all:logo_configfind./logos-typef-a!-namebanner.logo-a!-nameclassic.logo|排序>>logo_config$(MAKE)alllogo_config:echo"./logos/banner.logo">logo_configecho"./logos/classic.logo">>logo_configclean:Makefile.defaultrm-f*.orm-flinux_logolinux_logo-dynparse_logosload_logos.hrm-f*~cd$(LIBSYSINFO)&&$(MAKE)清洁cdpo&&$(MAKE)cleandistclean:清洁cd$(LIBSYSINFO)&&$(MAKE)distcleanrm-fMakefile.defaultlogo_config#rm-fpo/linux_logo.pot#这里是我们最终生成的linux_logo二进制文件,它依赖于linux_logo.o、load_logo.o两个中间文件和libsysinfo.a库linux_logo:linux_logo.oload_logo.o。/$(LIBSYSINFO)/libsysinfo.a$(CROSS)$(CC)$(LDFLAGS)-olinux_logolinux_logo.oload_logo.o$(LIBSYSINFO_LIBRARY)./$(LIBSYSINFO)/libsysinfo.alinux_logo_shared:linux_logo.oload_logo.o./$(LIBSYSINFO)/libsysinfo.a$(CROSS)$(CC)$(CFLAGS)-olinux_logo-dynlinux_logo.oload_logo.o$(LIBSYSINFO_LIBRARY)-lsysinfo#这里是libsysinfo的编译脚本.a库,他会进入$(LIBSYSINFO)目录,然后执行make命令。抄送)$(LDFLAGS)-oparse_logosparse_logos.oload_logo_native.oparse_logos.o:parse_logos.clogo_config$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cparse_logos.cload_logos.h:logo_configparse_logos./parse_logosload_logo.o:load_logo.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE))-cload_logo.cload_logo_native.o:load_logo.c$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-oload_logo_native.o-cload_logo.c#这里即为我们最终生成的linux_logo文件的主要数linux_logo。o:linux_logo.cdefaults.hload_logos.h@echo为$(OS)编译@echo编辑defaults.h以更改默认值$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)\-DLOCALE_DIR=\“$(PREFIX)/share/locale\”-DUSE_I18N=$(USE_I18N)\-clinux_logo.cinstall:linux_logo$(INSTALL)-c-m755$(PROGNAME)-D$(INSTALL_BINPATH)/$(PROGNAME)$(INSTALL)-c-D-m644$(PROGNAME).1.gz$(INSTALL_MANPATH)/man1/$(PROGNAME).1.gzcdpo&&$(MAKE)安装安装文档:$(INSTALL)-c-d-m755$(INSTALL_DOCPATH)/$(PROGNAME)$(INSTALL)-c-p-m644*[A-Z]$(INSTALL_DOCPATH)/$(PROGNAME)#老的拷贝安装方式:cplinux_logo$(PREFIX)/bin然后查看libsysinfo.astatic下的makefile图书馆路径:/../libsysinfo-0.3.0/MakefileincludeMakefile.defaultall:libsysinfo.aclean:rm-f*.o*~rm-flibsysinfo.alibsysinfo.soconfig.hcdAIX&&$(MAKE)cleancdLinux&&$(MAKE)cleancdFreeBSD&&$(MAKE)cleancdIrix&&$(MAKE)cleancdSunOS&&$(MAKE)cleancdw32&&$(MAKE)cleancdall&&$(MAKE)cleandistclean:干净rm-fMakefile.defaultinstall:#选择系统类型,本文使用armlibsysinfo.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。/cpuinfo_sparc.c\Linux/sysinfo_linux.c#进入all目录编译cdall&&$(MAKE)#进入$(OS)目录编译cd$(OS)&&$(MAKE)$(CROSS)$(AR)cruslibsysinfo.a./$(OS)/*.o./all/*.o#这里是libsysinfo.a库的链接命令,也依赖于$(OS)和所有文件夹的内容inshared:libsysinfo.ald-shared-olibsysinfo.so./$(OS)/*.o./all/*.o查看所有文件下的makefile路径:/../libsysinfo-0.3.0/all/Makefileinclude../Makefile.defaultall:bogomips.ofix_mhz.oparsing.ostring_truncate.osysinfo_common.ouname.obogomips.o:bogomips.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cbogomips.cfix_mhz.o:fix_mhz.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cfix_mhz.cparsing.o:解析.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cparsing.csysinfo_common.o:sysinfo_common.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-csysinfo_common.cstring_truncate.o:string_truncate.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cstring_truncate.cuname.o:uname.c$(CROSS)$(CC)$(CFLAGS)$(LIBSYSINFO_INCLUDE)-cuname.cclean:rm-f*.orm-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",]}完成后,这个开源库还需要一个入口来加载。在本文中,我们仍然选择图形的BULID.gn来添加依赖。路径:test/xts/acts/grahpic/BUILD.gnimport("//build/ohos_var.gni")group("graphic"){testonly=trueif(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-namerk3568--gn-argsbuild_xts=true--build-target"acts"--gn-argsis_standard_system=true5.执行编译后生成的第三方库验证程序linuxlogo开源库手册。库文件会输出linuxlogo,路径为:out/rk3568/common/common。hrt@ubuntu:~/oh31/out/rk3568/common/common$lsglctslibdeqp_oh??os_platform.z.solibhmicui18n.z.solibphonenumber_standard.z.solibrosen_context.z.solibclibgif.z.solibhmicuuc.z.solinuxlogolibprotobuf_standard。z.solibsqlite.z.so1。复制linuxlogo到板子hdc_std.exe文件发送linuxlogo/data/local/tmp//2。登录开发板并运行linuxlogo。如果是第一次给PC权限:hdc_std.exeshell板子:cd/data/local/tmp板子:chmod+xruntest板子:./linuxlogo6、这里补充一下结果显示。我想谈谈程序编译的一些规范和方法。一般来说,C、C++代码首先要把源文件编译成一个中间代码文件,在Windows下是.obj文件,在Linux下是.o文件,也就是ObjectFile。此操作称为编译。然后将大量的ObjectFiles合成为可执行文件。此操作称为链接。编译时,需要确定编译目标所需的源文件。编译器需要的是正确的语法、正确的函数和变量声明。对于后者,通常需要告诉编译器头文件的位置(头文件应该只是声明,而定义应该放在C/C++文件中),只要所有语法正确即可,编译器可以编译一个中间目标文件。一般来说,每个源文件都应该对应一个中间目标文件(O文件或OBJ文件)。链接时,就是确定链接时需要依赖的额外库。主要是链接函数和全局变量,所以我们可以使用这些中间目标文件来链接我们的应用程序。链接器不关心函数所在的源文件,只关心函数的中间目标文件。很多时候,由于源文件太多,编译生成的中间目标文件太多,链接时需要明确指出中间目标文件的名字。这对于编译来说非常不方便,所以我们需要将中间目标文件打包生成库文件。Windows下为LibraryFile,即.lib文件;在UNIX下,它是一个ArchiveFile,也就是一个.a文件。总结就是源文件会先生成中间目标文件,中间目标文件再生成执行文件。在编译时,编译器只检查程序语法,以及是否声明了函数和变量。如果函数没有声明,编译器会报警告,但是可以生成ObjectFile。链接程序时,链接器会在所有目标文件中搜索该函数的实现。如果找不到它,它将报告链接器错误。总结本文主要介绍如何在开源鸿蒙下移植一个开源库,手写一个BUILD.gn,编译运行。
