Skip to content

Commit

Permalink
pw_build: Add check_includes to generated GN
Browse files Browse the repository at this point in the history
This CL extends generate_3p_gn.py to allow specifying a list of targets
that should have `check_includes = false` applied to them.

See also:
https://gn.googlesource.com/gn/+/main/docs/reference.md#var_check_includes

Change-Id: Ib15fa38017407ec10385db497b3849f53e93ef62
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/146591
Commit-Queue: Aaron Green <[email protected]>
Reviewed-by: Taylor Cramer <[email protected]>
  • Loading branch information
nopsledder authored and CQ Bot Account committed May 15, 2023
1 parent bf4c22f commit 45c67ca
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 3 deletions.
9 changes: 9 additions & 0 deletions pw_build/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ describe a single JSON object, with the following fields:
"allow_testonly": true
* ``no_gn_check``: List of Bazel targets that violate ``gn check``'s
`rules`__. Third-party targets that do not conform can be excluded.

.. code-block::
"no_gn_check": [ "//fuzztest:regexp_dfa" ]
.. __: https://gn.googlesource.com/gn/+/main/docs/reference.md#cmd_check

Python packages
---------------
GN templates for :ref:`Python build automation <docs-python-build>` are
Expand Down
2 changes: 2 additions & 0 deletions pw_build/py/generate_3p_gn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ def test_write_build_gn(self):
"""Tests writing a complete BUILD.gn file."""
generator = GnGenerator()
generator.set_repo('test')
generator.exclude_from_gn_check(bazel='//bar:target3')

generator.add_configs(
'',
Expand Down Expand Up @@ -485,6 +486,7 @@ def test_write_build_gn(self):
# Generated from //bar:target3
pw_source_set("target3") {
check_includes = false
cflags = [
"bar-flag",
]
Expand Down
20 changes: 18 additions & 2 deletions pw_build/py/pw_build/generate_3p_gn.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def __init__(self) -> None:
self._repo: str
self._repo_var: str
self._repos: Dict[str, Set[str]] = defaultdict(set)
self._no_gn_check: List[GnLabel] = []
self.configs: Dict[str, List[GnConfig]] = defaultdict(list)
self.targets: Dict[str, List[GnTarget]] = defaultdict(list)

Expand All @@ -127,6 +128,16 @@ def set_repo(self, repo: str) -> None:
self._base_label = GnLabel(f'$dir_pw_third_party/{repo}')
self._base_path = GnPath(f'$dir_pw_third_party_{self._repo_var}')

def exclude_from_gn_check(self, **kwargs) -> None:
"""Mark a target as being excluding from `gn check`.
This should be called before loading or adding targets.
Args:
kwargs: Same as `GnLabel`.
"""
self._no_gn_check.append(GnLabel(self._base_label, **kwargs))

def load_workspace(self, workspace_path: Path) -> str:
"""Loads a Bazel workspace.
Expand All @@ -137,7 +148,7 @@ def load_workspace(self, workspace_path: Path) -> str:
self.set_repo(self._workspace.repo)
return self._repo

def loadtargets(self, kind: str, allow_testonly: bool) -> None:
def load_targets(self, kind: str, allow_testonly: bool) -> None:
"""Analyzes a Bazel workspace and loads target info from it.
Target info will only be added for `kind` rules. Additionally,
Expand All @@ -161,6 +172,7 @@ def add_target(self, allow_testonly: bool = False, **kwargs) -> None:
Same as `GnTarget`.
"""
target = GnTarget(self._base_label.dir(), self._base_path, **kwargs)
target.check_includes = target.label() not in self._no_gn_check
if allow_testonly or not target.testonly:
package = target.package()
self.packages.add(package)
Expand Down Expand Up @@ -262,6 +274,7 @@ def write_build_gn(self, package: str, build_gn: GnWriter) -> None:
Args:
package: The name of the package to write a BUILD.gn for.
build_gn: The output writer object.
no_gn_check: List of targets with `check_includes = false`.
"""
build_gn.write_imports(['//build_overrides/pigweed.gni'])
build_gn.write_blank()
Expand Down Expand Up @@ -391,8 +404,11 @@ def _generate_gn(workspace_path: Path) -> None:
add_configs = obj.get('add', [])
removeconfigs = obj.get('remove', [])
allow_testonly = obj.get('allow_testonly', False)
no_gn_check = obj.get('no_gn_check', [])

generator.loadtargets('cc_library', allow_testonly)
for exclusion in no_gn_check:
generator.exclude_from_gn_check(bazel=exclusion)
generator.load_targets('cc_library', allow_testonly)
generator.generate_configs(add_configs, removeconfigs)

with GnFile(Path(output, f'{repo}.gni')) as repo_gni:
Expand Down
9 changes: 9 additions & 0 deletions pw_build/py/pw_build/gn_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(
base_path: Union[str, PurePosixPath, GnPath],
bazel: Optional[BazelRule] = None,
json: Optional[str] = None,
check_includes: bool = True,
) -> None:
"""Creates a GN target
Expand All @@ -70,6 +71,7 @@ def __init__(
self._repos: Set[str] = set()
self.visibility: List[GnVisibility] = []
self.testonly: bool = False
self.check_includes = check_includes
self.public: List[GnPath] = []
self.sources: List[GnPath] = []
self.inputs: List[GnPath] = []
Expand Down Expand Up @@ -167,6 +169,7 @@ def _from_json(self, data: str) -> None:
for scope in obj.get('visibility', [])
]
self.testonly = bool(obj.get('testonly', False))
self.testonly = bool(obj.get('check_includes', False))
self.public = [GnPath(path) for path in obj.get('public', [])]
self.sources = [GnPath(path) for path in obj.get('sources', [])]
self.inputs = [GnPath(path) for path in obj.get('inputs', [])]
Expand All @@ -193,6 +196,8 @@ def to_json(self) -> str:
obj['visibility'] = [str(scope) for scope in self.visibility]
if self.testonly:
obj['testonly'] = self.testonly
if not self.check_includes:
obj['check_includes'] = self.check_includes
if self.public:
obj['public'] = [str(path) for path in self.public]
if self.sources:
Expand Down Expand Up @@ -222,6 +227,10 @@ def name(self) -> str:
"""Returns the target name."""
return self._label.name()

def label(self) -> GnLabel:
"""Returns the target label."""
return self._label

def type(self) -> str:
"""Returns the target type."""
return self._type
Expand Down
2 changes: 2 additions & 0 deletions pw_build/py/pw_build/gn_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ def write_target(self, target: GnTarget) -> None:
visibility = [target.make_relative(scope) for scope in scopes]
self.write_list('visibility', visibility)

if not target.check_includes:
self.write('check_includes = false')
self.write_list('public', [str(path) for path in target.public])
self.write_list('sources', [str(path) for path in target.sources])
self.write_list('inputs', [str(path) for path in target.inputs])
Expand Down
3 changes: 2 additions & 1 deletion third_party/fuzztest/repo.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"$dir_pw_toolchain/host_clang:sanitize_undefined_heuristic",
"$dir_pw_toolchain/host_clang:sanitize_thread"
],
"allow_testonly": true
"allow_testonly": true,
"no_gn_check": [ "//fuzztest:regexp_dfa" ]
}

0 comments on commit 45c67ca

Please sign in to comment.