源代码布局

搜索源代码

如需查看和搜索 Fuchsia 源代码,您可以使用以下选项:

概览

大多数第一方开源代码位于 “fuchsia.git”代码库中。此代码库中的大多数代码都组织为区域的递归树。

区域具有常规的内部结构和依赖项结构。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 平台源代码树中使用的库。这些库可以使用默认的 internal sdk_category,这会阻止将其分发给合作伙伴;也可以通过添加注释来明确标记为 internal,以提醒用户其预期用途。

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

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

请参阅有关在 README.fuchsia 文件中为第三方代码编写元数据的准则

区域

大多数代码都组织为区域的递归树。每个区域都有常规的内部结构和依赖项结构,这有助于用户了解整个项目的代码结构。

目录结构

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

  • OWNERS
  • BUILD.gn
    • 用于定义相应区域的规范化目标的 build 文件。除了规范目标之外,区域所有者还可以在此添加其他目标。
  • docs/
    • 此目录应包含面向此领域工作的人员的文档
    • 面向最终开发者(或在 Fuchsia 的其他领域工作的人员)的文档应位于顶级文档或 SDK 代码库中
  • bundles/
    • 此目录包含此区域中软件包目标的软件包。每个区域都应至少包含一个包含该区域单元测试的 tests 软件包,但可以包含其他软件包。
  • bin/(可选)
  • lib/(可选)
  • drivers/(可选)
  • examples/(可选)
  • manifests/
    • 此目录包含 Jiri 清单。
    • Jiri 清单文件用于描述在您运行 jiri update 时要同步的一组项目。如需了解详情,请参阅README
  • tests/(可选)
    • 此目录包含跨该区域内的多个源代码目录的集成测试
    • 如果不同的领域可以在子目录中包含测试,建议为不同的测试目录添加 OWNERS 文件,以明确所有权。
    • 涵盖单个二进制文件或库的单元测试最好与要测试的代码放在一起
  • testing/(可选)
    • 此目录包含在该领域和子领域中编写测试时有用的实用程序和库。
    • 此目录中的目标只能由仅用于测试的目标依赖。
  • 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/

在构建系统中被标记为“仅用于测试”的区域中的目标可能还依赖于该区域和父级目录中的 testing 目录:

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

规范目标

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

  • 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 中的各个区域提升到单独的代码库中。通常,当某个领域与系统的其余部分之间的接口足够稳定时(需要顶级 OWNER 批准),我们应将该领域提升为单独的代码库。

新代码可以是:

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