Fuchsia 系统的编译和探索

版权声明:转载必须注明本文转自严振杰的博客: http://blog.yanzhenjie.com

最近下载了 Fuchsia 源代码并编译好后跑起来进行了简单的探索,并且跑了几个测试程序,现在把中途遇到的问题和编译运行流程记录一下,如果能帮到其他遇到相同问题的读者就更新值得了。Fuchsia 的源代码托管在Google Open Source,因此下载源代码时需要翻越需要越过 GFW(仅学术研究用途),Fuchsia 的源代码有多个 git 仓库,使用 Jiri 进行管理,因此下载 Fuchsia 的源代码也需要安装 Jiri。

Jiri 可以通过 Fuchsia 的引导脚本自动安装,如果我们想探索一下单独编译安装 Jiri,可以阅读这篇文章:
https://yanzhenjie.blog.csdn.net/article/details/94580675

Google 的官网上只提供了 Linux 和 Mac OS X 系统的编译文档,这也是可想而知的。恰好目前本人在工作和生活中也是使用 Linux 和 Mac OS X 系统,并不是标榜使用 Linux 和 Max OS X 就多好,而是目前对本人而言更加适合。本人也建议读者朋友不要在 Windows 折腾了,使用 Linux 或者 Mac OS X 做编译工作更加方便快捷一点。

Fuchsia 仓库的 WebGit 地址是https://fuchsia.googlesource.com,相应的文档也在这里。前两天 Google 也上线了Fuchsia 开发者网站,这两个网址都需要翻越 GFW 才能阅览哦。


本文内容

  • 下载 Fuchsia 的系统源代码
  • 编译 Fuchsia 的系统源代码
  • 启动 Fuchsia 系统
  • Fuchsia 系统结构探索
  • 在 Fuchsia 中运行测试程序

很多人根据官方文旦一步步下来,都不能一次性下载编译成功,本人也是遇到了几个问题,在后面的步骤中也会一个个提出并给出解决方案。

下载 Fuchsia 的系统源码

Google 官方英文文档:https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/getting_started.md

准备源码下载环境和编译环境

Debian 系统准备环境:

sudo apt-get install build-essential curl git python unzip

一般情况下,会全部一次性安装好,如果遇到什么问题,某个包或者软件没有安装好,我们应该根据具体情况想办法把这几个家伙装好,然后进行下一步。

Mac OS X 系统准备环境:

xcode-select --install

根据官网提示,还需要安装最新版本 Xcode。

接下来,无论是 Linux 还是 OS X 都需要安装 Golang 1.6 或者更高版本,同时需要安装 Python2.7,有的同学可能把系统自带的 Python2.7 卸载了,使用了 3.x 的版本代替,这里需要注意,必须是 Python2.7 的版本。

另外需要注意的是,不论是任何系统,都需要把 Git、Python、Go 等配置到系统环境变量中去,这种基础操作这里就不提了,不过有些系统都自带了 Git 和 Python2.7,我们在下载源码之前最好确保全部都安装好了,否则如果下载到一半出现什么幺蛾子能让你气的原地爆炸。

配置 GFW 环境

如果读者的设备不需要翻越 GFW 或者是全局支持翻越 GFW 的环境,那么不需要看这一小节,请直接阅读下一章节。

因为引导脚本也是在fuchsia.googlesource.com上,我假设读者的设备是有翻越 GFW 的能力的,这里在当前命令行配置一下 HTTP 代理,方便下载脚本和其他需要的文件,读者请替换成自己的 IP 和端口:

export http_proxy=socks5://127.0.0.1:1080
export https_proxy=socks5://127.0.0.1:1080

除了 HTTP 的代理外,还需要配置 Git 的代理,配置 Git 的代理方式有多种。

第一种,配置全局代理:

git config --global http.proxy socks5://127.0.0.1:1080
git config --global https.proxy socks5://127.0.0.1:1080

第二种,为某个仓库配置代理:

git config --local http.proxy http://127.0.0.1:1080
git config --local https.proxy https://127.0.0.1:1080

第三种,在命令行中 clone 时指定代理:

git clone -c https.proxy=socks5://127.0.0.1:1080 ...

虽然本人的设备支持全局翻越 GFW,对于 Git 的代理,我使用了第二种方式,这样不妨碍我做其他工作。

使用引导脚本下载源码

上述操作完了之后就可以使用 Google 的引导脚本下载源码了,假如你想把源码下载到~/Workspace/fuchsia目录下,那么使用命令行进入到~/Workspace目录下,然后执行下面的引导脚本:

curl -s "https://fuchsia.googlesource.com/fuchsia/+/master/scripts/bootstrap?format=TEXT" | base64 --decode | bash

如果你想指定源码目录,例如~/Workspace/FuchsiaSystem,那么在最后加-s "~/Workspace/FuchsiaSystem"即可,否则该引导脚本将把源码下载到当前目录的子目录fuchsia下:

curl -s "https://fuchsia.googlesource.com/fuchsia/+/master/scripts/bootstrap?format=TEXT" | base64 --decode | bash -s "~/Workspance/FuchsiaSystem"

这个过程根据网速的不同,可能持续数十分钟到数十个小时,本人下载了两个小时不到。

编译 Fuchsia 的系统源代码

注意,下面提到的配置环境变量,不是在命令行中执行一下,而是配置用户或者系统的环境变量文件中去,例如~/.bashrc~/.bash_profile/etc/profile或者/etc/bashrc等,修改完对应的文件后,记得执行source ...使对应操作生效。

配置编译环境

首先还是配置源码需要的一些环境,不要问我为什么,我们先来配置一个 Fuchsia 系统源码的所在目录的变量:

export FUCHSIA_DIR=~/Workspace/Fuchsia/fuchsia

你的路径可能跟我的不一样,因为我是在~/Workspace/Fuchsia目录下执行上一节的引导脚本的,因此我的源码在这里。这个变量名称为什么叫FUCHSIA_DIR呢?因为我看了很多官方文档,里面就是这么叫的,另外 Fuchsia 作为一个系统,后期肯定会推出专门 FuchsiaSDK,我猜后期可能会产生一个FUCHSIA_HOME的变量指向 FuchsiaSDK 的目录。目前系统源码下载好之后也有一个sdk的目录,这里面是目前开发阶段的 SDK。

现在,我们先进入到 Fuchsia 的源码目录中:

cd $FUCHSIA_DIR

Fuchsia 使用 Jiri 来管理 Fuchsia 的多个 Git 仓库,因此首先配置 Jiri 到系统 Path 中去:

export PATH=$PATH:$FUCHSIA_DIR/.jiri_root/bin

为了方便,我们把 Fuchsia 的编译命令·fx也加入到系统 Path 中去,fx$FUCHSIA_DIR/scripts目录下,但是该目录包含了很多脚本,有可能和系统的其他命令冲突,所以我们不能把这个目录直接加入到 Path 中,因此为了方便管理,我们把fx也连接到Jiribin目录下,目前经过我的实践,我觉得这个方案很棒:

ln -s scripts/fx .jiri_root/bin

此时,我们便可以在命令行执行fx来试试是否配置成功,如果不成功自己再看看是哪一步操作出了问题。

fx 编译时的选项介绍

接下来,我会先做一些介绍,但是读者不要急着执行命令,要把本小节看完后再执行,否则可能会浪费一点时间。

按照官网的教程,现在就可以进行编译了:

fx set core.x64 --with //bundles:kitchen_sink
fx build

但是,你千万不要着急,我敢说没用过fx的同学肯定不知道这命令中的各参数都是啥意思,而且也不知道输出文件跑哪里去了,一脸懵逼的我肯定不会直接去编译浪费时间,那么接下来,我来介绍一下。

上述第一个命令的结构是这样的:

fx set [product].[board] --width //bundles:[name]

该命令用来选择要编译的产品类型、对应的芯片架构和额外捆绑物,下面会依次介绍它们。

product指产品配置,官方文档中提到了bringupworkstationcore,而我们可以通过fx list-products来查看所有的产品配置列表:

$ fx list-products
*
bringup
core
router
speaker
terminal
workstation

介绍最基本的三个:

  • bringup,最小的系统功能集,没有网络支持等,我猜可能仅是个能运行起来的内核和驱动程序等
  • core,安装了基本程序的最小功能集,例如网络能力等,比 bringup 高级一点
  • workstation,通用开发环境的基础,包含了例如 UI、媒体和我们想折腾的一些东西

board指芯片架构类型,官方文档中提到了x64armx64,而我们可以通过fx list-boards来查看所有的类型:

$ fx list-boards
*
arm64
chromebook-x64
cleo
hikey960
kirin970
msm8x53-som
mt8167s_ref
qemu-arm64
qemu-x64
toulouse
vim2
x64

这些选项和 Fuchsia 所运行的设备的芯片架构有关,这里不做太多介绍。

--width //bundles:[name]中的name表示额外的捆绑,比如测试程序等,官方文档中提到了三个选择,分别是toolstestskitchen_sink

它们的含义分别是:

  • tools,包含了大量的开发人员工具,相当于基础,例如 shell 组件,ls、vim、cat、curl 等
  • tests,包含所有的测试程序,亲测这个选项编译完成后占用空间较大
  • kitchen_sink,包含所有其他构建目标,编译完成后占用空间超级大

另外,要介绍编译的产物会输出在$FUCHSIA_DIR/out/default下,这个目录是可以设置的。我们试想一下,上面介绍到,productcoreworkstation,如果默认都输出在default下的话,那么如果我们想切换一下产品类型,就得完全重新编译一次源码(实测发现,每次编译根据选项的不同需要花费 1-3 个小时),这就太浪费时间啦。

此时,fx --dir [path]就出场了,例如我们想把workstation类型的编译产物输出到$FUCHSIA_DIR/out/workstation下,那么我们可以这样设置:

fx --dir out/workstation set workstation.x64

再例如,我们想把core类型的编译产物输入到$FUCHSIA_DIR/out/core下,那么我们可以这样设置:

fx --dir out/core set core.64

然后再运行fx build就可以编译 Fuchsia 系统啦,但是读者朋友还是不要着急,我把完整的配置亮出来:

fx --dir out/workstation set workstation.x64 --with //bundles:tests

虽然上面介绍了每一段的含义,这里还是简单说一下,首先指定了编译产物输出目录为$FUCHSIA_DIR/out/workstation,然后设置产品类型为workstation,然后带上所有的测试程序,以便与后期的探索学习。

编译 Zircon 内核源码

在上面为什么迟迟不让读者进行编译呢,因为可能会遇到一些小问题,这里我推荐直接直接编译,出现问题了再回来这个章节按照教程尝试,如果读者选择直接编译,请看下一节,不要自己直接编译。

Fuchsia 基于 Zircon 内核,如果直接编译 Fuchsia 的话,是会先编译 Zircon 内核的,中途不知道会出现什么幺蛾子,由于层层嵌套可能会很难发现问题,我这里推荐大家先编译 Zircon。

官网文档:https://fuchsia.googlesource.com/fuchsia/+/HEAD/zircon/docs/getting_started.md

如果读者使用 Debian,先确保安装了一下依赖:

sudo apt-get install texinfo libglib2.0-dev autoconf libtool bison libsdl-dev build-essential

如果使用的 Mac OS X 的话,先要安装 TunTap:

  • TunTap 主页:http://tuntaposx.sourceforge.net/
  • TunTap 下载链接:http://downloads.sourceforge.net/tuntaposx/tuntap_20150118.tar.gz
  • 不要问我为什么,Fuchsia 官网也没写,我在编译的时候发现的,先编译跑起来再说

在 OS X 上接着安装其他编译时的依赖项:

  • 使用 Homebrew
brew install wget pkg-config glib autoconf automake libtool
  • 使用 MacPorts
port install autoconf automake libtool libpixman pkgconfig glib2

我在 Linux 上和 OS X 上都是使用 Homebrew 的,虽然 Homebrew 一直是最新版本,但是上面这条命令一直安装失败:

glib: undefined method `uses_from_macos' for Formulary::FormulaNamespace1b33d7b036781a8c4dc38a980a07e0d5::Glib:Class

看起来是glib安装不上,担心是由于依赖问题,于是我一个个拆开安装尝试是哪个包出了问题,最后发现所有包都装上了,只是lib包一直装不上,于是我在 Homebrew 官网找到了资料:
https://brewinstall.org/Install-glib-on-Mac-with-Brew/

没有说是什么原因,但是对我来说好使:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null

上面安装 Homebrew 的脚本跑完后,再次安装glib就成功了:

brew install glib

接下来,编译 Ziecon,有两种方式。

第一种是使用 fx 命令编译:

fx build-zircon

这个方式是使用 fx 命令直接一次全部编译完成,想必是 fx 做了些事情的。

第二种方式,使用 gnninja 编译:

cd zircon
gn gen build-zirzon --args='variants = [ "clang" ]'

然后接下来的三选一,建议选第三个,出错选择第一个:

# arm64 and x64
ninja -C build-zircon

# arm64
ninja -C build-zircon arm64

# x64
ninja -C build-zircon x64

无论哪种方式,编译完成后还是回到 Fuchsia 的源码目录:

cd ..

编译 Fuchsia 源码

到这里在编译过程中的几个坑基本填平,如果读者遇到什么问题,可以给我留言。接着编译 Fuchsia:

fx build

这一步如果遇到问题,请看上一小节。接下来,下楼去买杯咖啡,等个一两个小时,编译完成就 OK 了。

运行和探索 Fuchsia

激动人心的时刻来了,Fuchsia 编译完成了,接下来启动它:

fx run

接下来,会在终端输出很多信息和警告,只要能启动,几乎可以无视所有的信息,大概需要 30S 左右,直到终端出现$说明 Fuchsia 启动了。

如果遇到下面的信息:

[INFO:dart_isolate.cc(503)] New isolate is in the running state.
[INFO:engine.cc(382)] Main isolate for engine 'userpicker_base_shell.cmx' w
[INFO:vulkan_application.cc(105)] Destroying Vulkan instance

也表示系统系统启动成功了,只是没有把$显示出来而已,只需要敲一下回车键就可以了,是不是有点失落?怎么看不到 UI 呀,不要灰心,UI 是有的,只是没有实体机所以 UI 很简单,我们等下看。

如果你用 SSH 登录过 Linux,那么现在看到的就足够了,因此我们选择的是workstation,所以基本的shell命令是包含的,此时可以查看一下 Fuchsia 的文件系统结构:

$ ls
bin
blob
boot
data
dev
hub
install
pkgfs
svc
system
tmp
volume

读者可以随意进出各个目录看一下文件系统结构,如果想退出系统可以用以下命令关机退出 Fuchsia 回到本机的终端:

dm shutdown

如果读者朋友想体验一下 UI,那么可以从 QEMU 启动 Fuchsia:

fx run -g

和上面一样的,会出来一个黑窗体,然后有几个 tab 可以看看,太简单了就没啥意思,我们还是从命令行探索。

探索 Fuchsia

Fuchsia 是一个系统,接下来我们在 Fuchsia 上运行一些简单的程序。

系统启动后默认不包含一些测试的应用程序的,所以我们需要上传一些程序到 Fuchsia 中去,Google 的官方文档中告诉我们,需要设置本地 DHCP 服务器和 NAT 为 Fuchsia 配置 IPv4 接口和路由,因此我们启动 Fuchsia 时用一个配置 DHCP 的脚本启动。

首先,退出刚才启动的系统:

dm shutdown

退出时比启动快多了,只需要几秒钟,接着使用一个配置 DHCP 的脚本启动 Fuchsia:

fx run -N -u scripts/start-dhcp-server.sh

同样的,等待 30S 左右,系统就启动成功了,然而此时的系统还是一个光杆司令,我们还得为它启动一个更新服务器,用来上传一些应用程序和文件。此时,留着启动 Fuchsia 系统的终端不动,在$FUCHSIA_DIR目录重新打开一个终端,然后为 Fuchsia 启动更新服务器:

fx server -v

大概需要几秒中,更新服务器就启动并等待启动动作了,

根据官方文档,此时我们可以运行一些内置的测试包来体验一下 Fuchsia 了,但是实际上我没有直接运行成功,而是需要先让 Fuchsia 建立一下连接,Fuchsia 才能运行这些程序,我们再开一个终端,用shell登录到 Fuchsia 中,此时会通过服务器和 Fuchsia 建立连接,要说明的是,这种方式是用来登录实体设备的,这里我们只是临时用一下:

fx shell

执行完这个命令后,大概五六秒的样子,我们就可以在第三个终端中登录到第一个终端所在的 Fuchsia 了,此时第三个终端退出 Fuchsia 的命令是:

exit

此时,在第一个终端(如果第三个终端没有退出 shell,也可以)来执行一个示例程序cowsay,这个程序可以让一头牛讲话:

cowsay Hi!

执行完后我们可以看到:

 ______
| Hi!  |
 ------
     \  ^__^
      \ (oo)\_____
        (__)\     )\/\
           ||----w |
           ||     ||

还有另一个掷骰子的应用rolldice

rolldice

执行完后可以看到:

+---+
|   |
| * |
|   |
+---+

接下来我们可以执行一些测试程序,还记得我们在最开始编译系统时使用的--with //bundles:test,我们现在就可以看看有哪些测试程序:

fx list-packages

包比较多,读者可以粗略的看看一下,这里我们选择hello_world_cpp_tests,现在我们在第三个终端上进入到$FUCHSIA_DIR目录(如果没有退出 shell 的话,exit退出),编译该程序并上传到 Fuchsia 上:

fx build-push hello_world_cpp_tests

现在我们在第一个终端,也就是 Fuchsia 上执行:

run hello_world_cpp_tests

执行完成后可以看到测试结果:

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from HelloWorldTest
[ RUN      ] HelloWorldTest.True
[       OK ] HelloWorldTest.True (1 ms)
[----------] 1 test from HelloWorldTest (6 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (43 ms total)
[  PASSED  ] 1 test.

表示测试通过。如果你是使用实体设备的,就在第三个终端,执行:

fx -i run-test hello_world_cpp_tests

也可以看到上述执行结果。

再演示一个拷贝本机文件到 Fuchsia 的能力,现在我们使用第三个终端在$FUCHSIA_DIR目录下新建一个hello.md的文件:

touch hello.md

然后向该文件写入一些数据:

vim hello.md

此时会使用 vim打开 hello.md 文件,在键盘上摁一下i,就可以输入内容了,输入内容结束后,摁下esc键,然后此时输入:wq就可以保存该文件并退回到终端了。

此时,我们把这个文件推到 Fuchsia 的tmp目录下:

fx cp hello.md /tmp/hello.md

为了证明实际推上去了,此时在 Fuchsia 中尝试打开该文件:

vim /tmp/hello.md

你会发现文件确实被上传上来了。

我们在这里也尝试了 Fuchsia 的vim,你也可以尝试一下其他命令,比如curl

$ curl -v http://blog.csdn.net
> GET / HTTP/1.1
> Host: blog.csdn.net
> User-Agent: curl/7.54.0-DEV
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: openresty
< Date: Sat, 06 Jul 2019 03:22:06 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: keep-alive
< Keep-Alive: timeout=20
< Location: https://blog.csdn.net/
<
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>openresty</center>
</body>
</html>

因为 CSDN 使用的是 https,所以这里要求客户端重定向到 https 的地址。

简单的探索到这里结束,关于fx命令的更多介绍请看 Fuchsia 的官方文档:
https://fuchsia.googlesource.com/fuchsia/+/master/docs/development/workflows/fx.md

本文到此结束,这篇文章写的很浅,完全是体验类型的,为了照顾大多数人,几乎是小白都能按照我的教程实际体验 Fuchsia 的,实际上还有很多可以玩的东西,后期再慢慢写,告辞!


版权声明:转载必须注明本文转自严振杰的博客: http://blog.yanzhenjie.com

你可能感兴趣的:(Fuchsia,Flutter)