使用如下的fx子命令build编译fuchsia代码。实际上运行的是目录tools/devshell/下的编译脚本build。fx将调用ninja运行两次:第一次编译zircon,第二次编译fuchsia。
~/fuchsia$ scripts/fx build
其实,每个fx的子命令都对应着一个tools/devshell目录下的脚本文件:
~/fuchsia$ ls tools/devshell/
add-update-source cp lib mkzedboot README.md serial shell wait
aemu doctor list-boards netaddr reboot serve ssh
args exec list-packages netboot run serve-updates symbolize
build flash list-products netls run-host-tests set syslog
~/fuchsia$
当然,也可以使用fx build命令单独编译zircon。如下编译zircon的default目标:
~/fuchsia$ scripts/fx build zircon/default
ninja: Entering directory `/home/kai/fuchsia/out/default.zircon'
[65/65] STAMP obj/default.stamp
~/fuchsia$
或者,单独编译fuchsia的目标target。如下编译fuchsia的default目标,由于依赖于zircon,首先要编译zircon,之后再是编译fuchsia目标。
~/fuchsia$ scripts/fx build default
ninja: Entering directory `/home/kai/fuchsia/out/default.zircon'
ninja: no work to do.
ninja: Entering directory `/home/kai/fuchsia/out/default'
[1/1] Regenerating ninja files
[355/355] STAMP obj/default.stamp
~/fuchsia$
来看一下tools/devshell/build脚本中的主函数main。如果zircon的编译目录不存在,调用fx-gen函数创建(tools/devshell/lib/var.sh),此函数使用buildtools/gn脚本创建编译目录。如上所示,如果指定编译fuchsia的target(如上的default),脚本将自动为zircon_target增加一个default目标。即编译fuchsia时将先编译zircon的default目标。随后调用run-ninja函数进行zircon相关编译,编译目录指定-C为:out/default.zircon。通常情况下参数${zircon_targets[@]}为空。
function main {
if [ ! -d "$ZIRCON_BUILDROOT" ]; then
echo >&2 "Re-running gn gen first (missing $ZIRCON_BUILDROOT)"
fx-gen || return
fi
if [ ${#fuchsia_targets[@]} -ne 0 ]; then
zircon_targets+=(default)
fi
run-ninja -C "${ZIRCON_BUILDROOT}" "${switches[@]}" "${zircon_targets[@]}"
在zircon编译完成之后,如果只是编译zircon相关target,主函数至此结束。如果编译zircon的default目标是为了准备编译fuchsia目标,接下来再次调用run-ninja编译fuchsia。编译目录指定为:out/default。
# If there were explicit Zircon targets and no other explicit targets,
# the Zircon run was enough by itself. Otherwise Zircon default is
# a prerequisite for any Fuchsia target (including implicit default).
if [ ${#fuchsia_targets[@]} -ne 0 -o ${#zircon_targets[@]} -eq 0 ]; then
run-ninja -C "${FUCHSIA_BUILD_DIR}" "${switches[@]}" "${fuchsia_targets[@]}"
fuchsia_status=$?
if [ "${status}" -eq 0 ]; then
status="${fuchsia_status}"
fi
fi
return "${status}"
}
简化一下,函数run-ninja仅是封装了fx-run-ninja函数(tools/devshell/lib/vars.sh),最终调用buildtools/ninja脚本执行编译。
function run-ninja {
(fx-run-ninja "${FUCHSIA_DIR}/buildtools/ninja" "$@") || exit
}
脚本buildtools/ninja如下。只是给SCRIPT_ROOT和TOOL_NAME两个变量赋值,调用exec_tool.sh脚本。
readonly SCRIPT_ROOT="$(cd $(dirname ${BASH_SOURCE[0]} ) && pwd)"
readonly TOOL_NAME=$(basename "$0")
source "${SCRIPT_ROOT}/exec_tool.sh"
脚本exec_tool.sh如下。根据系统架构获取动编译工具的路径,执行编译。例如最终的ninja路径为:buildtools/linux-x64/ninja。
case "$(uname -s)" in
Darwin)
readonly HOST_PLATFORM="mac-x64"
;;
Linux)
readonly HOST_PLATFORM="linux-x64"
;;
esac
readonly TOOL_PATH="${SCRIPT_ROOT}/${HOST_PLATFORM}/${TOOL_NAME}"
exec "${TOOL_PATH}" "$@"
ninja的编译规则文件默认为build.ninja,如下out/default.zircon目录下的build.ninja文件。
~/fuchsia$ ls -l out/default.zircon/build.ninja*
-rw-rw-r-- 1 kai kai 1023201 Jun 13 02:46 out/default.zircon/build.ninja
-rw-rw-r-- 1 kai kai 49635 Jun 13 02:46 out/default.zircon/build.ninja.d
~/fuchsia$
使用如下的ninja命令工具deps可查看功能的依赖关系(只显示一部分),目标cowsay.cowsay.o的依赖关系包括一个C文件和多个头文件。
~/fuchsia$ buildtools/linux-x64/ninja -C out/default -t deps
obj/examples/cowsay/cowsay.cowsay.o: #deps 8, deps mtime 1560228190 (VALID)
../../examples/cowsay/cowsay.c
../../zircon/third_party/ulib/musl/include/stdio.h
../../zircon/third_party/ulib/musl/include/features.h
../../zircon/third_party/ulib/musl/include/bits/alltypes.h
../../zircon/third_party/ulib/musl/include/bits/null.h
../../buildtools/linux-x64/clang/lib/clang/9.0.0/include/stddef.h
../../zircon/third_party/ulib/musl/include/string.h
../../zircon/third_party/ulib/musl/include/strings.h
ninja运行产生的依赖关系和日志文件位于编译目录下,分别为.ninja_deps和.ninja_log。
~/fuchsia$ ls -l out/default/.ninja_*
-rw-rw-r-- 1 kai kai 7086288 Jun 11 06:18 out/default/.ninja_deps
-rw-rw-r-- 1 kai kai 3025583 Jun 13 02:48 out/default/.ninja_log
~/fuchsia$
ninja工具命令browse可生成依赖图,启动一个运行在8000端口的web服务,可通过浏览器查看。可指定本地监听地址:--host=192.168.1.x,也可指定监听端口,如--port=8080。
~/fuchsia$ buildtools/linux-x64/ninja -C out/default -t browse
Web server running on localhost:8000, ctl-C to abort...
Web server pid 91479
END