作者:王石,胡瑞涛
简介
在#跟着小白一起学鸿蒙# [二]第一个OpenHarmony程序章节我们学习了如何开发一个OpenHarmony的终端程序,采用的方法就是使用BUILD.gn脚本文件,通过./build.sh脚本进行编译,这也是OpenHarmony官方推荐的编译程序的方法。但是这样的方法牵扯方便广,速度慢,接下来我们来熟悉下OpenHarmony的另外两种编译方法。
GCC编译方法
-
工具链位置:
[源码路径]/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin/
-
编译命令:
arm-linux-gnueabi-gcc -static helloworld.c -o gcchelloworld
-
方法解析:
使用gcc工具链的编译方法是嵌入式开发的通用方法。但是这里有个特殊的地方-static。 gcc 加上 -static,会在链接阶段, 查找对应模块的静态库, 而非动态库, 并把需要的东西,都带进目标文件),编译好后,文件会非常大,但是,运行时就不需要依赖。这个原因则是在OpenHarmony的镜像文件里放的是musl的lib库,没有glibc的lib库,所以如果不用-static标志则有可能在运行时找其他运行库,找不到则运行不成功。
CLang编译方法
-
工具链位置:[源码路径]/prebuilts/clang/ohos/linux-x86_64/llvm/bin
-
编译命令:
-
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
-
-
方法解析:
clang编译器是APPLE公司的编译器大牛Chris Lattner主导下编写的,其目标是替换大名鼎鼎的GCC编译器。一般编译器的流程如下:
graph LR 源代码 --> 预处理 --> 前端 --> 优化 --> 后端 --> 链接 --> 生成文件
通过上面的命令分析分了两部,第一步编译生成中间文件:helloworld.c.o,也就是从预处理一直到后端的过程;第二步链接helloworld.c.o和/lib/ld-musl-arm.so.1生成目标文件muslhelloworld也就是链接和生成文件。这部分和上部分的区别就是手动引用musl库。那么musl库和glibc的库的区别是什么呢?
- 开源版本:glibc(LGPLv2.1),musl(MIT)
- 运行速度:glibc优于musl,同时稳定性也是glibc更好
- 代码可读性: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命令直接编译对应模块
https://ost.51cto.com/#bkwz