版权声明:转载必须注明本文转自严振杰的博客: 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 才能阅览哦。
很多人根据官方文旦一步步下来,都不能一次性下载编译成功,本人也是遇到了几个问题,在后面的步骤中也会一个个提出并给出解决方案。
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 的环境,那么不需要看这一小节,请直接阅读下一章节。
因为引导脚本也是在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"
这个过程根据网速的不同,可能持续数十分钟到数十个小时,本人下载了两个小时不到。
注意,下面提到的配置环境变量,不是在命令行中执行一下,而是配置用户或者系统的环境变量文件中去,例如
~/.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
也连接到Jiri
的bin
目录下,目前经过我的实践,我觉得这个方案很棒:
ln -s scripts/fx .jiri_root/bin
此时,我们便可以在命令行执行fx
来试试是否配置成功,如果不成功自己再看看是哪一步操作出了问题。
接下来,我会先做一些介绍,但是读者不要急着执行命令,要把本小节看完后再执行,否则可能会浪费一点时间。
按照官网的教程,现在就可以进行编译了:
fx set core.x64 --with //bundles:kitchen_sink
fx build
但是,你千万不要着急,我敢说没用过fx
的同学肯定不知道这命令中的各参数都是啥意思,而且也不知道输出文件跑哪里去了,一脸懵逼的我肯定不会直接去编译浪费时间,那么接下来,我来介绍一下。
上述第一个命令的结构是这样的:
fx set [product].[board] --width //bundles:[name]
该命令用来选择要编译的产品类型、对应的芯片架构和额外捆绑物,下面会依次介绍它们。
product
指产品配置,官方文档中提到了bringup
、workstation
和core
,而我们可以通过fx list-products
来查看所有的产品配置列表:
$ fx list-products
*
bringup
core
router
speaker
terminal
workstation
介绍最基本的三个:
board
指芯片架构类型,官方文档中提到了x64
和armx64
,而我们可以通过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
表示额外的捆绑,比如测试程序等,官方文档中提到了三个选择,分别是tools
、tests
和kitchen_sink
:
它们的含义分别是:
另外,要介绍编译的产物会输出在$FUCHSIA_DIR/out/default
下,这个目录是可以设置的。我们试想一下,上面介绍到,product
有core
和workstation
,如果默认都输出在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
,然后带上所有的测试程序,以便与后期的探索学习。
在上面为什么迟迟不让读者进行编译呢,因为可能会遇到一些小问题,这里我推荐直接直接编译,出现问题了再回来这个章节按照教程尝试,如果读者选择直接编译,请看下一节,不要自己直接编译。
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:
在 OS X 上接着安装其他编译时的依赖项:
brew install wget pkg-config glib autoconf automake libtool
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
做了些事情的。
第二种方式,使用 gn
和 ninja
编译:
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:
fx build
这一步如果遇到问题,请看上一小节。接下来,下楼去买杯咖啡,等个一两个小时,编译完成就 OK 了。
激动人心的时刻来了,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 中去,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