-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
133 changed files
with
3,280 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Make sure not to use legacy features and be prepared for future Bazel versions | ||
# These flags have to be supported by all Bazel versions supported by DWYU | ||
# Flags only available for specific Bazel versions are managed directly in the acceptance tests | ||
common --incompatible_disable_target_provider_fields | ||
common --incompatible_disallow_empty_glob | ||
common --incompatible_no_implicit_file_export | ||
common --incompatible_struct_has_no_methods | ||
common --incompatible_use_cc_configure_from_rules_cc | ||
common --incompatible_use_platforms_repo_for_constraints | ||
common --incompatible_visibility_private_attributes_at_definition | ||
build --incompatible_default_to_explicit_init_py | ||
|
||
# Allow users to provide their own workspace settings | ||
try-import %workspace%/.bazelrc.user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* @martis42 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
*~ | ||
|
||
# Bazel | ||
bazel-* | ||
.bazelrc.user | ||
|
||
# Python | ||
__pycache__ | ||
*.pyc | ||
|
||
# IDEs | ||
.clwb | ||
.idea | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Code reviews | ||
|
||
All contributions require a review from the [code owners](.github/CODEOWNERS). | ||
|
||
# Bug reports | ||
|
||
Please make sure you are aware of the [early project stage](https://github.com/martis42/depend_on_what_you_use#word-of-warning) and are accustomed with the [known limitations](https://github.com/martis42/depend_on_what_you_use#known-limitations) | ||
|
||
Please introduce a minimal example for reproducing the bug. | ||
Ideally as a test case, but any minimal example helps | ||
|
||
# Feature changes/requests | ||
|
||
* Please create an [issue](https://github.com/martis42/depend_on_what_you_use/issues) before changing features or introducing new features. | ||
Discussing your idea first makes sure it is in the interest of the project and your work will not be in vain due to following an undesired direction. | ||
* No feature shall be changed or introduced without adapting or adding tests accordingly. | ||
|
||
# Trivial changes | ||
|
||
Feel free to directly create pull requests without creating an issue for small improvements like fixing typos. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Martin Medler | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,190 @@ | ||
# depend_on_what_you_use | ||
# Depend on what you use (DWYU) | ||
|
||
DWYU is a Bazel aspect for C++ projects to make sure the headers your targets are using are aligned with the targets dependency list. | ||
It applies the principals established by [Include What You Use](https://github.com/include-what-you-use/include-what-you-use) | ||
to the dependencies of your `cc_*` targets. | ||
|
||
The main features are: | ||
* Finding include statements which are not available through a direct dependency, aka **preventing to rely on transitive dependencies** | ||
* Finding unused dependencies | ||
* Given one uses `implementation_deps`, finding dependencies which are used only in private code and thus should be an implementation dependency | ||
|
||
# Word of Warning | ||
|
||
This project is still in a prototyping phase. | ||
It has been made public to ease sharing with other developers for gathering feedback on the concept. | ||
Do not expect stability of | ||
* the git history | ||
* the project structure | ||
* the feature set | ||
* the tools chosen to implement DWYU | ||
|
||
# Getting started | ||
|
||
## Get a release | ||
|
||
Choose a release from the [release page](https://github.com/martis42/depend_on_what_you_use/releases) and follow the instructions. | ||
|
||
## Get a specific commit | ||
|
||
Put the following into your `WORKSPACE` file: | ||
```sh | ||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") | ||
|
||
dwyu_version = "<git_commit_sha>" | ||
|
||
http_archive( | ||
name = "depend_on_what_you_use", | ||
sha256 = "<archive_checksum>", | ||
strip_prefix = "depend_on_what_you_use-{}".format(dwyu_version), | ||
url = "https://github.com/bazelbuild/rules_python/archive/{}.zip".format(dwyu_version), | ||
) | ||
``` | ||
|
||
## Use DWYU | ||
|
||
### Configure the aspect | ||
|
||
Configure an aspect with the desired behavior. | ||
The features which can be configured trough the the aspect factory attributes are documented at [Features](#features). | ||
Put the following inside a `aspect.bzl` file (file name is exemplary): | ||
```sh | ||
load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") | ||
|
||
# Provide no arguments for the default behavior | ||
# Or set a custom value for the various attributes | ||
your_dywu_aspect = dwyu_aspect_factory() | ||
``` | ||
|
||
### Use the aspect | ||
|
||
Invoke the aspect through the command line on a target: \ | ||
`bazel build <target_pattern> --aspects=//:aspect.bzl%your_dywu_aspect --output_groups=cc_dwyu_output` | ||
|
||
If no problem is found, the command will exit with `INFO: Build completed successfully`. \ | ||
If a problem is detected, the build command will fail with an error and a description of the problem will be printed in the terminal. | ||
For example: | ||
``` | ||
================================================================================ | ||
DWYU: Failure | ||
Unused dependencies (none of their headers are referenced): | ||
Dependency='//some/target/with_an_unused:dependency' | ||
=============================================================================== | ||
``` | ||
|
||
### Create a rule invoking the aspect. | ||
|
||
You can invoke the aspect from within a rule. | ||
This can be useful to make the execution part of a bazel build (e.g. `bazel build //...`) without having to execute the longish manual aspect build command. | ||
|
||
The Bazel documentation for invoking an aspect from within a rule can be found [here](https://bazel.build/rules/aspects#invoking_the_aspect_from_a_rule). | ||
A concrete example for doing so for a DWYU aspect can be [found in the recursion test cases](test/recursion/rule.bzl). | ||
|
||
## Features | ||
|
||
### Custom header ignore list | ||
|
||
By default DWYU ignores all header from the standard library when comparing include statements to the dependencies. | ||
|
||
You can exclude a custom set of header files by providing a config file in json format to the aspect. | ||
An example for this and the correct format can be seen at [test/custom_config](../test/custom_config). | ||
|
||
### Recursion | ||
|
||
By default DWYU analyzes only the target it is being applied to. | ||
|
||
You can activate recursive analysis, meaning the aspect analyzes recursively all dependencies of the target it is being | ||
applied to. Activate this behavior via: | ||
``` | ||
your_aspect = dwyu_aspect_factory(recursive = True) | ||
``` | ||
|
||
This can be used to create a rule invoking DWYU on a target and all its dependencies as part of a normal build command. | ||
Also it can be a convenience to analyze specific fraction of your stack without utilizing bazel (c)query. | ||
|
||
Examples for this can be seen at [test/recursion](../test/recursion). | ||
|
||
### Measure dependency utilization | ||
|
||
If a library provides many headers but typically only a fraction of them are used at the call sites, this can be a hint | ||
that the library should be split into smaller parts. DWYU allows you to find cases where a percentage less than | ||
a provided threshold of headers from a dependency is used by a call site. | ||
|
||
This feature is intended to analyze your stack and search for suboptimal dependencies. It is not recommended to enforce | ||
unconditionally a minimum dependency header utilization on your whole stack. \ | ||
Using `include_prefix`, `strip_include_prefix` or `includes` on `cc_` targets tampers with the reliability of this measurement. | ||
Those attributes make multiple include paths available for a single header file. | ||
These, paths appear as multiple files to the DWYU implementation. | ||
Consequently, the amount of headers provided by a dependency increases virtually and thus utilization drops. | ||
|
||
Activate this behavior via: | ||
``` | ||
your_aspect = dwyu_aspect_factory(min_utilization = [0..100]) | ||
``` | ||
|
||
Examples for this can be seen at [test/dependency_utilization](../test/dependency_utilization). | ||
|
||
### Implementation_deps | ||
|
||
Bazel 5.0.0 introduces the experimental feature [`implementation_deps`](https://docs.bazel.build/versions/main/be/c-cpp.html#cc_library.implementation_deps) | ||
for `cc_library`. In short, this enables you to specify dependencies which are only relevant for your `srcs` files and | ||
are not made available to users of the library. | ||
|
||
DWYU can report dependencies which are only used in private sources and should be moved from `deps` to `implementation_deps`. | ||
|
||
Activate this behavior via: | ||
``` | ||
your_aspect = dwyu_aspect_factory(use_implementation_deps = True) | ||
``` | ||
|
||
Examples for this can be seen at [test/implementation_deps](../test/implementation_deps). | ||
|
||
## Supported Platforms | ||
|
||
### Bazel | ||
|
||
Minimum required Bazel version is **4.0.0**. | ||
* Before 3.3.0 CcInfo compilation_context has a structure which is not supported by the aspect | ||
* Before 4.0.0 the global json module is not available in Starlark | ||
|
||
### Python | ||
|
||
Requires Python 3. Code is only tested with Python 3.8, but should work with most 3.X versions. | ||
|
||
## Operating system | ||
|
||
DWYU is not designed for a specific platform. | ||
Ubuntu 20.04 is however the only OS DWYU is currently being tested on. | ||
|
||
## Known limitations | ||
|
||
* If includes are added through a macro, this is invisible to DWYU. | ||
* Defines are ignored. | ||
No matter if they are defined directly inside the header under inspection, headers from the dependencies or injected through the `defines = [...]` attribute of the `cc_` rules. | ||
* Include statements utilizing `..` to go up the directory tree are not resolved. | ||
|
||
# Project Roadmap | ||
|
||
## Overview of current state | ||
|
||
The focus until now has been to come up with a prototype for the idea behind DWYU and to be able to gather first user feedback. | ||
|
||
[Test cases](test) have been established to make sure the concept works with a wide range of use cases and DWYU can evolve without introducing regressions. | ||
|
||
The Bazel aspect implementation is for sure not yet ideal, but is considered it a solid starting point. | ||
|
||
The Python implementation to analyze the include statements in C++ code is a minimal implementation with [several restrictions](#Known-limitations). | ||
If it will be expanded or replaced is currently unclear. | ||
|
||
## TODOs | ||
|
||
See [docs/todos](docs/todos.md). | ||
|
||
# Contributing | ||
|
||
See [Contributing](CONTRIBUTING.md). | ||
|
||
# License | ||
|
||
Copyright © 2022-present, [Martin Medler](https://github.com/martis42). \ | ||
This project licensed under the [MIT](https://opensource.org/licenses/MIT) license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
workspace(name = "depend_on_what_you_use") | ||
|
||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") | ||
|
||
# | ||
# External dependencies | ||
# | ||
|
||
http_archive( | ||
name = "rules_python", | ||
sha256 = "a30abdfc7126d497a7698c29c46ea9901c6392d6ed315171a6df5ce433aa4502", | ||
strip_prefix = "rules_python-0.6.0", | ||
urls = ["https://github.com/bazelbuild/rules_python/archive/0.6.0.tar.gz"], | ||
) | ||
|
||
http_archive( | ||
name = "bazel_skylib", | ||
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", | ||
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz"], | ||
) | ||
|
||
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") | ||
|
||
bazel_skylib_workspace() | ||
|
||
# | ||
# Project | ||
# | ||
|
||
load("@bazel_skylib//lib:versions.bzl", "versions") | ||
|
||
versions.check(minimum_bazel_version = "4.0.0") | ||
|
||
# | ||
# Testing | ||
# | ||
|
||
load("//test:test.bzl", "test_setup") | ||
|
||
test_setup() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
exports_files(["private/empty_default_config.json"]) |
Oops, something went wrong.