本文摘录自 OHOZ 团队的 OpenHarmony 源码导读项目,在线阅读(腾讯云、Github Pages)中包含最新的内容。
鸿蒙的预编译内容
本子系统包含鸿蒙为开发者预编译好的内容,主要为
- sysroot:ARM 版本的 MUSL libc 库,开发者可以通过
clang --sysroot=<sysroot-dir>
完成交叉编译中的链接操作 - signcenter:对应用签名,以保证应用完整性和来源可靠。
MUSL
musl 是基于 Linux 系统调用 API 之上实现的 C 语言标准库(libc),历史可以追溯到 2005 年,但在 2011 年才正式确定了 MUSL 这个名称,开始对标 glibc、uClibc,从 2012 年开始,musl 开始使用 MIT License。
musl 致力于简单、高效,凭借 libc 优秀的松耦合性,做到了静态版本最小 10kB,即使添加了线程等高级特性,也可以控制到 50kB,所以特别适合嵌入式设备。为了控制资源的使用, musl 自己竟然不做动态内存分配。
可以在其 官网 下载源码,或者直接 git clone git://git.musl-libc.org/musl
,查看文档则可以去 wiki
musl 实现了多个标准中的 API:
- C 语言的标准库 API: C99、C11
- POSIX 2008
- 更广泛的 agreed-upon extensions
编译 musl 得到 libc 和 compiler
想要从源码编译 musl 需要的依赖非常少,也不限制在 linux 上编译,在 Linux 上编译也不需要 Linux kernel headers,只要有 make 和一个符合 C99 的 Compiler 就行,满足 C99 要求的 Compiler 不少:GCC、LLVM/clang、Firm/cparser、PCC 都行,都能够成功的编译 musl。
交叉编译 musl 也非常方便,从源码中可以看到支持非常多的 target CPU:
$ cd arch
$ ls
aarch64 arm generic i386 m68k microblaze mips mips64 mipsn32 or1k powerpc powerpc64 riscv64 s390x sh x32 x86_64
只有 riscv64,没有 riscv32 么?
编译 musl 也非常简单,为了不影响 host,下面使用 gcc 的 docker:
$ cd musl-1.2.2
$ docker run -it -v $(pwd):/home/musl gcc
root@b2afc2921eb7:/ # cd /home/musl
root@b2afc2921eb7:/home/musl# ./configure
root@b2afc2921eb7:/home/musl# make -j8
编译出的结果位于 lib/
,过程文件位于 obj/
,和一个 compiler musl-gcc
:
root@b2afc2921eb7:/home/musl# ls lib
Scrt1.o crt1.o crti.o crtn.o libc.a libc.so libcrypt.a libdl.a libm.a libpthread.a libresolv.a librt.a libutil.a libxnet.a musl-gcc.specs rcrt1.o
root@b2afc2921eb7:/home/musl# ls obj
crt include ldso musl-gcc src
make install
安装的话会从源向目的拷贝文件:
源 | 目的 |
---|---|
lib/*.a 、lib/*.o |
/usr/local/musl/lib/ |
include/*.h 、arch/xxx/*.h |
/usr/local/musl/include/ |
obj/musl-gcc |
/usr/local/musl/bin/ |
使用 musl 编译 helloworld
现在,你就可以舍弃掉 gcc,转用 musl-gcc 这个 Compiler 编译自己的程序了,依然在 gcc 的 docker 里测试:
root@b2afc2921eb7:/home/musl# cat main.c
#include <stdio.h>
int main(void){
printf("Hello musl\n");
return 0;
}
root@b2afc2921eb7:/home/musl# /usr/local/musl/bin/musl-gcc main.c
root@b2afc2921eb7:/home/musl# ./a.out
Hello musl
甚至可以用 musl-gcc 再次编译 musl 自己,编译结果会比 gcc 缺少几个文件 —— 能不能用没试过,至少能编过。
root@b2afc2921eb7:/home/musl# CC=