This document reviews the policies and best practices for ensuring clear separation between third party and first party code.
Third party code is part of the Fuchsia checkout but is neither copyrighted by the Fuchsia authors nor subject to Fuchsia's license. In other words, any code that is not 100% owned by the Fuchsia authors should be managed as third party code.
The Fuchsia project maintains copies of third party code dependencies under the
//third_party/
directory in the checkout. This is also known as vendoring.
Vendoring ensures that third party code is served from Fuchsia-owned source
repositories and is served at revisions that are known to work with other code
in the Fuchsia checkout.
To ensure that third party code is in compliance with the the Fuchsia project policies, follow the best practices in the section below. These best practices also help simplify maintenances tasks, for instance, when updating third party code to newer revisions from upstream repositories.
This section describes the recommended strategy for manually managing third party code. However, if possible, automated dependency management solutions are preferred.
Below is the recommended source layout, using googletest
as an example:
root [fuchsia.googlesource.com/fuchsia]
third_party/
googletest/
BUILD.gn
OWNERS
README.fuchsia
src/ [fuchsia.googlesource.com/third_party/github.com/google/googletest]
Note the following:
//third_party/googletest/src/
is the root of a Fuchsia-owned mirror repository that contains a copy of the upstream repository{:.external} forgoogletest
.//third_party/googletest/
is within thefuchsia.git
repository.//third_party/googletest/README.fuchsia
contains structured metadata regardinggoogletest
. SeeREADME.fuchsia
file syntax.//third_party/googletest/BUILD.gn
defines build targets for thegoogletest
library. Since this file belongs tofuchsia.git
(not thegoogletest
repository), it can be updated in lockstep with other FuchsiaBUILD.gn
files that depend ongoogletest
. This makes build refactors and other large-scale changes easier.//third_party/googletest/OWNERS
is the associatedOWNERS
file. Because it's defined infuchsia.git
, it is possible to include owners from other files elsewhere in the Fuchsia project.
Additional files that are required to adapt the third party code to the Fuchsia
project may be present under (in this case) //third_party/googletest
.
Third party repositories that had been introduced before the best practices were
established do not necessarily follow the recommended source layout in the
section above. For instance, these legacy repositories often mix first party
files (mainly BUILD.gn
) with third party files.
To migrate legacy third party repositories to the new layout, follow these steps:
Note: For Python repositories, replace //third_party/<name>/src
with
//third_party/<name>/<module_name>
to follow Python's convention.
This convention is expected by common Python tools like
pyright.
-
Move Fuchsia-specific
BUILD.gn
files to//build/secondary
.- Copy
BUILD.gn
files from//third_party/<name>
to//build/secondary/third_party/<name>
. If there is more than oneBUILD.gn
file, maintain the same subtree under//build/secondary
. - In the copied
BUILD.gn
files, update references to paths to third party files in the form of//third_party/<name>/
to the form of//third_party/<name>/src/
. - Copy
OWNERS
from//third_party/<name>
to//build/secondary/<name>
, or create it if it does not exist. Review theOWNERS
file to ensure that it follows the best practices. - Copy
README.fuchsia
from//third_party/<name>
to//build/secondary/<name>
. Review the contents of this file and ensure that the metadata is correct. In uncommon cases there are modifications made to third party code in third party repositories, and such changes are listed inREADME.fuchsia
. Local modifications will often require you to make special accommodations that are not covered in this guide. - Review
//third_party/<name>
for any other first party.gni
files and move those to//build/secondary/<name>
as well. - Update
//build/secondary/third_party/<name>/BUILD.gn
(and other files containing source paths such as.gni
files) to use the new source location//third_party/<name>/src
. This requires updating all sources, including directory paths and more.
Example: https://fxrev.dev/622785
Note: CQ won't catch errors in this change (for example, typos in paths) because the secondary build files are not yet active. You can validate that your
BUILD.gn
files are correct by staging the next commit (update the integration manifest), runningjiri update -local-manifest
, then building (such as withfx build
). - Copy
-
Update the integration manifest.
Note: This step can only be performed in Google's internal repositories at the moment.
Replace
path
(notname
) of the existing third party project at//third_party/<name>
with//third_party/<name>/src
, while keeping the revision unchanged. With this change merged, the Fuchsia build will switch to using theBUILD.gn
files from the previous step.Example: http://tqr/457911
-
Move Fuchsia-specific files added in step 1 to
//third_party/<name>
.Now that third party code is nested under
//third_party/<name>/src
and//third_party/<name>
is part offuchsia.git
, you can undo the transitional step 1.-
Wait for the integration manifest change to merge and roll, then run
jiri update
. Or stage the integration manifest change from the previous step in your local checkout, then runjiri update -local-manifest
. -
Move
BUILD.gn
and other Fuchsia-specific files from//build/secondary/<name>
to//third_party/<name>
. -
Update
//.gitignore
so that//third_party/<name>
is tracked but//third_party/<name>/src
is not tracked.
Example: https://fxrev.dev/622789
-
-
Turn
//third_party/<name>/src
into a mirror.Note: This step can only be performed in Google's internal repositories at the moment.
Change
//third_party/<name>/src
to track upstream such that it only has upstream changes in itsgit log
. You can do this by updating the integration manifest to reference an upstream commit hash.Example: http://tqr/427570
For automated dependency management solutions, see the following:
-
Rust: Follow the external Rust crates guide.
-
Dart: Follow the third party Dart packages guide.
-
Go: See
//third_party/golibs/
.
There are currently no solutions for automated management of C/C++ and Python dependencies. Please refer to the source layout section above.
The majority of third party dependencies can follow the practices described above. However, a small minority of dependencies that are subject to uncommon circumstances are managed differently.
Having exotic dependencies can increase complexity and maintenance costs, which are incurred by direct dependencies of the third party code. Additionally, they add complexity to common global maintenance tasks such as:
- Performing git administration tasks.
- Updating and maintaining toolchains.
- Responding to disclosed security vulnerabilities by updating vulnerable third party code from upstream sources.
- Refactoring build rules, such as to enforce new compile-time checks.
Please exercise careful deliberation when stepping off the beaten path.