源代码布局

搜索源代码

要查看和搜索 Fuchsia 源代码,您可以选择以下选项:

概览

大多数第一方开源代码都位于“fuchsia.git”代码库中。此代码库中的大部分代码都会整理成递归的 areas 树。

区域具有常规的内部和依赖项结构。fuchsia.git 代码库本身遵循区域的结构,但还有顶级所独有的其他结构。

具体来说,可以将 fuchsia.gitsrc 顶级目录视为根区域。它遵循区域要求的结构,并且是子区域所在的地点。不过,需要某个区域的某些目录也存在于 src 旁边,而不是位于该区域中,例如 third_party。您可以将这些最佳实践视为面向所有领域的全球性全球性平台。src 之外还有其他位置包含更高级区域,例如在 vendor/* 中。作为开源代码 third_party,所有区域都可以使用。

无论是开源代码库还是闭源代码库,也遵循区域规范,并映射到 fuchsia.git 中 src 的子目录。目前,我们只有少量此类“花瓣”代码库,但随着系统稳定,我们会将 fuchsia.git 代码库中当前存在的区域“推广”到单独的代码库。

vendor/* 目录包含闭合源代码,由该代码的供应商整理。//vendor 以外的任何内容都不能依赖于 //vendor。支持不同供应商之间的依赖项,vendor/A 可以依赖于 vendor/B

products 目录包含您可以构建的产品列表。有些产品体积非常小,构建速度很快(例如核心产品),而其他产品则比较复杂(例如 workbench_eng 产品)。

sdk 目录包含构成 Fuchsia API Surface 的库。其中一些库是客户端库,而另一些库是 FIDL 库。并非所有这些库都会在 Fuchsia SDK 中分发。所有非测试 FIDL 库都应放在 //sdk/fidl 目录中,按 FIDL 库名称组织,包括仅用于 Fuchsia 平台源代码树的库。这些库可以使用默认的 sdk_category(即 internal),这样可以防止将其分发给合作伙伴,也可以将库明确标记为 internal,并添加注释来提醒用户其预期用途。

大多数第三方依赖项都存储在单独的代码库中。只有在需要支持以下源代码树配置之一时,这些代码库才会包含在本地检出中:

  • 启动:此源代码树配置包含足够的代码来构建 bringup 产品。
  • 开源。此源代码树配置包含 Fuchsia 源代码树中的所有开源代码。
  • 所有来源。此源代码树配置包含 Fuchsia 源代码树中的所有开放和封闭源代码。

请参阅相关指南,了解如何为 README.fuchsia 文件中编写第三方代码的元数据。

领域

大多数代码都会整理成递归的区域树。每个区域都有常规的内部和依赖项结构,这有助于人们了解整个项目的代码结构。

目录结构

每个区域都需要有一个 OWNERS 文件以及文档和测试。还可以包含二进制文件、库、驱动程序和其他源代码。此外,区域可以包含重复该模式的子区域:

  • OWNERS
  • BUILD.gn
    • 为区域定义规范目标的 build 文件。除了规范目标之外,区域所有者还可以为此目标添加其他目标。
  • docs/
    • 此目录应包含适用于此区域工作人员的文档
    • 面向最终开发者(或在 Fuchsia 其他领域工作的人员)的文档应位于顶级文档或 SDK 代码库中
  • bundles/
    • 此目录包含此区域的软件包目标捆绑包。每个区域都应至少包含一个 tests 软件包,其中包含该区域的单元测试,但可以包含其他软件包。
  • bin/(可选)
  • lib/(可选)
  • drivers/(可选)
  • examples/(可选)
  • tests/(可选)
    • 此目录包含跨越同一区域内多个源代码目录的集成测试
    • 如果不同的区域可以在子目录中放置测试,建议为不同的测试目录添加 OWNERS 文件,以阐明所有权。
    • 涵盖单个二进制文件或库的单元测试最好与其测试的代码放在一起
  • testing/(可选)
    • 此目录包含可用于编写此区域和子区域的测试的实用程序和库。
    • 此目录中的目标只能由 testonly 目标依赖于。
  • third_party/(可选)
    • 大多数 third_party 依赖项应该位于单独的仓库中
    • 仅当满足以下所有条件时,才能在某个区域添加 third_party 依赖项:
      • 根据政策,该代码必须位于 third_party 目录中
      • 您打算向上游创建分支(即进行重大更改,但不计划集成未来的上游更改)
      • 您为 (a) 与上游不匹配且 (b) 未出现在 Fuchsia 源代码树中任何位置的任何其他 third_party 目录中的代码都使用了新的名称。
      • 代码是开源的
    • 如需详细了解 third_party 源代码布局,请参阅第三方源代码管理
  • tools/(可选)
    • 此目录包含由该区域提供的命令行工具。这些通常可以(或必须)为开发主机(而不是 Fuchsia)构建。它们不一定会在相应区域自己的 build 中直接使用,但也可以供开发者使用。这些测试不一定会在 SDK 中发布。build 中使用但确实不适合开发者直接使用的特殊用途工具应与其用途相近,而非此处。
    • 它应该包含一个针对每种工具命名的子目录(或具有自然集合名称的相关工具集合),而不是将该区域的所有工具放在顶层 tools/BUILD.gn 文件中。
  • [subareas](可选)
    • 子区域应遵循通用区域模板
    • 不要创建深层嵌套的区域结构(例如,三个应该就足够了)

除了枚举目录之外,各区域还可能使用其他目录进行内部组织。

所有者

每个区域和子区域都必须包含一个 OWNERS 文件。目录可以包含 OWNERS 而不被视为区域,例如顶级 products 目录或 /src/lib 目录的子目录。缺少 OWNERS 文件的目录与其同一区域的父目录具有相同的所有者。

一种例外情况是 //src/tests 目录,来自不同区域、涵盖系统多个方面(而不仅限于特定区域)的测试预计会进行。因此,每个区域都应为位于此目录中的任何测试添加 OWNERS 文件。

依赖项结构

除了依赖于自身之外,区域还可以仅依赖于顶级 buildsdkthird_party 目录,以及树中任何位置的 lib 目录:

  • //build
  • //sdk
  • //third_party
  • //src/**/lib/

在构建系统中标记为 test only 的区域中的目标可能还依赖于该区域中的 testing 目录和祖先实体:

  • (../)+testing/(仅限 testonly=true 目标)

规范化目标

每个区域和子区域都必须在其顶级 BUILD.gn 文件中定义以下规范目标:

  • <dir-name>

    • 所有目录都应具有与该目录同名的目标。目录目标本质上是一个“全部”目标,旨在并用于生成“build-everything”构建。
    • 目录和子目录中定义的所有可构建工件。
    • 当前目录和子目录中的所有测试。
    • 目录目标应仅生成最大数量的 build,而不应包含可能会修改特定产品的“产品行为”的配置目标或变更。例如,包含目录目标不应导致新软件在启动时自动启动,也不应替换默认服务拓扑或服务映射。
    • 向某个区域添加新的子目录时,该目录应定义此目录名称目标,并将目录名称目标包含到父目录目标中。
  • tests

    • 此区域中的所有测试
    • 添加包含新测试目标的新子目录时,应将测试目标添加到父级目录测试目标中。

命名惯例

通常,为文件和目录命名时,最佳实践是使用简短明了的名称。如果名称由多个单词组成,这些单词应以下划线分隔,例如 long_file_name

示例

以下是名为 fortune 的目录的示例。

import("//build/drivers.gni")
import("//build/components.gni")

group("fortune") {
  testonly = true
  deps = [
    ":pkg",
    ":tests",
  ]
}

group("tests") {
  testonly = true
  deps = [
    ":fortune_tests"
  ]
}

executable("bin") {
  output_name = "fortune"

  sources = [
    "fortune.cc"
  ]
}

executable("test") {
  testonly = true
  output_name = "fortune-test"

  sources = [
    "test.cc"
  ]
}

fuchsia_component("component") {
  manifest = "meta/fortune.cml"
  deps = [ ":bin" ]
}

fuchsia_package("pkg") {
  package_name = "fortune"
  deps = [ ":component" ]
}

fuchsia_unittest_package("fortune_tests") {
  deps = [ ":test" ]
}

代码库布局

本部分介绍了 Fuchsia 源代码树的目录布局。未加星标的条目是 fuchsia.git 代码库中的目录或文件。已加星标 (*) 条目是使用 jiri 映射到目录结构的单独代码库(预构建目录除外,该目录通过 CIPD 填充)。

  • .clang-format
  • .dir-locals.el
  • .gitattributes
  • .gitignore
  • AUTHORS
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • LICENSE
  • OWNERS
  • PATENTS
  • README.md
  • rustfmt.toml
  • sdk/banjo/fuchsia.hardware.gpio/
  • sdk/banjo/...
  • sdk/fidl/fuchsia.media/
  • sdk/fidl/fuchsia.mediacodec/
  • sdk/fidl/...
  • sdk/lib/ddk/
  • sdk/lib/fit/
  • sdk/lib/fidl/
  • sdk/lib/zircon/
  • sdk/lib/...
  • .gn
  • BUILD.gn
  • build/
  • bundles/
  • configs/
  • infra/
    • configs/
      • generated/
  • integration/
  • products/
  • scripts/
  • docs/
  • examples/
  • third_party/
    • boringssl/ *
    • icu/ *
    • rust_crates/ *
    • ... *
  • prebuilt/
    • chromium/ *
    • llvm/ *
  • tools/
    • banjo/
    • fidl/bin/backend/{c,cpp,dart,go,llcpp,rust}
    • fidl/bin/frontend/
    • fidl/docs/
    • fidl/examples/
    • fidl/tests/
  • src/
    • lib/
    • cobalt/
    • component/
    • connectivity/
    • developer/
    • experiences/ *
    • graphics/
    • identity/
    • media/
    • storage/
    • testing/
    • ui/
      • scenic/
    • updater/
    • virtualization/
    • zircon/kernel/
    • zircon/drivers/
    • zircon/userspace/
  • vendor/
    • [closed-source code from various vendors] *

进化

当系统稳定后,我们可以将 fuchsia.git 之外的区域推广到单独的代码库。通常,当某个区域与系统其余部分之间的接口足够稳定(需要获得顶级 OWNERS 的批准)时,我们应将该区域提升为单独的代码库。

新代码可以是:

  • 添加到 fuchsia.git 中的现有目录
  • 添加到现有区域的新顶级区域或子区域
  • 已添加至现有代码库
  • 添加到了新的代码库(需要顶级所有者的批准)