#冲刺创作新星# [五]OpenHarmony的4种编译方法 原创 精华

左翼风发
发布于 2022-9-28 10:29
浏览
6收藏

作者:王石,胡瑞涛

简介

在 [二]第一个OpenHarmony程序章节我们学习了如何开发一个OpenHarmony的终端程序,采用的方法就是使用BUILD.gn脚本文件,通过./build.sh脚本进行编译,这也是OpenHarmony官方推荐的编译程序的方法。但是这样的方法牵扯方便广,速度慢,接下来我们来熟悉下OpenHarmony的另外两种编译方法。

GCC编译方法

  1. 工具链位置:

    [源码路径]/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/
    
  2. 编译命令:

    arm-linux-gnueabi-gcc -static helloworld.c -o gcchelloworld
    
  3. 方法解析:

    使用gcc工具链的编译方法是嵌入式开发的通用方法。但是这里有个特殊的地方-static。 gcc 加上 -static,会在链接阶段, 查找对应模块的静态库, 而非动态库, 并把需要的东西,都带进目标文件),编译好后,文件会非常大,但是,运行时就不需要依赖。这个原因则是在OpenHarmony的镜像文件里放的是musl的lib库,没有glibc的lib库,所以如果不用-static标志则有可能在运行时找其他运行库,找不到则运行不成功。

CLang编译方法

  1. 工具链位置:[源码路径]/prebuilts/clang/ohos/linux-x86_64/llvm/bin

  2. 编译命令:

    • clang --sysroot=[ohos代码路径]/out/rk3568/obj/third_party/musl/ --target=arm-linux-ohosmusl -D__clang__ -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -w -o helloworld.c.o -c helloworld.c

    • clang --sysroot=[ohos代码路径]/out/rk3568/obj/third_party/musl/ --target=arm-linux-ohosmusl -D__clang__ -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -w -Wl,–dynamic-linker,/lib/ld-musl-arm.so.1 -rdynamic helloworld.c.o -o muslhelloworld

  3. 方法解析:

    clang编译器是APPLE公司的编译器大牛Chris Lattner主导下编写的,其目标是替换大名鼎鼎的GCC编译器。一般编译器的流程如下:

    graph LR
    源代码 --> 预处理 --> 前端 --> 优化 --> 后端 --> 链接 --> 生成文件
    

    通过上面的命令分析分了两部,第一步编译生成中间文件:helloworld.c.o,也就是从预处理一直到后端的过程;第二步链接helloworld.c.o和/lib/ld-musl-arm.so.1生成目标文件muslhelloworld也就是链接和生成文件。这部分和上部分的区别就是手动引用musl库。那么musl库和glibc的库的区别是什么呢?

    1. 开源版本:glibc(LGPLv2.1),musl(MIT)
    2. 运行速度:glibc优于musl,同时稳定性也是glibc更好
    3. 代码可读性:musl优于glibc

总结

OpenHarmony的官方编译方法就是使用./build.sh脚本文件,调用顺序大致如下:

graph LR
build.sh --> entry.py --> vendor和product --> hb --> ninja --> clang

所以如果要缩减编译时间还有一些特殊方法:

  • ./build.sh --product-name 【产品名称如:rk3568】–ccache --build-target 【编译对象模块,如:moduleb_lib】

    此方法也是官方的一种编译方法,虽说只编译一个模块,但是流程是完整的,即:

    • 用BUILD.gn生成ninja文件,然后通过上面的流程编译最总的模块二进制文件
  • ninja -C out/rk3568(根据编译的productname来填) moduleb_lib(编译对象模块,如:moduleb_lib)

    此方法的前提是首先用./build.sh编译过一遍,然后因为out目录里提前生成了build.ninja,所以可以直接用ninja命令直接编译对应模块

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2023-2-21 08:45:24修改
6
收藏 6
回复
举报
8条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

看起来编译方法中glibc似乎更胜一筹呀

1
回复
2022-9-28 14:41:03
真庐山升龙霸
真庐山升龙霸

主页没看到第二篇,请问在哪看呢

回复
2022-9-28 15:40:24
左翼风发
左翼风发 回复了 真庐山升龙霸
主页没看到第二篇,请问在哪看呢
回复
2022-9-28 18:10:50
左翼风发
左翼风发 回复了 红叶亦知秋
看起来编译方法中glibc似乎更胜一筹呀

但是开源协议和二次开发的代码整洁度也是一个考量维度

回复
2022-9-28 18:12:06
离北况归
离北况归

催更大佬,三方库的NAPI接口开发😋😋😋

回复
2022-9-29 10:46:07
左翼风发
左翼风发

正在准备验证中

回复
2022-9-29 11:48:47
离北况归
离北况归

更正一下大佬的笔误:ninja -C /out/rk3568应该去掉out前面的/

回复
2023-2-6 23:07:51
左翼风发
左翼风发

已修改,谢谢

回复
2023-2-22 22:07:44
回复
    相关推荐