├── dwyu ├── BUILD ├── aspect │ ├── private │ │ ├── analyze_includes │ │ │ ├── test │ │ │ │ ├── data │ │ │ │ │ ├── empty_header.h │ │ │ │ │ ├── config │ │ │ │ │ │ ├── empty.json │ │ │ │ │ │ ├── system_headers_info.json │ │ │ │ │ │ ├── ignore_patterns.json │ │ │ │ │ │ ├── extra_ignore_paths.json │ │ │ │ │ │ └── overwrite_default_ignore_paths.json │ │ │ │ │ ├── another_header.h │ │ │ │ │ ├── some_defines.h │ │ │ │ │ ├── .clang-format │ │ │ │ │ ├── include_based_on_pre_processor_token.h │ │ │ │ │ ├── commented_includes │ │ │ │ │ │ ├── mixed_style.h │ │ │ │ │ │ ├── single_line_comments.h │ │ │ │ │ │ └── block_comments.h │ │ │ │ │ ├── dep_info_bar.json │ │ │ │ │ ├── dep_info_foo.json │ │ │ │ │ ├── implementation_dep_info_bar.json │ │ │ │ │ ├── implementation_dep_info_foo.json │ │ │ │ │ ├── some_header.h │ │ │ │ │ ├── target_under_inspection_empty.json │ │ │ │ │ ├── use_defines.h │ │ │ │ │ ├── target_under_inspection.json │ │ │ │ │ └── header_with_defines.h │ │ │ │ └── benchmark │ │ │ │ │ ├── README.md │ │ │ │ │ └── BUILD │ │ │ └── BUILD │ │ ├── cc_toolchain_headers_info_stub.json │ │ ├── analyze_preprocessor_results │ │ │ ├── RREADME.md │ │ │ └── BUILD │ │ ├── preprocessing │ │ │ ├── extract_includes.h │ │ │ ├── executable_stub.bzl │ │ │ └── test │ │ │ │ ├── BUILD │ │ │ │ └── data │ │ │ │ └── commented_includes.h │ │ ├── BUILD │ │ ├── process_target │ │ │ └── BUILD │ │ └── cc_toolchain_headers_stub.bzl │ ├── test │ │ └── BUILD │ └── BUILD ├── cc_toolchain_headers │ ├── private │ │ ├── test │ │ │ ├── data │ │ │ │ ├── include_root │ │ │ │ │ ├── bar │ │ │ │ │ │ └── bar.h │ │ │ │ │ ├── relevant.h │ │ │ │ │ ├── foo │ │ │ │ │ │ ├── header.hpp │ │ │ │ │ │ └── no_extension_in_sub_dir_is_ignored │ │ │ │ │ ├── .hidden_is_ignored │ │ │ │ │ ├── relevant_no_extension │ │ │ │ │ └── wrong_extension.txt │ │ │ │ └── outside_search_path.h │ │ │ └── BUILD │ │ ├── empty.cpp │ │ └── BUILD │ ├── cc_toolchain_headers.bzl │ ├── providers.bzl │ └── BUILD ├── private │ ├── test │ │ ├── data │ │ │ └── multiple_options.txt │ │ ├── BUILD │ │ └── utils_test.bzl │ ├── utils.bzl │ ├── utils.cpp │ ├── BUILD │ └── utils.h ├── cc_info_mapping │ ├── providers.bzl │ ├── private │ │ ├── providers.bzl │ │ └── BUILD │ └── BUILD └── apply_fixes │ ├── utils.py │ ├── test │ ├── utils_test.py │ └── buildozer_executor_test.py │ └── BUILD ├── examples ├── BUILD ├── WORKSPACE.bzlmod ├── define_macros │ ├── lib.h │ ├── transitive_dep_a.h │ ├── transitive_dep_b.h │ ├── main.cpp │ └── BUILD ├── skipping_targets │ ├── lib_a.h │ ├── lib_b.h │ ├── use_broken_external_dependency.h │ └── use_transitive_dep.h ├── .bazelversion ├── support │ ├── external_targets │ │ ├── WORKSPACE │ │ ├── foo.h │ │ ├── has_unused_dep.h │ │ ├── BUILD │ │ └── MODULE.bazel │ └── external_targets.bzl ├── target_mapping │ ├── libs │ │ ├── c.h │ │ ├── a.h │ │ ├── b.h │ │ └── BUILD │ ├── use_lib_b.cpp │ ├── use_lib_c.cpp │ ├── BUILD │ └── mapping │ │ └── BUILD ├── rule_using_dwyu │ ├── bad_target.h │ ├── BUILD │ └── rule.bzl ├── basic_usage │ ├── my_type.h │ ├── use_lib.h │ ├── not_using_lib.h │ ├── lib.h │ ├── use_lib.cpp │ └── README.md ├── recursion │ ├── lib.h │ ├── use_lib.h │ └── BUILD ├── set_cpp_standard │ ├── use_specific_cpp_standard.h │ ├── cpp_lib.cpp │ ├── cpp_lib.h │ └── BUILD ├── ignoring_includes │ ├── ignore_includes.json │ ├── BUILD │ ├── use_unavailable_headers.h │ └── README.md └── WORKSPACE ├── third_party ├── BUILD ├── bzip2 │ ├── BUILD │ ├── README.md │ └── repository.bzl ├── pcpp │ ├── BUILD │ ├── pcpp.BUILD │ └── recursion_fix.patch ├── xz │ ├── BUILD │ ├── README.md │ └── repository.bzl ├── zlib │ ├── BUILD │ ├── README.md │ └── repository.bzl ├── zstd │ ├── BUILD │ ├── README.md │ └── repository.bzl ├── boost │ └── wave │ │ └── BUILD ├── rules_boost │ ├── BUILD │ └── rules_boost_step_2.bzl ├── extensions_step_2.bzl └── extensions_step_1.bzl ├── tools ├── dwyu │ ├── BUILD │ └── aspect.bzl └── clang_tidy │ └── BUILD ├── .bazelversion ├── test ├── apply_fixes │ ├── BUILD │ ├── missing_dependency │ │ ├── workspace │ │ │ ├── dummy.h │ │ │ ├── external_dep │ │ │ │ ├── WORKSPACE │ │ │ │ ├── foo.h │ │ │ │ ├── sub │ │ │ │ │ └── dir │ │ │ │ │ │ ├── bar.h │ │ │ │ │ │ └── BUILD │ │ │ │ ├── BUILD │ │ │ │ └── MODULE.bazel │ │ │ ├── private_header │ │ │ │ ├── bar.h │ │ │ │ ├── private_bar.h │ │ │ │ ├── bar.cpp │ │ │ │ └── BUILD │ │ │ ├── libs │ │ │ │ ├── sub │ │ │ │ │ └── bar.h │ │ │ │ └── foo.h │ │ │ ├── root_lib.h │ │ │ ├── other_lib │ │ │ │ ├── foo.h │ │ │ │ └── BUILD │ │ │ ├── ambiguous_lib │ │ │ │ ├── lib.h │ │ │ │ └── BUILD │ │ │ ├── use_manipulated_bar.h │ │ │ ├── use_ambiguous_lib.cpp │ │ │ ├── use_generated_code.cpp │ │ │ ├── use_private_header.cpp │ │ │ ├── use_external_dep.cpp │ │ │ ├── configured_lib │ │ │ │ ├── configured_deps.h │ │ │ │ └── BUILD │ │ │ ├── mixed_libs_usage.h │ │ │ ├── use_libs.cpp │ │ │ ├── use_configured_lib.h │ │ │ ├── aspect.bzl │ │ │ ├── mixed_libs_usage.cpp │ │ │ └── generate_code │ │ │ │ └── BUILD │ │ ├── test_find_generated_code.py │ │ ├── test_suggest_missing_dep_for_binary.py │ │ ├── test_suggest_missing_dep_from_hdrs_and_srcs.py │ │ └── test_suggest_missing_dep_based_on_fallback_logic_using_header_file_name.py │ ├── tool_cli │ │ ├── workspace │ │ │ ├── sub │ │ │ │ └── foo │ │ │ │ │ ├── foo.h │ │ │ │ │ └── BUILD │ │ │ ├── binary.cpp │ │ │ ├── lib.h │ │ │ ├── aspect.bzl │ │ │ └── BUILD │ │ ├── README.md │ │ ├── test_dry_run_performs_no_change.py │ │ └── test_utilize_bazel_info.py │ ├── unused_dependency │ │ ├── workspace │ │ │ ├── lib_a.h │ │ │ ├── lib_b.h │ │ │ ├── lib_c.h │ │ │ ├── using_a.cpp │ │ │ ├── aspect.bzl │ │ │ └── BUILD │ │ ├── test_remove_unused_public_dep.py │ │ └── test_remove_unused_private_dep.py │ ├── needlessly_public_dependency │ │ └── workspace │ │ │ ├── lib_a.h │ │ │ ├── lib_b.h │ │ │ ├── lib_c.h │ │ │ ├── using_c.h │ │ │ ├── using_a_and_b.cpp │ │ │ ├── aspect.bzl │ │ │ └── BUILD │ └── README.md ├── benchmark │ ├── BUILD │ ├── .bazelversion │ ├── aspect.bzl │ ├── .bazelrc │ └── MODULE.bazel ├── aspect │ ├── skip_tags │ │ ├── bar.h │ │ ├── foo.h │ │ ├── aspect.bzl │ │ ├── test_skip_no_dwyu_tag.py │ │ ├── test_skip_custom_tag.py │ │ └── BUILD │ ├── platforms │ │ ├── linux.cpp │ │ ├── windows.cpp │ │ ├── main.cpp │ │ ├── test_ignore_incompatible_platforms.py │ │ └── BUILD │ ├── valid │ │ ├── foo │ │ │ ├── textual.cc │ │ │ ├── b.h │ │ │ └── a.h │ │ ├── bar │ │ │ ├── bar.h │ │ │ ├── private_a.h │ │ │ ├── sub │ │ │ │ └── dir │ │ │ │ │ └── private_b.h │ │ │ └── bar.cc │ │ ├── BUILD │ │ └── test_common_valid_case.py │ ├── command_length_limit │ │ ├── foo.h │ │ ├── make_large_arg.bzl │ │ ├── test_command_length_limit.py │ │ └── BUILD │ ├── no_preprocessor │ │ ├── lib_a.h │ │ ├── lib_b.h │ │ ├── use_libs.h │ │ ├── aspect.bzl │ │ ├── BUILD │ │ └── test_no_preprocessor.py │ ├── set_cpp_standard │ │ ├── lib.h │ │ ├── cpp_lib.cpp │ │ ├── cpp_lib.h │ │ ├── use_specific_cpp_standard.h │ │ ├── aspect.bzl │ │ ├── BUILD │ │ └── test_set_cplusplus.py │ ├── external_repo │ │ ├── repo │ │ │ ├── WORKSPACE │ │ │ ├── foo.h │ │ │ ├── some │ │ │ │ └── dir │ │ │ │ │ └── bar.h │ │ │ ├── BUILD │ │ │ └── MODULE.bazel │ │ ├── repo.bzl │ │ ├── use_external_libs.h │ │ ├── BUILD │ │ └── test_external_dependencies.py │ ├── skip_external_targets │ │ ├── BUILD │ │ ├── external_dep │ │ │ ├── WORKSPACE │ │ │ ├── lib │ │ │ │ ├── b.h │ │ │ │ └── a.h │ │ │ ├── broken_dep.h │ │ │ ├── BUILD │ │ │ └── MODULE.bazel │ │ ├── external_dep.bzl │ │ ├── aspect.bzl │ │ └── test_skip_broken_target.py │ ├── .bazelversion │ ├── complex_includes │ │ ├── ext_repo │ │ │ ├── WORKSPACE │ │ │ ├── some │ │ │ │ └── dir │ │ │ │ │ ├── complex_include_a.h │ │ │ │ │ └── complex_include_b.h │ │ │ ├── use_complex_includes.cpp │ │ │ ├── complex_includes.cpp │ │ │ ├── MODULE.bazel │ │ │ └── BUILD │ │ ├── some │ │ │ └── dir │ │ │ │ ├── complex_include_a.h │ │ │ │ └── complex_include_b.h │ │ ├── use_complex_includes.cpp │ │ ├── ext_repo.bzl │ │ ├── complex_includes.cpp │ │ └── BUILD │ ├── multiple_deps_for_one_header │ │ ├── bar.h │ │ ├── foo.h │ │ ├── BUILD │ │ └── test_multiple_deps_for_one_header.py │ ├── preprocessing │ │ ├── support │ │ │ ├── transitive.h │ │ │ ├── lib_a.h │ │ │ ├── lib_b.h │ │ │ ├── lib_c.h │ │ │ ├── lib_d.h │ │ │ └── lib_e.h │ │ ├── macros.h │ │ ├── use_complex_libraries.cpp │ │ ├── README.md │ │ ├── select_includes_via_external_macros.cpp │ │ └── test_preprocessing.py │ ├── shared_library │ │ ├── foo.h │ │ ├── foo.cc │ │ ├── README.md │ │ ├── BUILD │ │ └── test_shared_library_without_srcs.py │ ├── target_mapping │ │ ├── libs │ │ │ ├── non_cc_thing.sh │ │ │ ├── c.h │ │ │ ├── a.h │ │ │ └── b.h │ │ ├── use_lib_b.cpp │ │ ├── use_lib_c.cpp │ │ ├── BUILD │ │ ├── test_use_b_with_direct_deps_mapping.py │ │ ├── test_use_b_with_specific_mapping.py │ │ ├── test_use_b_with_transitive_deps_mapping.py │ │ ├── test_use_c_with_transitive_deps_mapping.py │ │ ├── test_use_b_via_impl_deps_with_specific_mapping.py │ │ ├── mapping │ │ │ └── BUILD │ │ ├── test_use_c_with_direct_deps_mapping.py │ │ └── test_use_c_with_specific_mapping.py │ ├── defines │ │ ├── support │ │ │ ├── a.h │ │ │ ├── b.h │ │ │ ├── c.h │ │ │ ├── some_defines.h │ │ │ ├── conditional_defines.h │ │ │ └── BUILD │ │ ├── use_command_line_defines.h │ │ ├── defines_from_bazel_target.h │ │ ├── in_file_defines.h │ │ ├── use_defines_from_dependency_header.h │ │ ├── test_processing_defines.py │ │ ├── include_using_pre_processor_token.h │ │ └── transitive_defines_from_bazel_target.h │ ├── ignore_includes │ │ ├── support │ │ │ ├── some_header.h │ │ │ ├── do_match_include_end.h │ │ │ ├── some_other_header.h │ │ │ ├── ignored_sub_path_1 │ │ │ │ └── some_header.h │ │ │ ├── ignored_sub_path_2 │ │ │ │ └── some_header.h │ │ │ ├── a_substring_match_does_not_work_here.h │ │ │ ├── matching_begin_without_regex_works_example.h │ │ │ └── BUILD │ │ ├── use_not_ignored_header.h │ │ ├── use_ignored_header_and_std_lib.h │ │ ├── use_multiple_ignored_headers.h │ │ ├── extra_ignore_include_paths.json │ │ ├── ignore_include_paths.json │ │ ├── use_ignored_patterns.h │ │ ├── ignore_include_patterns.json │ │ ├── test_ignore_include_patterns.py │ │ ├── test_custom_ignore_include_paths.py │ │ └── test_extra_ignore_include_paths.py │ ├── implementation_deps │ │ ├── external_repo │ │ │ ├── WORKSPACE │ │ │ ├── ext_lib.h │ │ │ ├── ext │ │ │ │ └── dir │ │ │ │ │ ├── ext_lib_with_includes.h │ │ │ │ │ ├── ext_lib_with_add_prefix.h │ │ │ │ │ └── ext_lib_with_strip_prefix.h │ │ │ ├── MODULE.bazel │ │ │ └── BUILD │ │ ├── support │ │ │ ├── transitive.h │ │ │ ├── lib_a.h │ │ │ ├── lib_b.h │ │ │ ├── lib_with_defines.h │ │ │ └── sub │ │ │ │ └── dir │ │ │ │ ├── lib_with_includes.h │ │ │ │ ├── lib_with_add_prefix.h │ │ │ │ └── lib_with_strip_prefix.h │ │ ├── use_defines.h │ │ ├── binary_using_foo.cpp │ │ ├── use_external.h │ │ ├── use_libs.cpp │ │ ├── use_complex_includes.h │ │ ├── use_libs.h │ │ ├── use_complex_includes.cpp │ │ ├── use_external.cpp │ │ ├── use_defines.cpp │ │ └── test_superfluous_public_dep.py │ ├── recursion │ │ ├── d.h │ │ ├── e.h │ │ ├── f.h │ │ ├── a.h │ │ ├── b.h │ │ ├── c.h │ │ ├── use_impl_deps.cpp │ │ ├── main.cpp │ │ ├── aspect.bzl │ │ ├── test_find_transitive_problem_via_deps.py │ │ └── test_find_transitive_problem_via_iml_deps.py │ ├── alias │ │ ├── no_dependencies.cpp │ │ ├── a.h │ │ ├── README.md │ │ ├── use_a_and_b.cpp │ │ ├── b.h │ │ ├── test_use_dependency_through_alias.py │ │ ├── test_unused_dependency_through_alias.py │ │ └── test_invalid_dependency_through_alias.py │ ├── tree_artifact │ │ ├── some_lib.h │ │ ├── use_tree_artifact.cpp │ │ ├── test_use_tree_artifact_correctly.py │ │ └── README.md │ ├── rule_using_aspect │ │ ├── b.h │ │ ├── c.h │ │ ├── a.h │ │ ├── main.cpp │ │ ├── use_impl_deps.cpp │ │ ├── aspect.bzl │ │ ├── test_dwyu_rule.py │ │ ├── test_recursive_dwyu_rule.py │ │ └── test_recursive_dwyu_rule_with_impl_deps.py │ ├── generated_code │ │ ├── foo.cpp │ │ ├── BUILD │ │ └── test_generated_code.py │ ├── unused_dep │ │ ├── main.cpp │ │ ├── bar.h │ │ ├── foo.h │ │ ├── test_detect_unused_dep.py │ │ ├── BUILD │ │ └── test_detect_unused_impl_dep.py │ ├── virtual_includes │ │ ├── prefixed.h │ │ ├── stripped.cpp │ │ ├── prefixed.cpp │ │ ├── use_stripped.cpp │ │ ├── some │ │ │ └── sub │ │ │ │ └── dir │ │ │ │ └── stripped.h │ │ ├── use_prefixed.cpp │ │ ├── test_correctly_process_virtual_includes.py │ │ └── BUILD │ ├── includes │ │ ├── some │ │ │ └── sub │ │ │ │ └── dir │ │ │ │ └── includes.h │ │ ├── includes.cpp │ │ ├── use_includes.cpp │ │ ├── BUILD │ │ └── test_system_includes.py │ ├── using_transitive_dep │ │ ├── foo.h │ │ ├── bar.h │ │ ├── main.cpp │ │ ├── transitive_usage_through_impl_deps.h │ │ ├── BUILD │ │ └── test_detect_using_transitive_dep.py │ ├── relative_includes │ │ ├── normal_include.h │ │ ├── other │ │ │ └── other.h │ │ ├── system_include.h │ │ ├── virtual_prefix.h │ │ ├── some │ │ │ ├── sub │ │ │ │ ├── dir │ │ │ │ │ ├── bar.h │ │ │ │ │ └── foo.h │ │ │ │ └── dir2 │ │ │ │ │ └── baz.h │ │ │ └── virtual_strip.h │ │ ├── use_normal_include.cpp │ │ ├── README.md │ │ ├── system_include.cpp │ │ ├── normal_include.cpp │ │ ├── virtual_strip.cpp │ │ ├── virtual_prefix.cpp │ │ ├── use_system_include.cpp │ │ ├── use_virtual_strip.cpp │ │ ├── use_virtual_prefix.cpp │ │ └── test_relative_includes.py │ ├── ignore_toolchain_headers │ │ ├── custom_ignored_headers.json │ │ ├── use_custom_toolchain_header.h │ │ ├── use_toolchain_header.h │ │ ├── BUILD │ │ ├── custom_ignored_headers.bzl │ │ ├── test_custom_toolchain_headers_info.py │ │ └── aspect.bzl │ ├── aspect.bzl │ ├── .bazelrc │ ├── REAME.md │ ├── version.py │ └── BUILD ├── workspace_integration │ ├── WORKSPACE.bzlmod │ ├── valid_target.h │ ├── .bazelversion │ ├── BUILD │ ├── aspect.bzl │ ├── README.md │ ├── .bazelrc │ └── WORKSPACE ├── cc_toolchains │ ├── mocked │ │ ├── .bazelignore │ │ ├── .bazelversion │ │ ├── toolchains │ │ │ ├── classic │ │ │ │ ├── data │ │ │ │ │ ├── fizz │ │ │ │ │ │ ├── buzz │ │ │ │ │ │ │ └── buzz.h │ │ │ │ │ │ └── fizz │ │ │ │ │ └── foobar │ │ │ │ │ │ └── foobar.h │ │ │ │ ├── MODULE.bazel │ │ │ │ └── tools │ │ │ │ │ └── fake_gcc │ │ │ └── rule_based │ │ │ │ ├── data │ │ │ │ ├── foobar │ │ │ │ │ └── foobar.h │ │ │ │ ├── fizz │ │ │ │ │ ├── buzz │ │ │ │ │ │ └── buzz.h │ │ │ │ │ └── fizz │ │ │ │ └── BUILD │ │ │ │ ├── MODULE.bazel │ │ │ │ ├── tools │ │ │ │ └── BUILD │ │ │ │ └── gcc │ │ ├── README.md │ │ ├── tools │ │ │ └── BUILD │ │ ├── .bazelrc │ │ └── BUILD │ └── upstream │ │ ├── aspect.bzl.tpl │ │ ├── BUILD.tpl │ │ ├── aspect_cpp.bzl.tpl │ │ ├── use_toolchain_headers.h.tpl │ │ ├── README.md │ │ └── bazelrc.tpl ├── README.md ├── __init__.py └── support │ ├── BUILD │ ├── platform.py │ └── result.py ├── .mdformat.toml ├── scripts ├── build_examples.sh ├── test_aspect_tests_scripts.sh ├── test_mocked_cc_toolchains.sh ├── BUILD ├── test │ ├── BUILD │ └── extract_std_headers_test.py └── release.md ├── .gitattributes ├── BUILD ├── WORKSPACE ├── ty.toml ├── .buildifier.json ├── .gitignore ├── .clang-format ├── docs └── BUILD ├── setup_step_1.bzl ├── defs.bzl └── setup_step_2.bzl /dwyu/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/dwyu/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bazelversion: -------------------------------------------------------------------------------- 1 | 8.4.2 2 | -------------------------------------------------------------------------------- /test/apply_fixes/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/benchmark/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/bzip2/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/pcpp/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/xz/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/zlib/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/zstd/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/clang_tidy/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/WORKSPACE.bzlmod: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/define_macros/lib.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/bar.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/foo.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/boost/wave/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/skipping_targets/lib_a.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/platforms/linux.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/platforms/windows.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/valid/foo/textual.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/rules_boost/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/.bazelversion: -------------------------------------------------------------------------------- 1 | ../.bazelversion -------------------------------------------------------------------------------- /test/aspect/command_length_limit/foo.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/lib_a.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/lib_b.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/lib.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/define_macros/transitive_dep_a.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/define_macros/transitive_dep_b.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/support/external_targets/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/support/external_targets/foo.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/BUILD: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/workspace_integration/WORKSPACE.bzlmod: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/workspace_integration/valid_target.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/.bazelversion: -------------------------------------------------------------------------------- 1 | ../../.bazelversion -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/multiple_deps_for_one_header/bar.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/transitive.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/shared_library/foo.h: -------------------------------------------------------------------------------- 1 | int foo(); 2 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/libs/non_cc_thing.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/benchmark/.bazelversion: -------------------------------------------------------------------------------- 1 | ../../.bazelversion -------------------------------------------------------------------------------- /examples/support/external_targets/has_unused_dep.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/dummy.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/sub/foo/foo.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/lib_a.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/lib_b.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/lib_c.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/defines/support/a.h: -------------------------------------------------------------------------------- 1 | // some content 2 | -------------------------------------------------------------------------------- /test/aspect/defines/support/b.h: -------------------------------------------------------------------------------- 1 | // some content 2 | -------------------------------------------------------------------------------- /test/aspect/defines/support/c.h: -------------------------------------------------------------------------------- 1 | // some content 2 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/some_header.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/do_match_include_end.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/some_other_header.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/.bazelignore: -------------------------------------------------------------------------------- 1 | toolchains/ 2 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/empty_header.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/aspect/private/cc_toolchain_headers_info_stub.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/lib_a.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/lib_b.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/lib_c.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/.bazelversion: -------------------------------------------------------------------------------- 1 | ../../../.bazelversion -------------------------------------------------------------------------------- /test/workspace_integration/.bazelversion: -------------------------------------------------------------------------------- 1 | ../../.bazelversion -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/bar/bar.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/relevant.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/outside_search_path.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/WORKSPACE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/ignored_sub_path_1/some_header.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/ignored_sub_path_2/some_header.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/classic/data/fizz/buzz/buzz.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/classic/data/foobar/foobar.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/data/foobar/foobar.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/config/empty.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/foo/header.hpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/target_mapping/libs/c.h: -------------------------------------------------------------------------------- 1 | int doC() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/platforms/main.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/recursion/d.h: -------------------------------------------------------------------------------- 1 | #ifndef D_H 2 | #define D_H 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /test/aspect/recursion/e.h: -------------------------------------------------------------------------------- 1 | #ifndef E_H 2 | #define E_H 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /test/aspect/recursion/f.h: -------------------------------------------------------------------------------- 1 | #ifndef F_H 2 | #define F_H 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/data/fizz/buzz/buzz.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.mdformat.toml: -------------------------------------------------------------------------------- 1 | wrap = "keep" 2 | number = false 3 | end_of_line = "lf" 4 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/.hidden_is_ignored: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/relevant_no_extension: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/wrong_extension.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/rule_using_dwyu/bad_target.h: -------------------------------------------------------------------------------- 1 | #include "not/existing/header.h" 2 | -------------------------------------------------------------------------------- /examples/skipping_targets/lib_b.h: -------------------------------------------------------------------------------- 1 | int doB() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/alias/no_dependencies.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/a_substring_match_does_not_work_here.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/libs/c.h: -------------------------------------------------------------------------------- 1 | int doC() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/private_header/bar.h: -------------------------------------------------------------------------------- 1 | int doBar(); 2 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/matching_begin_without_regex_works_example.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/transitive.h: -------------------------------------------------------------------------------- 1 | // Content is irrelevant 2 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/another_header.h: -------------------------------------------------------------------------------- 1 | #include "foo/bar.h" 2 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/binary.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/tree_artifact/some_lib.h: -------------------------------------------------------------------------------- 1 | int doSomething() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /examples/skipping_targets/use_broken_external_dependency.h: -------------------------------------------------------------------------------- 1 | #include "has_unused_dep.h" 2 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/lib.h: -------------------------------------------------------------------------------- 1 | int doSomething() { 2 | returen 42; 3 | } 4 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/data/include_root/foo/no_extension_in_sub_dir_is_ignored: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/basic_usage/my_type.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct MyType { 4 | int foo; 5 | }; 6 | -------------------------------------------------------------------------------- /examples/basic_usage/use_lib.h: -------------------------------------------------------------------------------- 1 | #include "basic_usage/my_type.h" 2 | 3 | MyType doSomething(); 4 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the integration tests for the various DWYU features. 2 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/ext_lib.h: -------------------------------------------------------------------------------- 1 | int extLib() { 2 | return 1; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/multiple_deps_for_one_header/foo.h: -------------------------------------------------------------------------------- 1 | #include "multiple_deps_for_one_header/bar.h" 2 | -------------------------------------------------------------------------------- /dwyu/private/test/data/multiple_options.txt: -------------------------------------------------------------------------------- 1 | --list 2 | tik 3 | tok 4 | --value 5 | foo 6 | --flag 7 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/libs/sub/bar.h: -------------------------------------------------------------------------------- 1 | int doBar { 2 | return 1; 3 | }; 4 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/root_lib.h: -------------------------------------------------------------------------------- 1 | int doRoot() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/defines/support/some_defines.h: -------------------------------------------------------------------------------- 1 | #define SWITCH_USE_B 2 | #define SOME_SWITCH_VALUE 1337 3 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/lib/b.h: -------------------------------------------------------------------------------- 1 | int doLibB() { 2 | return 1337; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/recursion/a.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H 2 | #define A_H 3 | 4 | #include "recursion/c.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/recursion/b.h: -------------------------------------------------------------------------------- 1 | #ifndef B_H 2 | #define B_H 3 | 4 | #include "recursion/c.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/recursion/c.h: -------------------------------------------------------------------------------- 1 | #ifndef C_H 2 | #define C_H 3 | 4 | #include "recursion/d.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/b.h: -------------------------------------------------------------------------------- 1 | #ifndef B_H 2 | #define B_H 3 | 4 | // Do nothing 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/c.h: -------------------------------------------------------------------------------- 1 | #ifndef C_H 2 | #define C_H 3 | 4 | // Do nothing 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/some_defines.h: -------------------------------------------------------------------------------- 1 | #define MY_DEFINE 2 | #define THE_ANSWER 42 3 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/empty.cpp: -------------------------------------------------------------------------------- 1 | // Empty file as dummy input for a minimal compilation action 2 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/foo.h: -------------------------------------------------------------------------------- 1 | int doFoo() { 2 | return 1337; 3 | } 4 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/other_lib/foo.h: -------------------------------------------------------------------------------- 1 | int doOtherFoo() { 2 | return 1234; 3 | } 4 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | DisableFormat: true 3 | SortIncludes: Never 4 | -------------------------------------------------------------------------------- /examples/recursion/lib.h: -------------------------------------------------------------------------------- 1 | #include "not/existing/header.h" 2 | 3 | int doSomething() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/ambiguous_lib/lib.h: -------------------------------------------------------------------------------- 1 | int doSomething() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/sub/dir/bar.h: -------------------------------------------------------------------------------- 1 | int doBar() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/aspect/alias/a.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H 2 | #define A_H 3 | 4 | int doA() { 5 | return 1; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/generated_code/foo.cpp: -------------------------------------------------------------------------------- 1 | #include "generated_code/bar.h" 2 | 3 | int main() { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/use_not_ignored_header.h: -------------------------------------------------------------------------------- 1 | #include "support/a_substring_match_does_not_work_here.h" 2 | -------------------------------------------------------------------------------- /test/aspect/recursion/use_impl_deps.cpp: -------------------------------------------------------------------------------- 1 | #include "recursion/a.h" 2 | 3 | int doSth() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/shared_library/foo.cc: -------------------------------------------------------------------------------- 1 | #include "shared_library/foo.h" 2 | 3 | int foo() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/main.cpp: -------------------------------------------------------------------------------- 1 | #include "unused_dep/bar.h" 2 | 3 | int main() { 4 | return doStuff(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/valid/foo/b.h: -------------------------------------------------------------------------------- 1 | #ifndef B_H 2 | #define B_H 3 | 4 | int doB() { 5 | return 1; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/classic/data/fizz/fizz: -------------------------------------------------------------------------------- 1 | simulate a header file without extension like vector 2 | -------------------------------------------------------------------------------- /examples/recursion/use_lib.h: -------------------------------------------------------------------------------- 1 | #include "recursion/lib.h" 2 | 3 | int useLibrary() { 4 | return doSomething(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/use_ignored_header_and_std_lib.h: -------------------------------------------------------------------------------- 1 | #include "support/some_header.h" 2 | #include 3 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/a.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H 2 | #define A_H 3 | 4 | #include "rule_using_aspect/b.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/main.cpp: -------------------------------------------------------------------------------- 1 | #include "rule_using_aspect/a.h" 2 | 3 | int main() { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/valid/foo/a.h: -------------------------------------------------------------------------------- 1 | #ifndef A_H 2 | #define A_H 3 | 4 | int doA() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/data/fizz/fizz: -------------------------------------------------------------------------------- 1 | simulate a header file without extension like vector 2 | -------------------------------------------------------------------------------- /examples/target_mapping/libs/a.h: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/b.h" 2 | 3 | int doA() { 4 | return 42 + doB(); 5 | } 6 | -------------------------------------------------------------------------------- /examples/target_mapping/libs/b.h: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/c.h" 2 | 3 | int doB() { 4 | return 42 + doC(); 5 | } 6 | -------------------------------------------------------------------------------- /examples/target_mapping/use_lib_b.cpp: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/b.h" 2 | 3 | int main() { 4 | return doB(); 5 | } 6 | -------------------------------------------------------------------------------- /examples/target_mapping/use_lib_c.cpp: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/c.h" 2 | 3 | int main() { 4 | return doC(); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/build_examples.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | cd examples 6 | bazel build //... 7 | cd - 8 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/private_header/private_bar.h: -------------------------------------------------------------------------------- 1 | int doPrivateStuff() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/using_a.cpp: -------------------------------------------------------------------------------- 1 | #include "lib_a.h" 2 | 3 | int usingA() { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/libs/a.h: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/b.h" 2 | 3 | int doA() { 4 | return 42 + doB(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/libs/b.h: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/c.h" 2 | 3 | int doB() { 4 | return 42 + doC(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/prefixed.h: -------------------------------------------------------------------------------- 1 | #ifndef PREFIXED_H 2 | #define PREFIXED_H 3 | 4 | int doPrefixed(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/stripped.cpp: -------------------------------------------------------------------------------- 1 | #include "sub/dir/stripped.h" 2 | 3 | int doStripped() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ignore some directories for 'git archive', aka release cutting 2 | .bcr export-ignore 3 | .github export-ignore 4 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/config/system_headers_info.json: -------------------------------------------------------------------------------- 1 | [ 2 | "foo/bar.h", 3 | "some_header" 4 | ] 5 | -------------------------------------------------------------------------------- /test/aspect/alias/README.md: -------------------------------------------------------------------------------- 1 | An alias is resolved to the actual target before the aspect parses it as part of the dependency list. 2 | -------------------------------------------------------------------------------- /test/aspect/includes/some/sub/dir/includes.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDES_H 2 | #define INCLUDES_H 3 | 4 | int doIncludes(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/use_impl_deps.cpp: -------------------------------------------------------------------------------- 1 | #include "rule_using_aspect/a.h" 2 | 3 | int doSth() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/use_lib_b.cpp: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/b.h" 2 | 3 | int main() { 4 | return doB(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/use_lib_c.cpp: -------------------------------------------------------------------------------- 1 | #include "target_mapping/libs/c.h" 2 | 3 | int main() { 4 | return doC(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | 4 | int doStuff() { 5 | return 1; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef FOO_H 2 | #define FOO_H 3 | 4 | int theAnswer() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /dwyu/aspect/test/BUILD: -------------------------------------------------------------------------------- 1 | load(":dwyu_test.bzl", "dwyu_aspect_test_suite") 2 | 3 | dwyu_aspect_test_suite(name = "dwyu_aspect_tests") 4 | -------------------------------------------------------------------------------- /examples/basic_usage/not_using_lib.h: -------------------------------------------------------------------------------- 1 | #include "basic_usage/my_type.h" 2 | 3 | MyType doSomething() { 4 | return MyType{42}; 5 | } 6 | -------------------------------------------------------------------------------- /examples/set_cpp_standard/use_specific_cpp_standard.h: -------------------------------------------------------------------------------- 1 | #if __cplusplus != 201703 2 | 3 | #include "not/existing/dep.h" 4 | 5 | #endif 6 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef FOO_H 2 | #define FOO_H 3 | 4 | int doFoo() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/use_multiple_ignored_headers.h: -------------------------------------------------------------------------------- 1 | #include "support/some_header.h" 2 | #include "support/some_other_header.h" 3 | -------------------------------------------------------------------------------- /test/aspect/recursion/main.cpp: -------------------------------------------------------------------------------- 1 | #include "recursion/a.h" 2 | #include "recursion/b.h" 3 | 4 | int main() { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/valid/bar/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | 4 | #include "valid/foo/a.h" 5 | 6 | int doBar(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/prefixed.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/prefixed.h" 2 | 3 | int doPrefixed() { 4 | return 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/use_stripped.cpp: -------------------------------------------------------------------------------- 1 | #include "sub/dir/stripped.h" 2 | 3 | int main() { 4 | return doStripped(); 5 | } 6 | -------------------------------------------------------------------------------- /examples/set_cpp_standard/cpp_lib.cpp: -------------------------------------------------------------------------------- 1 | #include "set_cpp_standard/cpp_lib.h" 2 | 3 | void someFunction() { 4 | // Do something 5 | } 6 | -------------------------------------------------------------------------------- /examples/skipping_targets/use_transitive_dep.h: -------------------------------------------------------------------------------- 1 | #include "skipping_targets/lib_b" 2 | 3 | int doSomething() { 4 | return doB(); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/test_aspect_tests_scripts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | cd test/aspect 6 | bazel test //:all 7 | cd - 8 | -------------------------------------------------------------------------------- /test/aspect/alias/use_a_and_b.cpp: -------------------------------------------------------------------------------- 1 | #include "alias/a.h" 2 | #include "alias/b.h" 3 | 4 | int main() { 5 | return doA() + doB(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_DEFINES_H 2 | #define USE_DEFINES_H 3 | 4 | int useDefines(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/use_libs.h: -------------------------------------------------------------------------------- 1 | #define FOO 2 | 3 | #ifdef FOO 4 | #include "lib_a.h" 5 | #else 6 | #include "lib_b.h" 7 | #endif 8 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/cpp_lib.cpp: -------------------------------------------------------------------------------- 1 | #include "set_cpp_standard/cpp_lib.h" 2 | 3 | void someFunction() { 4 | // Do something 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/lib/a.h: -------------------------------------------------------------------------------- 1 | #include "lib/lib_b.h" 2 | 3 | int doLibA() { 4 | return doLibB() + 42; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef FOO_H 2 | #define FOO_H 3 | 4 | int theAnswer() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/some/sub/dir/stripped.h: -------------------------------------------------------------------------------- 1 | #ifndef STRIPPED_H 2 | #define STRIPPED_H 3 | 4 | int doStripped(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/use_prefixed.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/prefixed.h" 2 | 3 | int main() { 4 | return doPrefixed(); 5 | } 6 | -------------------------------------------------------------------------------- /examples/set_cpp_standard/cpp_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __cplusplus 2 | 3 | #include "not/existing/dep.h" 4 | 5 | #endif 6 | 7 | void someFunction(); 8 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | # Mark test dir as importable package. 2 | # This overwrites the standard lib test package, which is fine as we don't need it. 3 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/using_c.h: -------------------------------------------------------------------------------- 1 | #include "lib_c.h" 2 | 3 | int doSomethingPublic() { 4 | return 13; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo/some/dir/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | 4 | int doBar() { 5 | return 13; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/include_based_on_pre_processor_token.h: -------------------------------------------------------------------------------- 1 | #define MY_HEADER "some/header.h" 2 | 3 | #include MY_HEADER 4 | -------------------------------------------------------------------------------- /examples/basic_usage/lib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "basic_usage/my_type.h" 4 | 5 | MyType makeMyType() { 6 | return MyType{42}; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/test_mocked_cc_toolchains.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | cd test/cc_toolchains/mocked 6 | bazel test //:all 7 | cd - 8 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/normal_include.h: -------------------------------------------------------------------------------- 1 | #ifndef NORMAL_INCLUDE_H 2 | #define NORMAL_INCLUDE_H 3 | 4 | int useNormalInclude(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/other/other.h: -------------------------------------------------------------------------------- 1 | #ifndef OTHER_H 2 | #define OTHER_H 3 | 4 | int doOther() { 5 | return 123; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/system_include.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_INCLUDE_H 2 | #define SYSTEM_INCLUDE_H 3 | 4 | int useSystemInclude(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/virtual_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef VIRTUAL_PREFIX_H 2 | #define VIRTUAL_PREFIX_H 3 | 4 | int useVirtualPrefix(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/valid/bar/private_a.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_A_H 2 | #define PRIVATE_A_H 3 | 4 | int doPrivateA() { 5 | return 13; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_manipulated_bar.h: -------------------------------------------------------------------------------- 1 | #include "new/path/sub/bar.h" 2 | 3 | int useBar() { 4 | return doBar(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/extra_ignore_include_paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra_ignore_include_paths": [ 3 | "support/some_header.h" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/binary_using_foo.cpp: -------------------------------------------------------------------------------- 1 | #include "implementation_deps/support/lib_a.h" 2 | 3 | int main() { 4 | return libA(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_external.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_EXTERNAL_H 2 | #define USE_EXTERNAL_H 3 | 4 | int doSomethingWithExternal(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_libs.cpp: -------------------------------------------------------------------------------- 1 | #include "implementation_deps/support/lib_b.h" 2 | 3 | int useLibs() { 4 | return libB() + 11; 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/some/sub/dir/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | 4 | inline int doBar() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/some/sub/dir2/baz.h: -------------------------------------------------------------------------------- 1 | #ifndef BAZ_H 2 | #define BAZ_H 3 | 4 | inline int doBaz() { 5 | return 1; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/some/virtual_strip.h: -------------------------------------------------------------------------------- 1 | #ifndef VIRTUAL_STRIP_H 2 | #define VIRTUAL_STRIP_H 3 | 4 | int useVirtualStrip(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/valid/bar/sub/dir/private_b.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_B_H 2 | #define PRIVATE_B_H 3 | 4 | int doPrivateB() { 5 | return 5; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_ambiguous_lib.cpp: -------------------------------------------------------------------------------- 1 | #include "ambiguous_lib/lib.h" 2 | 3 | int main() { 4 | return doSomething(); 5 | } 6 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_generated_code.cpp: -------------------------------------------------------------------------------- 1 | #include "generate_code/foo.h" 2 | 3 | int main() { 4 | return doGenerated(); 5 | } 6 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_private_header.cpp: -------------------------------------------------------------------------------- 1 | #include "bar/private_bar.h" 2 | 3 | int main() { 4 | return doPrivateStuff(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/tree_artifact/use_tree_artifact.cpp: -------------------------------------------------------------------------------- 1 | #include "tree_artifact/public_hdrs.h/tree_lib.h" 2 | 3 | int main() { 4 | return doTreeThings(); 5 | } 6 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | default_aspect = dwyu_aspect_factory() 4 | -------------------------------------------------------------------------------- /test/aspect/alias/b.h: -------------------------------------------------------------------------------- 1 | #ifndef B_H 2 | #define B_H 3 | 4 | #include "alias/a.h" 5 | 6 | int doB() { 7 | return doA() + 11; 8 | } 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/lib_a.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_A_H 2 | #define SUPPORT_LIB_A_H 3 | 4 | int libA() { 5 | return 42; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/lib_b.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_B_H 2 | #define SUPPORT_LIB_B_H 3 | 4 | int libB() { 5 | return 13; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /tools/dwyu/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu = dwyu_aspect_factory(use_cpp_implementation = True, use_implementation_deps = True) 4 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/config/ignore_patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_include_patterns": [ 3 | "foo", 4 | "bar" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /examples/basic_usage/use_lib.cpp: -------------------------------------------------------------------------------- 1 | #include "basic_usage/use_lib.h" 2 | #include "basic_usage/lib.h" 3 | 4 | MyType doSomething() { 5 | return makeMyType(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/some/dir/complex_include_a.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_INCLUDE_A_H 2 | #define COMPLEX_INCLUDE_A_H 3 | 4 | int doComplexIncludeA(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/some/dir/complex_include_b.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_INCLUDE_B_H 2 | #define COMPLEX_INCLUDE_B_H 3 | 4 | int doComplexIncludeB(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/custom_ignored_headers.json: -------------------------------------------------------------------------------- 1 | [ 2 | "toolchain/header_a.h", 3 | "toolchain/header_b.hh", 4 | "toolchain_header_c" 5 | ] 6 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/use_custom_toolchain_header.h: -------------------------------------------------------------------------------- 1 | #include "toolchain/header_a.h" 2 | #include "toolchain/header_b.hh" 3 | #include "toolchain_header_c" 4 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/commented_includes/mixed_style.h: -------------------------------------------------------------------------------- 1 | /* */ // #include "commented.h" 2 | /* // #include "commented.h" */ 3 | #include "active.h" 4 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/config/extra_ignore_paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra_ignore_include_paths": [ 3 | "foo", 4 | "bar" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_external_dep.cpp: -------------------------------------------------------------------------------- 1 | #include "foo.h" 2 | #include "sub/dir/bar.h" 3 | 4 | int main() { 5 | return doFoo() + doBar(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/lib_a.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_A_H 2 | #define SUPPORT_LIB_A_H 3 | 4 | int libA() { 5 | return 1; 6 | } 7 | 8 | #endif // SUPPORT_LIB_A_H 9 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/lib_b.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_B_H 2 | #define SUPPORT_LIB_B_H 3 | 4 | int libB() { 5 | return 2; 6 | } 7 | 8 | #endif // SUPPORT_LIB_B_H 9 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/lib_c.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_C_H 2 | #define SUPPORT_LIB_C_H 3 | 4 | int libC() { 5 | return 3; 6 | } 7 | 8 | #endif // SUPPORT_LIB_C_H 9 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/lib_d.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_D_H 2 | #define SUPPORT_LIB_D_H 3 | 4 | int libD() { 5 | return 4; 6 | } 7 | 8 | #endif // SUPPORT_LIB_D_H 9 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/support/lib_e.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_E_H 2 | #define SUPPORT_LIB_E_H 3 | 4 | int libE() { 5 | return 5; 6 | } 7 | 8 | #endif // SUPPORT_LIB_E_H 9 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/README.md: -------------------------------------------------------------------------------- 1 | Tests based on mocked toolchains. 2 | Mocking minimal toolchains allows us to define exactly the desired results with no side effects. 3 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | alias( 2 | name = "apply_fixes", 3 | actual = "//dwyu/apply_fixes:main", 4 | visibility = ["//visibility:public"], 5 | ) 6 | 7 | exports_files([".clang-tidy"]) 8 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | # For now we need a WORKSPACE file to mark the workspace root. 2 | # The projects has however migrated to the MODULE.bazel approach and thus the WORKSPACE file is empty. 3 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/using_a_and_b.cpp: -------------------------------------------------------------------------------- 1 | #include "lib_a.h" 2 | #include "lib_b.h" 3 | 4 | int doSomethingPrivate() { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/some/dir/complex_include_a.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_INCLUDE_A_H 2 | #define COMPLEX_INCLUDE_A_H 3 | 4 | int doComplexIncludeA(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/some/dir/complex_include_b.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_INCLUDE_B_H 2 | #define COMPLEX_INCLUDE_B_H 3 | 4 | int doComplexIncludeB(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/workspace_integration/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "valid_target", 5 | hdrs = ["valid_target.h"], 6 | ) 7 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/configured_lib/configured_deps.h: -------------------------------------------------------------------------------- 1 | #include "ambiguous_lib/lib.h" 2 | 3 | int doSomethingConfigured() { 4 | return doSomething(); 5 | } 6 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_complex_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_COMPLEX_INCLUDES_H 2 | #define USE_COMPLEX_INCLUDES_H 3 | 4 | int doSomethingWithComplexIncludes(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/broken_dep.h: -------------------------------------------------------------------------------- 1 | #include "lib/a.h" 2 | #include "lib/b.h" 3 | 4 | int useLibWithoutDirectDep() { 5 | return doLibA() + doLibB(); 6 | } 7 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/aspect.bzl.tpl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu = dwyu_aspect_factory(ignore_cc_toolchain_headers = True) 4 | -------------------------------------------------------------------------------- /test/aspect/shared_library/README.md: -------------------------------------------------------------------------------- 1 | There are cases where targets have no sources due to only wrapping other targets. 2 | DWYU shall be able to gracefully handle those by skipping them. 3 | -------------------------------------------------------------------------------- /examples/ignoring_includes/ignore_includes.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra_ignore_include_paths": [ 3 | "some/header.h" 4 | ], 5 | "ignore_include_patterns": [ 6 | "some_pkg/.*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/private_header/bar.cpp: -------------------------------------------------------------------------------- 1 | #include "bar/bar.h" 2 | #include "bar/private_bar.h" 3 | 4 | int doBar() { 5 | return 1337 + doPrivateStuff(); 6 | } 7 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/README.md: -------------------------------------------------------------------------------- 1 | These test cases are not directly related to analyzing C++ targets, but rather focus on the various options available to 2 | control the automatic fixes tool. 3 | -------------------------------------------------------------------------------- /test/aspect/includes/includes.cpp: -------------------------------------------------------------------------------- 1 | // Header is available via multiple paths 2 | #include 3 | #include 4 | 5 | int doIncludes() { 6 | return 42; 7 | } 8 | -------------------------------------------------------------------------------- /ty.toml: -------------------------------------------------------------------------------- 1 | [environment] 2 | extra-paths = ["./test/aspect"] 3 | 4 | [rules] 5 | # Does not work with how the dynamically load modules for integration testing 6 | unresolved-attribute = "ignore" 7 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/dep_info_bar.json: -------------------------------------------------------------------------------- 1 | { 2 | "header_files": [ 3 | "public/dep/bar_1.h", 4 | "public/dep/bar_2.h" 5 | ], 6 | "target": "//public/dep:bar" 7 | } 8 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/dep_info_foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "header_files": [ 3 | "public/dep/foo_1.h", 4 | "public/dep/foo_2.h" 5 | ], 6 | "target": "//public/dep:foo" 7 | } 8 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/mixed_libs_usage.h: -------------------------------------------------------------------------------- 1 | // used solely publicly 2 | #include "root_lib.h" 3 | // used publicly and privately 4 | #include "libs/foo.h" 5 | 6 | int doMixed(); 7 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/BUILD.tpl: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "use_toolchain_headers", 5 | hdrs = ["use_toolchain_headers.h"], 6 | ) 7 | -------------------------------------------------------------------------------- /test/workspace_integration/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@custom_dwyu//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu = dwyu_aspect_factory() 4 | dwyu_cpp = dwyu_aspect_factory(use_cpp_implementation = True) 5 | -------------------------------------------------------------------------------- /test/aspect/includes/use_includes.cpp: -------------------------------------------------------------------------------- 1 | // Header is available via multiple paths 2 | #include 3 | #include 4 | 5 | int main() { 6 | return doIncludes(); 7 | } 8 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/bar.h: -------------------------------------------------------------------------------- 1 | #ifndef BAR_H 2 | #define BAR_H 3 | #include "using_transitive_dep/foo.h" 4 | 5 | int doStuff() { 6 | return theAnswer() + 1; 7 | } 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_libs.cpp: -------------------------------------------------------------------------------- 1 | #include "libs/foo.h" 2 | #include "libs/sub/bar.h" 3 | #include "root_lib.h" 4 | 5 | int main() { 6 | return doFoo() + doBar() + doRoot(); 7 | } 8 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/lib_with_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_LIB_WITH_DEFINES_H 2 | #define SUPPORT_LIB_WITH_DEFINES_H 3 | 4 | int libWitDefines() { 5 | return 1337; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/macros.h: -------------------------------------------------------------------------------- 1 | #define LIB_A_FILE_PATH "support/lib_a.h" 2 | 3 | #define TOGGLE 4 | 5 | #define THE_ANSWER 42 6 | 7 | #define SQUARE(x) (x) * (x) 8 | 9 | #define STRINGIFY(x) #x 10 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/implementation_dep_info_bar.json: -------------------------------------------------------------------------------- 1 | { 2 | "header_files": [ 3 | "private/dep/bar_1.h", 4 | "private/dep/bar_2.h" 5 | ], 6 | "target": "//private/dep:bar" 7 | } 8 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/implementation_dep_info_foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "header_files": [ 3 | "private/dep/foo_1.h", 4 | "private/dep/foo_2.h" 5 | ], 6 | "target": "//private/dep:foo" 7 | } 8 | -------------------------------------------------------------------------------- /test/benchmark/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_legacy_default = dwyu_aspect_factory() 4 | dwyu_cpp_impl = dwyu_aspect_factory(use_cpp_implementation = True) 5 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/aspect_cpp.bzl.tpl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu = dwyu_aspect_factory(ignore_cc_toolchain_headers = True, use_cpp_implementation = True) 4 | -------------------------------------------------------------------------------- /scripts/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_binary.bzl", "py_binary") 2 | 3 | py_binary( 4 | name = "extract_std_headers", 5 | srcs = ["extract_std_headers.py"], 6 | visibility = [":__subpackages__"], 7 | ) 8 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/libs/foo.h: -------------------------------------------------------------------------------- 1 | // Show that multiple files 'foo.h' in the dependency graph are no issue 2 | #include "other_lib/foo.h" 3 | 4 | int doFoo() { 5 | return doOtherFoo() + 1337; 6 | } 7 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | use_implementation_deps_aspect = dwyu_aspect_factory(use_implementation_deps = True) 4 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo.bzl: -------------------------------------------------------------------------------- 1 | # buildifier: disable=unnamed-macro 2 | def load_external_repo(): 3 | native.local_repository( 4 | name = "external_test_repo", 5 | path = "external_repo/repo", 6 | ) 7 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/ignore_include_paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_include_paths": [ 3 | "support/some_header.h" 4 | ], 5 | "extra_ignore_include_paths": [ 6 | "support/some_other_header.h" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/sub/dir/lib_with_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_SUB_DIR_LIB_WITH_INCLUDES_H 2 | #define SUPPORT_SUB_DIR_LIB_WITH_INCLUDES_H 3 | 4 | int libwithIncludes() { 5 | return 4; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /examples/support/external_targets.bzl: -------------------------------------------------------------------------------- 1 | # buildifier: disable=unnamed-macro 2 | def load_external_targets(): 3 | native.local_repository( 4 | name = "external_targets", 5 | path = "support/external_targets", 6 | ) 7 | -------------------------------------------------------------------------------- /scripts/test/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_test.bzl", "py_test") 2 | 3 | py_test( 4 | name = "extract_std_headers_test", 5 | srcs = ["extract_std_headers_test.py"], 6 | deps = ["//scripts:extract_std_headers"], 7 | ) 8 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "foo", 5 | hdrs = ["foo.h"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/sub/dir/lib_with_add_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_SUB_DIR_LIB_WITH_ADD_PREFIX_H 2 | #define SUPPORT_SUB_DIR_LIB_WITH_ADD_PREFIX_H 3 | 4 | int libwithAddPrefix() { 5 | return 8; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/use_toolchain_headers.h.tpl: -------------------------------------------------------------------------------- 1 | // C++ standard library usage 2 | #include 3 | #include 4 | #include 5 | 6 | // C standard library usage 7 | #include 8 | #include 9 | -------------------------------------------------------------------------------- /third_party/rules_boost/rules_boost_step_2.bzl: -------------------------------------------------------------------------------- 1 | load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps") 2 | 3 | def rules_boost_step_2(): 4 | # Makes @boost available, e.g. '@boost//:algorithm'. 5 | boost_deps() 6 | -------------------------------------------------------------------------------- /third_party/xz/README.md: -------------------------------------------------------------------------------- 1 | Patch taken from https://github.com/bazelbuild/bazel-central-registry/blob/43585652a95b238e7499ef9e83688d07bc2dd348/modules/xz/5.4.5.bcr.2/patches/patch.diff so we can support WORKSPACE until it is fully deprecated 2 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/sub/dir/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "bar", 5 | hdrs = ["bar.h"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/use_configured_lib.h: -------------------------------------------------------------------------------- 1 | #include "ambiguous_lib/lib.h" 2 | #include "configured_lib/configured_deps.h" 3 | 4 | int useConfiguredLib() { 5 | return doSomethingConfigured() + doSomething(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/use_complex_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/dir/complex_include_b.h" 2 | #include 3 | 4 | int useComplexIncludes() { 5 | return doComplexIncludeA() + doComplexIncludeB(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/use_toolchain_header.h: -------------------------------------------------------------------------------- 1 | // C++ standard library usage 2 | #include 3 | #include 4 | #include 5 | 6 | // C standard library usage 7 | #include 8 | #include 9 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/cpp_lib.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | 3 | // If '__cplusplus' would not be set, we fail the DWYU analysis due to an unused dependency 4 | #include "set_cpp_standard/lib.h" 5 | 6 | #endif 7 | 8 | void someFunction(); 9 | -------------------------------------------------------------------------------- /examples/ignoring_includes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "use_unavailable_headers", 5 | hdrs = ["use_unavailable_headers.h"], 6 | ) 7 | 8 | exports_files(["ignore_includes.json"]) 9 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/sub/foo/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "foo", 5 | hdrs = ["foo.h"], 6 | deps = [ 7 | "//:lib", # unused 8 | ], 9 | ) 10 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/ext/dir/ext_lib_with_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_EXT_DIR_LIB_WITH_INCLUDES_H 2 | #define SUPPORT_EXT_DIR_LIB_WITH_INCLUDES_H 3 | 4 | int extLibwithIncludes() { 5 | return 4; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/support/sub/dir/lib_with_strip_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_SUB_DIR_LIB_WITH_STRIP_PREFIX_H 2 | #define SUPPORT_SUB_DIR_LIB_WITH_STRIP_PREFIX_H 3 | 4 | int libwithStripPrefix() { 5 | return 2; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/use_specific_cpp_standard.h: -------------------------------------------------------------------------------- 1 | #if __cplusplus == 201703 2 | 3 | // If '__cplusplus' would not be set as desired, we fail the DWYU analysis due to an unused dependency 4 | #include "set_cpp_standard/lib.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /third_party/bzip2/README.md: -------------------------------------------------------------------------------- 1 | Patch taken from https://github.com/bazelbuild/bazel-central-registry/blob/2e38be281c26c4758de12b0f36fa5ed2ffe812b3/modules/bzip2/1.0.8/patches/add_build_file.patch so we can support WORKSPACE until it is fully deprecated 2 | -------------------------------------------------------------------------------- /third_party/zlib/README.md: -------------------------------------------------------------------------------- 1 | Patch taken from https://github.com/bazelbuild/bazel-central-registry/blob/2e38be281c26c4758de12b0f36fa5ed2ffe812b3/modules/zlib/1.3.1/patches/add_build_file.patch so we can support WORKSPACE until it is fully deprecated 2 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/commented_includes/single_line_comments.h: -------------------------------------------------------------------------------- 1 | //#include "commented.h" 2 | // #include 3 | #include "active_a.h" // 4 | 5 | #include "active_b.h" 6 | 7 | void Foo(); // #include "commented.h" 8 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/use_complex_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/dir/complex_include_b.h" 2 | #include 3 | 4 | int useComplexIncludes() { 5 | return doComplexIncludeA() + doComplexIncludeB(); 6 | } 7 | -------------------------------------------------------------------------------- /test/aspect/external_repo/use_external_libs.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_EXTERNAL_LIBS_H 2 | #define USE_EXTERNAL_LIBS_H 3 | 4 | #include "foo.h" 5 | #include "some/dir/bar.h" 6 | 7 | int useLibs() { 8 | return doFoo() + doBar(); 9 | } 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/ext/dir/ext_lib_with_add_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_EXT_DIR_LIB_WITH_ADD_PREFIX_H 2 | #define SUPPORT_EXT_DIR_LIB_WITH_ADD_PREFIX_H 3 | 4 | int extLibwithAddPrefix() { 5 | return 8; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_libs.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_LIBS_H 2 | #define USE_LIBS_H 3 | 4 | #include "implementation_deps/support/lib_a.h" 5 | 6 | int wrapBar() { 7 | return libA() * 2; 8 | } 9 | 10 | int useLibs(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/tools/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:defs.bzl", "py_binary") 2 | 3 | py_binary( 4 | name = "toolchain_headers_info_check", 5 | srcs = ["toolchain_headers_info_check.py"], 6 | visibility = ["//:__pkg__"], 7 | ) 8 | -------------------------------------------------------------------------------- /third_party/zstd/README.md: -------------------------------------------------------------------------------- 1 | Patch taken from https://github.com/bazelbuild/bazel-central-registry/blob/2e38be281c26c4758de12b0f36fa5ed2ffe812b3/modules/zstd/1.5.5.bcr.1/patches/add_build_file.patch so we can support WORKSPACE until it is fully deprecated 2 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | default_aspect = dwyu_aspect_factory() 4 | use_implementation_deps_aspect = dwyu_aspect_factory(use_implementation_deps = True) 5 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | default_aspect = dwyu_aspect_factory() 4 | use_implementation_deps_aspect = dwyu_aspect_factory(use_implementation_deps = True) 5 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo.bzl: -------------------------------------------------------------------------------- 1 | # buildifier: disable=unnamed-macro 2 | def load_complex_includes_repo(): 3 | native.local_repository( 4 | name = "complex_includes_test_repo", 5 | path = "complex_includes/ext_repo", 6 | ) 7 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/some_header.h: -------------------------------------------------------------------------------- 1 | #ifndef SOME_HEADER_H 2 | #define SOME_HEADER_H 3 | 4 | #include "bar.h" 5 | #include "foo/bar/baz.h" 6 | #include 7 | #include 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/ext/dir/ext_lib_with_strip_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_EXT_DIR_LIB_WITH_STRIP_PREFIX_H 2 | #define SUPPORT_EXT_DIR_LIB_WITH_STRIP_PREFIX_H 3 | 4 | int extLibwithStripPrefix() { 5 | return 2; 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/complex_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/dir/complex_include_b.h" 2 | #include 3 | 4 | int doComplexIncludeA() { 5 | return 42; 6 | } 7 | 8 | int doComplexIncludeB() { 9 | return 24; 10 | } 11 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep.bzl: -------------------------------------------------------------------------------- 1 | # buildifier: disable=unnamed-macro 2 | def load_external_dep(): 3 | native.local_repository( 4 | name = "skip_external_deps_test_repo", 5 | path = "skip_external_targets/external_dep", 6 | ) 7 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/use_ignored_patterns.h: -------------------------------------------------------------------------------- 1 | #include "support/do_match_include_end.h" 2 | #include "support/ignored_sub_path_1/some_header.h" 3 | #include "support/ignored_sub_path_2/some_header.h" 4 | #include "support/matching_begin_without_regex_works_example.h" 5 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/use_complex_libraries.cpp: -------------------------------------------------------------------------------- 1 | // Include headers from real projects which are known not to be trivial to preprocess 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/complex_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "virtual/prefix/dir/complex_include_b.h" 2 | #include 3 | 4 | int doComplexIncludeA() { 5 | return 42; 6 | } 7 | 8 | int doComplexIncludeB() { 9 | return 24; 10 | } 11 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/config/overwrite_default_ignore_paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_include_paths": [ 3 | "foo", 4 | "bar" 5 | ], 6 | "extra_ignore_include_paths": [ 7 | "foo", 8 | "foobar" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/target_under_inspection_empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "defines": [], 3 | "includes": [], 4 | "quote_includes": [], 5 | "external_includes": [], 6 | "system_includes": [], 7 | "header_files": [], 8 | "target": "//:foo" 9 | } 10 | -------------------------------------------------------------------------------- /.buildifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "auto", 3 | "mode": "fix", 4 | "lint": "fix", 5 | "warningsList": [ 6 | "+unsorted-dict-items", 7 | "-function-docstring", 8 | "-function-docstring-header", 9 | "-module-docstring" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/recursion/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "use_lib", 5 | hdrs = ["use_lib.h"], 6 | deps = [":faulty_lib"], 7 | ) 8 | 9 | cc_library( 10 | name = "faulty_lib", 11 | hdrs = ["lib.h"], 12 | ) 13 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/use_normal_include.cpp: -------------------------------------------------------------------------------- 1 | // relative includes to headers from dependencies 2 | #include "normal_include.h" 3 | #include "some/sub/dir/../dir/bar.h" 4 | #include "some/sub/dir/foo.h" 5 | 6 | int main() { 7 | return useNormalInclude() + doBar() + doFoo(); 8 | } 9 | -------------------------------------------------------------------------------- /test/aspect/valid/bar/bar.cc: -------------------------------------------------------------------------------- 1 | #include "valid/bar/bar.h" 2 | #include "valid/bar/private_a.h" 3 | #include "valid/bar/sub/dir/private_b.h" 4 | #include "valid/foo/b.h" 5 | #include "valid/foo/textual.cc" 6 | 7 | int doBar() { 8 | return doB() + doPrivateA() + doPrivateB(); 9 | } 10 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/cc_toolchain_headers.bzl: -------------------------------------------------------------------------------- 1 | load("//dwyu/cc_toolchain_headers/private:gather_cc_toolchain_headers.bzl", _gather_cc_toolchain_headers = "gather_cc_toolchain_headers") 2 | 3 | visibility("//dwyu/...") 4 | 5 | dwyu_gather_cc_toolchain_headers = _gather_cc_toolchain_headers 6 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/README.md: -------------------------------------------------------------------------------- 1 | Using relative include paths is considered a bad practice in Bazel projects as documented in [bazel-and-cpp](https://bazel.build/docs/bazel-and-cpp#include-paths). 2 | However, since relative include paths are a valid C++ feature, DWYU aims to support this. 3 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/mixed_libs_usage.cpp: -------------------------------------------------------------------------------- 1 | #include "mixed_libs_usage.h" 2 | // used publicly and privately 3 | #include "libs/foo.h" 4 | // used solely privately 5 | #include "libs/sub/bar.h" 6 | 7 | int doMixed() { 8 | return doRoot() + doFoo() + doBar(); 9 | } 10 | -------------------------------------------------------------------------------- /test/aspect/defines/use_command_line_defines.h: -------------------------------------------------------------------------------- 1 | #ifdef SOME_FLAG 2 | // do some things irrelevant for DWYU 3 | #else 4 | #include "not/extsting/header.h" 5 | #endif 6 | 7 | #if SOME_VALUE > 40 8 | // do some things irrelevant for DWYU 9 | #else 10 | #include "not/extsting/header.h" 11 | #endif 12 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | set_cplusplus = dwyu_aspect_factory(experimental_set_cplusplus = True) 4 | 5 | set_cplusplus_cpp = dwyu_aspect_factory(experimental_set_cplusplus = True, use_cpp_implementation = True) 6 | -------------------------------------------------------------------------------- /dwyu/cc_info_mapping/providers.bzl: -------------------------------------------------------------------------------- 1 | DwyuCcInfoMappingInfo = provider( 2 | "Mapping of targets to CcInfo providers which DWYU should use for analysis instead of the targets original CcInfo.", 3 | fields = { 4 | "mapping": "Dictionary with structure {'target label': CcInfo}", 5 | }, 6 | ) 7 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_skip_external = dwyu_aspect_factory(skip_external_targets = True) 4 | 5 | dwyu_skip_external_cpp = dwyu_aspect_factory(skip_external_targets = True, use_cpp_implementation = True) 6 | -------------------------------------------------------------------------------- /test/workspace_integration/README.md: -------------------------------------------------------------------------------- 1 | These tests ensure that DWYU is integrable as advertised in the documentation for all supported Bazel versions. 2 | 3 | We explicitly do not add further dependencies to ensure no other modules and their transitive dependencies overwrite the dependencies defined by DWYU. 4 | -------------------------------------------------------------------------------- /test/aspect/external_repo/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "use_external_libs", 5 | hdrs = ["use_external_libs.h"], 6 | deps = [ 7 | "@external_test_repo//:ext_bar", 8 | "@external_test_repo//:ext_foo", 9 | ], 10 | ) 11 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_custom_tags = dwyu_aspect_factory(skipped_tags = ["tag_marking_skipping"]) 4 | 5 | dwyu_custom_tags_cpp = dwyu_aspect_factory(skipped_tags = ["tag_marking_skipping"], use_cpp_implementation = True) 6 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_complex_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "dir/lib_with_includes.h" 2 | #include "lib_with_strip_prefix.h" 3 | #include "some/prefix/sub/dir/lib_with_add_prefix.h" 4 | 5 | int doSomethingWithComplexIncludes() { 6 | return libwithIncludes() + libwithStripPrefix() + libwithAddPrefix(); 7 | } 8 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_no_preprocessor = dwyu_aspect_factory(experimental_no_preprocessor = True) 4 | 5 | dwyu_no_preprocessor_cpp = dwyu_aspect_factory(experimental_no_preprocessor = True, use_cpp_implementation = True) 6 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/system_include.cpp: -------------------------------------------------------------------------------- 1 | // relatively including header from own target 2 | #include "system_include.h" 3 | #include "some/sub/dir/bar.h" 4 | // include from virtually prefixed path 5 | #include 6 | 7 | int useSystemInclude() { 8 | return doFoo() + doBar(); 9 | } 10 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/.bazelrc: -------------------------------------------------------------------------------- 1 | # Always tell why tests fail 2 | test --test_output=errors 3 | 4 | # Do not waste memory by keeping idle Bazel servers around 5 | startup --max_idle_secs=10 6 | 7 | # The symlinks are cluttering the file tree without much value 8 | common --experimental_convenience_symlinks=ignore 9 | -------------------------------------------------------------------------------- /test/support/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_library.bzl", "py_library") 2 | 3 | py_library( 4 | name = "support", 5 | testonly = True, 6 | srcs = [ 7 | "bazel.py", 8 | "platform.py", 9 | "result.py", 10 | ], 11 | visibility = ["//visibility:public"], 12 | ) 13 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "test_toolchain_rule_based") 2 | 3 | bazel_dep(name = "rules_cc", version = "0.1.1") 4 | bazel_dep(name = "rules_shell", version = "0.5.0") 5 | bazel_dep(name = "bazel_skylib", version = "1.0.3") 6 | bazel_dep(name = "platforms", version = "0.0.10") 7 | -------------------------------------------------------------------------------- /third_party/extensions_step_2.bzl: -------------------------------------------------------------------------------- 1 | load("//third_party/rules_boost:rules_boost_step_2.bzl", "rules_boost_step_2") 2 | 3 | def _non_module_dependencies_step_2_impl(_ctx): 4 | rules_boost_step_2() 5 | 6 | non_module_dependencies_step_2 = module_extension( 7 | implementation = _non_module_dependencies_step_2_impl, 8 | ) 9 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_preprocessor_results/RREADME.md: -------------------------------------------------------------------------------- 1 | This is an intermediate tool which will be removed soon when we implement what it does in C++. 2 | Thus, no extra documentation or tests are introduced. 3 | Either way, 90% of the implementation used here is from the well tested Python implementation of the DWYU aspect. 4 | -------------------------------------------------------------------------------- /test/aspect/defines/support/conditional_defines.h: -------------------------------------------------------------------------------- 1 | #include "defines/support/some_defines.h" 2 | 3 | // Set defines based on values from included header 4 | 5 | #ifdef SWITCH_USE_B 6 | #define USE_B 7 | #endif 8 | 9 | #if SOME_SWITCH_VALUE > 100 10 | #define SOME_VALUE 42 11 | #else 12 | #define SOME_VALUE 0 13 | #endif 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | 3 | # Bazel 4 | bazel-* 5 | *MODULE.bazel.lock 6 | user.bazelrc 7 | 8 | # Python 9 | __pycache__ 10 | *.pyc 11 | venv/ 12 | .coverage 13 | 14 | # IDEs 15 | .clwb 16 | .idea 17 | .vscode 18 | 19 | # Test data 20 | dwyu/aspect/private/analyze_includes/test/benchmark/parsing_examples 21 | test/benchmark/generated 22 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/private_header/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "private_header", 5 | srcs = [ 6 | "bar.cpp", 7 | "private_bar.h", 8 | ], 9 | hdrs = ["bar.h"], 10 | visibility = ["//visibility:public"], 11 | ) 12 | -------------------------------------------------------------------------------- /examples/support/external_targets/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "has_unused_dep", 5 | hdrs = ["has_unused_dep.h"], 6 | visibility = ["//visibility:public"], 7 | deps = [":foo"], 8 | ) 9 | 10 | cc_library( 11 | name = "foo", 12 | hdrs = ["foo.h"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/normal_include.cpp: -------------------------------------------------------------------------------- 1 | // relatively including header from own target 2 | #include "normal_include.h" 3 | #include "some/sub/dir/foo.h" 4 | // normal include relative to workspace root 5 | #include "relative_includes/some/sub/dir/bar.h" 6 | 7 | int useNormalInclude() { 8 | return doFoo() + doBar(); 9 | } 10 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/README.md: -------------------------------------------------------------------------------- 1 | These tests ensure the DWYU features utilizing the Bazel CC toolchain are working together with established upstream toolchains. 2 | The tests have no clear defined result besides "_DWYU should not fail_" as we can't define fine grained expected results with complex toolchains pointing to thousands of files. 3 | -------------------------------------------------------------------------------- /test/workspace_integration/.bazelrc: -------------------------------------------------------------------------------- 1 | # The symlinks have no value for us, but clutter the project view in the IDE 2 | build --experimental_convenience_symlinks=clean 3 | 4 | build:dwyu --output_groups=dwyu 5 | build:dwyu --aspects=//:aspect.bzl%dwyu 6 | 7 | build:dwyu_cpp --output_groups=dwyu 8 | build:dwyu_cpp --aspects=//:aspect.bzl%dwyu_cpp 9 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/ignore_include_patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_include_patterns": [ 3 | "support/ignored_sub_path_1/.*", 4 | ".*_match_include_end.h", 5 | "\\w+/ignored_sub_path_2/.*", 6 | "support/matching_begin_without_regex_works", 7 | "substring_match_does_not_work_here" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/main.cpp: -------------------------------------------------------------------------------- 1 | #include "using_transitive_dep/bar.h" 2 | #include "using_transitive_dep/foo.h" 3 | 4 | int main() { 5 | // ERROR: Using a function from library foo but depending only on library bar 6 | const int answer = theAnswer(); 7 | const int stuff = doStuff(); 8 | return answer != stuff; 9 | } 10 | -------------------------------------------------------------------------------- /examples/target_mapping/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | 3 | cc_binary( 4 | name = "use_lib_b", 5 | srcs = ["use_lib_b.cpp"], 6 | deps = ["//target_mapping/libs:a"], 7 | ) 8 | 9 | cc_binary( 10 | name = "use_lib_c", 11 | srcs = ["use_lib_c.cpp"], 12 | deps = ["//target_mapping/libs:a"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/command_length_limit/make_large_arg.bzl: -------------------------------------------------------------------------------- 1 | # buildifier: disable=unnamed-macro 2 | def make_large_defines(minimum_characters): 3 | fake_define = "__{n}_ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz__" 4 | steps = int(minimum_characters / (len(fake_define) - 2)) + 1 5 | return [fake_define.format(n = i) for i in range(steps)] 6 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | IndentWidth: 4 3 | ColumnLimit: 120 4 | PointerAlignment: Left 5 | AllowShortFunctionsOnASingleLine: Inline 6 | AllowShortBlocksOnASingleLine: Empty 7 | BinPackParameters: OnePerLine 8 | BreakBeforeBraces: Custom 9 | BreakAfterReturnType: None 10 | AlwaysBreakTemplateDeclarations: true 11 | BraceWrapping: 12 | BeforeElse: true 13 | -------------------------------------------------------------------------------- /examples/set_cpp_standard/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "cpp_lib", 5 | srcs = ["cpp_lib.cpp"], 6 | hdrs = ["cpp_lib.h"], 7 | ) 8 | 9 | cc_library( 10 | name = "use_specific_cpp_standard", 11 | hdrs = ["use_specific_cpp_standard.h"], 12 | copts = ["-std=c++17"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "ext_bar", 5 | hdrs = ["some/dir/bar.h"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_library( 10 | name = "ext_foo", 11 | hdrs = ["foo.h"], 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_external.cpp: -------------------------------------------------------------------------------- 1 | #include "dir/ext_lib_with_includes.h" 2 | #include "ext_lib.h" 3 | #include "ext_lib_with_strip_prefix.h" 4 | #include "some/prefix/ext/dir/ext_lib_with_add_prefix.h" 5 | 6 | int doSomethingWithExternal() { 7 | return extLib() + extLibwithIncludes() + extLibwithStripPrefix() + extLibwithAddPrefix(); 8 | } 9 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/virtual_strip.cpp: -------------------------------------------------------------------------------- 1 | // relatively including header from own target 2 | #include "some/virtual_strip.h" 3 | #include "other/other.h" 4 | #include "some/sub/dir/bar.h" 5 | // include from virtually stripped path 6 | #include "sub/dir/foo.h" 7 | 8 | int useVirtualStrip() { 9 | return doFoo() + doBar() + doOther(); 10 | } 11 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/use_defines.h: -------------------------------------------------------------------------------- 1 | #include "dwyu/aspect/private/analyze_includes/test/data/some_defines.h" 2 | 3 | #ifdef MY_DEFINE 4 | #include "expected/include_a.h" 5 | #else 6 | #include "bad/include_a.h" 7 | #endif 8 | 9 | #if THE_ANSWER > 40 10 | #include "expected/include_b.h" 11 | #else 12 | #include "bad/include_b.h" 13 | #endif 14 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/ambiguous_lib/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "lib_a", 5 | hdrs = ["lib.h"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_library( 10 | name = "lib_b", 11 | hdrs = ["lib.h"], 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu = dwyu_aspect_factory() 4 | dwyu_impl_deps = dwyu_aspect_factory(use_implementation_deps = True) 5 | 6 | dwyu_cpp = dwyu_aspect_factory(use_cpp_implementation = True) 7 | dwyu_impl_deps_cpp = dwyu_aspect_factory(use_implementation_deps = True, use_cpp_implementation = True) 8 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/virtual_prefix.cpp: -------------------------------------------------------------------------------- 1 | // relatively including header from own target 2 | #include "virtual_prefix.h" 3 | #include "other/other.h" 4 | #include "some/sub/dir/bar.h" 5 | // include from virtually prefixed path 6 | #include "custom/prefix/some/sub/dir/foo.h" 7 | 8 | int useVirtualPrefix() { 9 | return doFoo() + doBar() + doOther(); 10 | } 11 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/providers.bzl: -------------------------------------------------------------------------------- 1 | DwyuCcToolchainHeadersInfo = provider( 2 | "Information about header files which can be included without any explicit dependency through the CC toolchain.", 3 | fields = { 4 | "headers_info": "File storing all header file include paths usable through the CC toolchain. File content is a list in json format.", 5 | }, 6 | ) 7 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/use_system_include.cpp: -------------------------------------------------------------------------------- 1 | // relative includes to headers from dependencies 2 | #include "some/sub/dir/../dir/bar.h" 3 | #include "some/sub/dir/foo.h" 4 | #include "system_include.h" 5 | // include from virtually prefixed path 6 | #include 7 | 8 | int main() { 9 | return useSystemInclude() + doBar() + doFoo(); 10 | } 11 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/transitive_usage_through_impl_deps.h: -------------------------------------------------------------------------------- 1 | #include "using_transitive_dep/bar.h" 2 | #include "using_transitive_dep/foo.h" 3 | 4 | int doSth() { 5 | // ERROR: Using a function from library foo but depending only on library bar 6 | const int answer = theAnswer(); 7 | const int stuff = doStuff(); 8 | return answer != stuff; 9 | } 10 | -------------------------------------------------------------------------------- /dwyu/aspect/private/preprocessing/extract_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef DWYU_ASPECT_PRIVATE_PREPROCESSING_EXTRACT_INCLUDES_H 2 | #define DWYU_ASPECT_PRIVATE_PREPROCESSING_EXTRACT_INCLUDES_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace dwyu { 9 | 10 | std::set extractIncludes(std::istream& stream); 11 | 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /dwyu/cc_info_mapping/private/providers.bzl: -------------------------------------------------------------------------------- 1 | visibility("//dwyu/cc_info_mapping/...") 2 | 3 | DwyuRemappedCcInfo = provider( 4 | "An alternative CcInfo object for a target which can be used by DWYU during the analysis", 5 | fields = { 6 | "cc_info": "CcInfo provider", 7 | "target": "Label of target which should use the cc_info object", 8 | }, 9 | ) 10 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/use_virtual_strip.cpp: -------------------------------------------------------------------------------- 1 | // relative includes to headers from dependencies 2 | #include "some/sub/dir/../dir/bar.h" 3 | #include "some/sub/dir/bar.h" 4 | #include "some/virtual_strip.h" 5 | // include from virtually stripped path 6 | #include "sub/dir/../dir/foo.h" 7 | 8 | int main() { 9 | return useVirtualStrip() + doBar() + doFoo(); 10 | } 11 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/BUILD: -------------------------------------------------------------------------------- 1 | load(":toolchain_headers_info_test.bzl", "toolchain_headers_info_tests") 2 | 3 | toolchain_headers_info_tests( 4 | expected_headers = [ 5 | "buzz.h", 6 | "buzz/buzz.h", 7 | "fizz", 8 | "foobar.h", 9 | ], 10 | headers_info = "@depend_on_what_you_use//dwyu/aspect/private:cc_toolchain_headers", 11 | ) 12 | -------------------------------------------------------------------------------- /test/support/platform.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path, PosixPath 4 | 5 | 6 | def path_to_starlark_format(path: Path) -> str: 7 | """ 8 | We can't use the path directly on Windows as we need escaped backslashes on Windows 9 | """ 10 | return str(path) if isinstance(path, PosixPath) else str(path).replace("\\", "\\\\") 11 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/generate_code/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | genrule( 4 | name = "foo_h", 5 | outs = ["foo.h"], 6 | cmd = "echo 'int doGenerated() { return 42; }' > \"$@\"", 7 | ) 8 | 9 | cc_library( 10 | name = "foo", 11 | hdrs = ["foo.h"], 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /test/aspect/shared_library/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "foo_lib", 6 | srcs = ["foo.cc"], 7 | hdrs = ["foo.h"], 8 | ) 9 | 10 | cc_binary( 11 | name = "libfoo.so", 12 | linkshared = True, 13 | deps = [ 14 | ":foo_lib", 15 | ], 16 | ) 17 | -------------------------------------------------------------------------------- /docs/BUILD: -------------------------------------------------------------------------------- 1 | load("@aspect_bazel_lib//lib:docs.bzl", "stardoc_with_diff_test", "update_docs") 2 | 3 | stardoc_with_diff_test( 4 | name = "cc_info_mapping", 5 | bzl_library_target = "//dwyu/cc_info_mapping:cc_info_mapping", 6 | ) 7 | 8 | stardoc_with_diff_test( 9 | name = "dwyu_aspect", 10 | bzl_library_target = "//dwyu/aspect:factory", 11 | ) 12 | 13 | update_docs() 14 | -------------------------------------------------------------------------------- /test/aspect/defines/defines_from_bazel_target.h: -------------------------------------------------------------------------------- 1 | #ifdef SOME_DEFINE 2 | #include "defines/support/a.h" 3 | #else 4 | #include "non/existing/a.h" 5 | #endif 6 | 7 | #ifdef LOCAL_DEFINE 8 | #include "defines/support/a.h" 9 | #else 10 | #include "non/existing/b.h" 11 | #endif 12 | 13 | #if SOME_COPT > 40 14 | #include "defines/support/a.h" 15 | #else 16 | #include "non/existing/c.h" 17 | #endif 18 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/use_virtual_prefix.cpp: -------------------------------------------------------------------------------- 1 | // relative includes to headers from dependencies 2 | #include "some/sub/dir/../dir/bar.h" 3 | #include "some/sub/dir/bar.h" 4 | #include "virtual_prefix.h" 5 | // include from virtually prefixed path 6 | #include "custom/prefix/../prefix/some/sub/dir/foo.h" 7 | 8 | int main() { 9 | return useVirtualPrefix() + doBar() + doFoo(); 10 | } 11 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/benchmark/README.md: -------------------------------------------------------------------------------- 1 | With [cProfile](https://docs.python.org/3/library/profile.html) one can benchmark Python programs `python3 -m cProfile -o .prof `. 2 | When doing so, the benchmark scripst expect the user to run this fromt he workspace root. 3 | 4 | Visualizing this data as flamgraph can be done with [flameprof](https://pypi.org/project/flameprof/). 5 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/other_lib/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | # We use this library to prove that multiple header with the same name existing in the dependency is not a problem if 4 | # they are included with their full path 5 | cc_library( 6 | name = "other_lib", 7 | hdrs = ["foo.h"], 8 | visibility = ["//visibility:public"], 9 | ) 10 | -------------------------------------------------------------------------------- /test/aspect/defines/in_file_defines.h: -------------------------------------------------------------------------------- 1 | #define USE_A 2 | 3 | #ifdef USE_A 4 | #include "defines/support/a.h" 5 | #else 6 | #include "defines/support/b.h" 7 | #endif 8 | 9 | #ifdef NON_EXISTING_DEFINE 10 | #include "defines/support/b.h" 11 | #endif 12 | 13 | #define SOME_VALUE 42 14 | 15 | #if SOME_VALUE > 40 16 | #include "defines/support/a.h" 17 | #else 18 | #include "defines/support/b.h" 19 | #endif 20 | -------------------------------------------------------------------------------- /test/aspect/external_repo/repo/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "external_test_repo") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /test/aspect/multiple_deps_for_one_header/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "foo", 5 | hdrs = ["foo.h"], 6 | deps = [ 7 | ":bar_a", 8 | ":bar_b", 9 | ], 10 | ) 11 | 12 | cc_library( 13 | name = "bar_a", 14 | hdrs = ["bar.h"], 15 | ) 16 | 17 | cc_library( 18 | name = "bar_b", 19 | hdrs = ["bar.h"], 20 | ) 21 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/README.md: -------------------------------------------------------------------------------- 1 | This is partly a duplicate to the [defines](../defines/) integration tests. 2 | Here we concentrate more generally on correctly processing preprocessor statements. 3 | Also, some of the things we do here are only supported by the new C++ based implementation. 4 | 5 | When we deprecate the Python based implementation, we will remove the [defines](../defines/) integration tests. 6 | -------------------------------------------------------------------------------- /third_party/pcpp/pcpp.BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_library.bzl", "py_library") 2 | 3 | py_library( 4 | name = "pcpp", 5 | srcs = glob(["pcpp/**/*"]), 6 | imports = ["."], 7 | # Users are not supposed to reuse this directly. However, since users can include this project under 8 | # a custom name, we can't restrict visibility. 9 | visibility = ["//visibility:public"], 10 | ) 11 | -------------------------------------------------------------------------------- /dwyu/cc_info_mapping/private/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | 3 | bzl_library( 4 | name = "cc_info_mapping_impl_bzl", 5 | srcs = [ 6 | "direct_deps.bzl", 7 | "explicit.bzl", 8 | "providers.bzl", 9 | "transitive_deps.bzl", 10 | ], 11 | visibility = ["//dwyu/cc_info_mapping:__pkg__"], 12 | deps = ["@rules_cc//cc/common"], 13 | ) 14 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | 3 | bzl_library( 4 | name = "cc_toolchain_headers", 5 | srcs = [ 6 | "cc_toolchain_headers.bzl", 7 | "providers.bzl", 8 | ], 9 | visibility = ["//visibility:public"], 10 | deps = [ 11 | "//dwyu/cc_toolchain_headers/private:gather_cc_toolchain_headers_bzl", 12 | ], 13 | ) 14 | -------------------------------------------------------------------------------- /examples/support/external_targets/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "external_targets") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /examples/rule_using_dwyu/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | load(":rule.bzl", "dwyu_rule") 3 | 4 | cc_library( 5 | name = "bad_target", 6 | hdrs = ["bad_target.h"], 7 | ) 8 | 9 | dwyu_rule( 10 | name = "dwyu", 11 | tags = [ 12 | "manual", # This target is supposed to fail, thus only build it if explicitly requested 13 | ], 14 | deps = [":bad_target"], 15 | ) 16 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "complex_includes_test_repo") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/target_under_inspection.json: -------------------------------------------------------------------------------- 1 | { 2 | "defines": [ 3 | "SOME_DEFINE", 4 | "ANOTHER_DEFINE=42" 5 | ], 6 | "includes": ["."], 7 | "quote_includes": ["some/dir"], 8 | "external_includes": ["external/dir"], 9 | "system_includes": ["another/dir"], 10 | "header_files": [ 11 | "self/header_1.h", 12 | "self/header_2.h" 13 | ], 14 | "target": "//:baz" 15 | } 16 | -------------------------------------------------------------------------------- /setup_step_1.bzl: -------------------------------------------------------------------------------- 1 | load("//third_party:dependencies.bzl", "dependencies") 2 | 3 | def setup_step_1(): 4 | """ 5 | Perform the initial setup steps for this project. 6 | 7 | We cannot execute load statements from external workspaces until they have been defined. Thus, we have to perform 8 | multiple iterations of loading a setup function and executing it from the WORKSPACE file. 9 | """ 10 | dependencies() 11 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/external_dep/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "external_dep") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "impl_deps_external_test_repo") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "broken_dep", 5 | hdrs = ["broken_dep.h"], 6 | deps = [":a"], # Missing dependency to //lib:b 7 | ) 8 | 9 | cc_library( 10 | name = "a", 11 | hdrs = ["lib/a.h"], 12 | deps = [":b"], 13 | ) 14 | 15 | cc_library( 16 | name = "b", 17 | hdrs = ["lib/b.h"], 18 | ) 19 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/use_defines.cpp: -------------------------------------------------------------------------------- 1 | #include "implementation_deps/use_defines.h" 2 | 3 | // The value of a define can decide if we include one file or another 4 | #if THE_ANSWER > 10 5 | #include "support/lib_with_defines.h" 6 | #else 7 | // If this would be included, it would fail the DWYU analysis 8 | #include "support/transitive.h" 9 | #endif 10 | 11 | int useDefines() { 12 | return libWitDefines() + 42; 13 | } 14 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/external_dep/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "skip_external_deps_test_repo") 2 | 3 | # We specify by design an outdated rules_cc version. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 6 | bazel_dep(name = "rules_cc", version = "0.0.1") 7 | -------------------------------------------------------------------------------- /test/aspect/defines/use_defines_from_dependency_header.h: -------------------------------------------------------------------------------- 1 | #include "defines/support/conditional_defines.h" 2 | 3 | // Analyze include statements based on code parts active due to defines from included header 4 | 5 | #ifdef USE_B 6 | #include "defines/support/b.h" 7 | #else 8 | #include "defines/support/c.h" 9 | #endif 10 | 11 | #if SOME_VALUE > 40 12 | #include "defines/support/b.h" 13 | #else 14 | #include "defines/support/c.h" 15 | #endif 16 | -------------------------------------------------------------------------------- /test/aspect/generated_code/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | genrule( 5 | name = "bar_h", 6 | outs = ["bar.h"], 7 | cmd = "echo '// Header content' > \"$@\"", 8 | ) 9 | 10 | cc_library( 11 | name = "bar", 12 | hdrs = ["bar.h"], 13 | ) 14 | 15 | cc_binary( 16 | name = "foo", 17 | srcs = ["foo.cpp"], 18 | deps = [":bar"], 19 | ) 20 | -------------------------------------------------------------------------------- /examples/ignoring_includes/use_unavailable_headers.h: -------------------------------------------------------------------------------- 1 | // Standard library headers are ignored by default without a need for configuration 2 | #include 3 | 4 | // Header which does not exist but causes no error due to being ignored explicitly 5 | #include "some/header.h" 6 | 7 | // If all headers we want to ignore share a common path we can use patterns in the config to ease maintenance 8 | #include "some_pkg/bar.h" 9 | #include "some_pkg/foo.h" 10 | -------------------------------------------------------------------------------- /test/benchmark/.bazelrc: -------------------------------------------------------------------------------- 1 | # Do not waste memory by keeping idle Bazel servers around 2 | startup --max_idle_secs=10 3 | 4 | # Always tell why tests fail 5 | test --test_output=errors 6 | 7 | # The benchmarks don't care about higher versions than expected for our dependencies being used 8 | common --check_direct_dependencies=off 9 | 10 | # The symlinks are cluttering the file tree without much value 11 | common --experimental_convenience_symlinks=ignore 12 | -------------------------------------------------------------------------------- /test/workspace_integration/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "dwyu_examples") 2 | 3 | # Choose a custom name to prove we have no hard coded dependency on 'depend_on_what_you_use' being used as name 4 | local_repository( 5 | name = "custom_dwyu", 6 | path = "../../", 7 | ) 8 | 9 | load("@custom_dwyu//:setup_step_1.bzl", "setup_step_1") 10 | 11 | setup_step_1() 12 | 13 | load("@custom_dwyu//:setup_step_2.bzl", "setup_step_2") 14 | 15 | setup_step_2() 16 | -------------------------------------------------------------------------------- /dwyu/aspect/private/BUILD: -------------------------------------------------------------------------------- 1 | load("//dwyu/cc_toolchain_headers:cc_toolchain_headers.bzl", "dwyu_gather_cc_toolchain_headers") 2 | load(":cc_toolchain_headers_stub.bzl", "cc_toolchain_headers_stub") 3 | 4 | dwyu_gather_cc_toolchain_headers( 5 | name = "cc_toolchain_headers", 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_toolchain_headers_stub( 10 | name = "cc_toolchain_headers_stub", 11 | visibility = ["//visibility:public"], 12 | ) 13 | -------------------------------------------------------------------------------- /test/aspect/.bazelrc: -------------------------------------------------------------------------------- 1 | # Do not waste memory by keeping idle Bazel servers around 2 | startup --max_idle_secs=10 3 | 4 | # Always tell why tests fail 5 | test --test_output=errors 6 | 7 | # The integration tests don't care about higher versions than expected for our dependencies being used 8 | common --check_direct_dependencies=off 9 | 10 | # The symlinks are cluttering the file tree without much value 11 | common --experimental_convenience_symlinks=ignore 12 | -------------------------------------------------------------------------------- /dwyu/aspect/private/preprocessing/executable_stub.bzl: -------------------------------------------------------------------------------- 1 | def _executable_stub_impl(ctx): 2 | ctx.actions.write(output = ctx.outputs.executable, is_executable = True, content = "Irrelevant, will never be called") 3 | return [DefaultInfo( 4 | files = depset([ctx.outputs.executable]), 5 | executable = ctx.outputs.executable, 6 | )] 7 | 8 | executable_stub = rule( 9 | implementation = _executable_stub_impl, 10 | executable = True, 11 | ) 12 | -------------------------------------------------------------------------------- /examples/target_mapping/libs/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "a", 5 | hdrs = ["a.h"], 6 | visibility = ["//target_mapping:__subpackages__"], 7 | deps = [":b"], 8 | ) 9 | 10 | cc_library( 11 | name = "b", 12 | hdrs = ["b.h"], 13 | visibility = ["//target_mapping/mapping:__pkg__"], 14 | deps = [":c"], 15 | ) 16 | 17 | cc_library( 18 | name = "c", 19 | hdrs = ["c.h"], 20 | ) 21 | -------------------------------------------------------------------------------- /test/aspect/includes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "includes", 6 | srcs = ["includes.cpp"], 7 | hdrs = ["some/sub/dir/includes.h"], 8 | includes = [ 9 | "some", 10 | "some/sub", 11 | ], 12 | ) 13 | 14 | cc_binary( 15 | name = "use_includes", 16 | srcs = ["use_includes.cpp"], 17 | deps = [":includes"], 18 | ) 19 | -------------------------------------------------------------------------------- /dwyu/private/utils.bzl: -------------------------------------------------------------------------------- 1 | visibility("//dwyu/...") 2 | 3 | def label_to_name(label): 4 | """ 5 | Create a legal name from a string describing a Bazel target label 6 | """ 7 | return str(label).replace("@", "").replace("//", "_").replace("/", "_").replace(":", "_") 8 | 9 | def make_param_file_args(ctx): 10 | args = ctx.actions.args() 11 | 12 | args.set_param_file_format("multiline") 13 | args.use_param_file("--param_file=%s") 14 | 15 | return args 16 | -------------------------------------------------------------------------------- /test/aspect/valid/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "foo", 5 | hdrs = [ 6 | "foo/a.h", 7 | "foo/b.h", 8 | ], 9 | textual_hdrs = ["foo/textual.cc"], 10 | ) 11 | 12 | cc_library( 13 | name = "bar", 14 | srcs = [ 15 | "bar/bar.cc", 16 | "bar/private_a.h", 17 | "bar/sub/dir/private_b.h", 18 | ], 19 | hdrs = ["bar/bar.h"], 20 | deps = [":foo"], 21 | ) 22 | -------------------------------------------------------------------------------- /test/aspect/valid/test_common_valid_case.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//valid:bar", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/defines/test_processing_defines.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//defines:all", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/includes/test_system_includes.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//includes:all", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/recursion/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_recursive = dwyu_aspect_factory(recursive = True) 4 | dwyu_recursive_impl_deps = dwyu_aspect_factory(recursive = True, use_implementation_deps = True) 5 | 6 | dwyu_recursive_cpp = dwyu_aspect_factory(recursive = True, use_cpp_implementation = True) 7 | dwyu_recursive_impl_deps_cpp = dwyu_aspect_factory(recursive = True, use_implementation_deps = True, use_cpp_implementation = True) 8 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "cpp_lib", 5 | srcs = ["cpp_lib.cpp"], 6 | hdrs = ["cpp_lib.h"], 7 | deps = [":lib"], 8 | ) 9 | 10 | cc_library( 11 | name = "use_specific_cpp_standard", 12 | hdrs = ["use_specific_cpp_standard.h"], 13 | copts = ["-std=c++17"], 14 | deps = [":lib"], 15 | ) 16 | 17 | cc_library( 18 | name = "lib", 19 | hdrs = ["lib.h"], 20 | ) 21 | -------------------------------------------------------------------------------- /third_party/extensions_step_1.bzl: -------------------------------------------------------------------------------- 1 | load("//third_party/boost/wave:repository.bzl", "boost_wave") 2 | load("//third_party/pcpp:repository.bzl", "pcpp") 3 | load("//third_party/rules_boost:rules_boost_step_1.bzl", "rules_boost_step_1") 4 | 5 | def _non_module_dependencies_step_1_impl(_ctx): 6 | pcpp() 7 | rules_boost_step_1() 8 | boost_wave() 9 | 10 | non_module_dependencies_step_1 = module_extension( 11 | implementation = _non_module_dependencies_step_1_impl, 12 | ) 13 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_recursive = dwyu_aspect_factory(recursive = True) 4 | dwyu_recursive_impl_deps = dwyu_aspect_factory(recursive = True, use_implementation_deps = True) 5 | 6 | dwyu_recursive_cpp = dwyu_aspect_factory(recursive = True, use_cpp_implementation = True) 7 | dwyu_recursive_impl_deps_cpp = dwyu_aspect_factory(recursive = True, use_implementation_deps = True, use_cpp_implementation = True) 8 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/classic/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "test_toolchain_classic") 2 | 3 | # We specify by design outdated versions. 4 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 5 | # Specifying an ancient version here gives us in the end the version used by the root module which uses this 6 | # sub module for test purposes. 7 | bazel_dep(name = "rules_cc", version = "0.0.1") 8 | bazel_dep(name = "bazel_skylib", version = "1.0.3") 9 | -------------------------------------------------------------------------------- /test/aspect/platforms/test_ignore_incompatible_platforms.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//platforms:all", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/alias/test_use_dependency_through_alias.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//alias:use_a_directly", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | load(":custom_ignored_headers.bzl", "custom_cc_toolchain_headers_info") 3 | 4 | custom_cc_toolchain_headers_info( 5 | name = "custom_cc_toolchain_headers_info", 6 | ) 7 | 8 | cc_library( 9 | name = "use_toolchain_header", 10 | hdrs = ["use_toolchain_header.h"], 11 | ) 12 | 13 | cc_library( 14 | name = "use_custom_toolchain_header", 15 | hdrs = ["use_custom_toolchain_header.h"], 16 | ) 17 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/test_relative_includes.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//relative_includes:all", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/test_dwyu_rule.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_bazel_build(target=self.choose_target("//rule_using_aspect:dwyu_direct_main")) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/test_skip_no_dwyu_tag.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//skip_tags:ignored_by_default_behavior", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/shared_library/test_shared_library_without_srcs.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//shared_library:libfoo.so", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | # Analysis of this can only succeed when ignoring preprocessing, as otherwise one dependency would be unused 4 | cc_library( 5 | name = "use_libs", 6 | hdrs = ["use_libs.h"], 7 | deps = [ 8 | ":lib_a", 9 | ":lib_b", 10 | ], 11 | ) 12 | 13 | cc_library( 14 | name = "lib_a", 15 | hdrs = ["lib_a.h"], 16 | ) 17 | 18 | cc_library( 19 | name = "lib_b", 20 | hdrs = ["lib_b.h"], 21 | ) 22 | -------------------------------------------------------------------------------- /test/aspect/relative_includes/some/sub/dir/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef FOO_H 2 | #define FOO_H 3 | 4 | // normal relative include to file in same directory 5 | #include "bar.h" 6 | // Enter parent directory and descend again into current directory 7 | #include "../dir/bar.h" 8 | // Relative include to a file in another directory 9 | #include "../dir2/baz.h" 10 | // Example for complex relative path 11 | #include "../../sub/dir2/../dir/bar.h" 12 | 13 | inline int doFoo() { 14 | return doBar() + doBaz(); 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /test/aspect/tree_artifact/test_use_tree_artifact_correctly.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//tree_artifact:use_tree_artifact", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/test_correctly_process_virtual_includes.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//virtual_includes:all", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/command_length_limit/test_command_length_limit.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu(target="//command_length_limit:many_defines", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /dwyu/cc_info_mapping/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | 3 | bzl_library( 4 | name = "cc_info_mapping", 5 | srcs = [ 6 | "cc_info_mapping.bzl", 7 | "providers.bzl", 8 | ], 9 | visibility = ["//visibility:public"], 10 | deps = [ 11 | "//dwyu/cc_info_mapping/private:cc_info_mapping_impl_bzl", 12 | "//dwyu/private:utils_bzl", 13 | ], 14 | ) 15 | 16 | exports_files( 17 | ["cc_info_mapping.bzl"], 18 | visibility = ["//docs:__pkg__"], 19 | ) 20 | -------------------------------------------------------------------------------- /dwyu/private/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "dwyu/private/utils.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace dwyu { 7 | 8 | std::string listToStr(const std::vector& list) { 9 | std::string out{"["}; 10 | for (const auto& element : list) { 11 | out += element + ", "; 12 | } 13 | if (out.size() > 1) { 14 | out.pop_back(); 15 | out.back() = ']'; 16 | } 17 | else { 18 | out += "]"; 19 | } 20 | return out; 21 | } 22 | 23 | } // namespace dwyu 24 | -------------------------------------------------------------------------------- /test/aspect/tree_artifact/README.md: -------------------------------------------------------------------------------- 1 | A `TreeArtifact` is a special output of rules where one does not know beforehand how many output files will be generated. 2 | Code generators are a common use case relying on this construct. 3 | In other words, a `TreeArtifact` is a predeclared directory with unknown content. 4 | The content will not be available until the execution phase. 5 | Essentially, this makes it impossible to analyze a `TreeArtifact` in StarLark and requires doing so inside an action which is performed in the execution phase. 6 | -------------------------------------------------------------------------------- /examples/define_macros/main.cpp: -------------------------------------------------------------------------------- 1 | #include "define_macros/lib.h" 2 | 3 | // If FOO is not defined, this will fail the DWYU analysis due to using the header from a transitive dependency 4 | #ifndef FOO 5 | #include "define_macros/transitive_dep_a.h" 6 | #endif 7 | 8 | // If the C++ standard is not known, this will fail the DWYU analysis due to using the header from a transitive 9 | // dependency 10 | #if __cplusplus < 199711 11 | #include "define_macros/transitive_dep_b.h" 12 | #endif 13 | 14 | int main() { 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/test_detect_unused_dep.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//unused_dep:foo"]) 10 | actual = self._run_dwyu(target="//unused_dep:main", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /test/aspect/alias/test_unused_dependency_through_alias.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//alias:lib_a"]) 10 | actual = self._run_dwyu(target="//alias:unused_dependency", aspect=self.default_aspect) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /third_party/bzip2/repository.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 3 | 4 | def bzip2(): 5 | maybe( 6 | http_archive, 7 | name = "bzip2", 8 | sha256 = "ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269", 9 | strip_prefix = "bzip2-1.0.8", 10 | urls = ["https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz"], 11 | patches = [Label("//third_party/bzip2:bazelization.patch")], 12 | ) 13 | -------------------------------------------------------------------------------- /third_party/pcpp/recursion_fix.patch: -------------------------------------------------------------------------------- 1 | --- pcpp/preprocessor.py 2 | +++ pcpp/preprocessor.py 3 | @@ -558,6 +558,8 @@ class Preprocessor(PreprocessorHooks): 4 | for tok in tokens: 5 | if not hasattr(tok, 'expanded_from'): 6 | tok.expanded_from = [] 7 | + if len(expanding_from) == 1 and tok.value == expanding_from[0]: 8 | + return tokens 9 | i = 0 10 | #print("*** EXPAND MACROS in", "".join([t.value for t in tokens]), "expanding_from=", expanding_from) 11 | #print(tokens) 12 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/workspace/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "lib", 6 | hdrs = ["lib.h"], 7 | visibility = [":__subpackages__"], 8 | ) 9 | 10 | cc_binary( 11 | name = "binary", 12 | srcs = ["binary.cpp"], 13 | deps = [ 14 | ":lib", # unused 15 | ], 16 | ) 17 | 18 | cc_binary( 19 | name = "another_binary", 20 | srcs = ["binary.cpp"], 21 | deps = [ 22 | ":lib", # unused 23 | ], 24 | ) 25 | -------------------------------------------------------------------------------- /test/aspect/defines/include_using_pre_processor_token.h: -------------------------------------------------------------------------------- 1 | #define HEADER_PATH_A "defines/support/some_defines.h" 2 | 3 | #include HEADER_PATH_A 4 | 5 | // Ensure the 'some_define.h' header was included and parsed correctly by using some of its content 6 | #if SOME_SWITCH_VALUE > 100 7 | #include "defines/support/a.h" 8 | #endif 9 | 10 | #include CONDITIONAL_DEFINES_HEADER 11 | 12 | // Ensure the 'conditional_defines.h' header was included and parsed correctly by using some of its content 13 | #if SOME_VALUE > 40 14 | #include "defines/support/b.h" 15 | #endif 16 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_binary( 5 | name = "use_lib_b", 6 | srcs = ["use_lib_b.cpp"], 7 | deps = ["//target_mapping/libs:a"], 8 | ) 9 | 10 | cc_binary( 11 | name = "use_lib_c", 12 | srcs = ["use_lib_c.cpp"], 13 | deps = ["//target_mapping/libs:a"], 14 | ) 15 | 16 | cc_library( 17 | name = "use_lib_b_privately", 18 | srcs = ["use_lib_b.cpp"], 19 | implementation_deps = ["//target_mapping/libs:a"], 20 | ) 21 | -------------------------------------------------------------------------------- /third_party/zlib/repository.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 3 | 4 | def zlib(): 5 | maybe( 6 | http_archive, 7 | name = "zlib", 8 | sha256 = "9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23", 9 | strip_prefix = "zlib-1.3.1", 10 | urls = ["https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz"], 11 | patches = [Label("//third_party/zlib:bazelization.patch")], 12 | ) 13 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/test_recursive_dwyu_rule.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//rule_using_aspect:c"]) 10 | actual = self._run_bazel_build(target=self.choose_target("//rule_using_aspect:dwyu_recursive_main")) 11 | 12 | return self._check_result(actual=actual, expected=expected) 13 | -------------------------------------------------------------------------------- /third_party/zstd/repository.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 3 | 4 | def zstd(): 5 | maybe( 6 | http_archive, 7 | name = "zstd", 8 | sha256 = "9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4", 9 | strip_prefix = "zstd-1.5.5", 10 | urls = ["https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-1.5.5.tar.gz"], 11 | patches = [Label("//third_party/zstd:bazelization.patch")], 12 | ) 13 | -------------------------------------------------------------------------------- /dwyu/apply_fixes/utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | import shlex 5 | import subprocess 6 | from pathlib import Path 7 | 8 | log = logging.getLogger() 9 | 10 | 11 | def args_string_to_list(args: str | None) -> list[str]: 12 | return shlex.split(args) if args else [] 13 | 14 | 15 | def execute_and_capture(cmd: list[str], cwd: Path, check: bool = True) -> subprocess.CompletedProcess: 16 | log.debug(f"Executing command: {shlex.join(cmd)}") 17 | return subprocess.run(cmd, cwd=cwd, check=check, capture_output=True, text=True) 18 | -------------------------------------------------------------------------------- /test/aspect/REAME.md: -------------------------------------------------------------------------------- 1 | This directory contains the integration tests for the DWYU aspect. 2 | 3 | The tests are executed with various supported Bazel versions. 4 | [bazelisk](https://github.com/bazelbuild/bazelisk) has to be available on `PATH`. 5 | 6 | The test cases and their expected behavior are defined in [execute_tests.py](execute_tests.py). 7 | 8 | Execute all tests with various Bazel versions:
9 | `./execute_tests.py` 10 | 11 | You can execute specific test cases or use specific Bazel versions. For details see the help:
12 | `./execute_tests.py --help` 13 | -------------------------------------------------------------------------------- /test/aspect/set_cpp_standard/test_set_cplusplus.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//set_cpp_standard:all", aspect=self.choose_aspect("//set_cpp_standard:aspect.bzl%set_cplusplus") 12 | ) 13 | 14 | return self._check_result(actual=actual, expected=expected) 15 | -------------------------------------------------------------------------------- /defs.bzl: -------------------------------------------------------------------------------- 1 | """ 2 | Public symbols available to DWYU users. 3 | """ 4 | 5 | load("//dwyu/aspect:factory.bzl", _dwyu_aspect_factory = "dwyu_aspect_factory") 6 | load( 7 | "//dwyu/cc_info_mapping:cc_info_mapping.bzl", 8 | _MAP_DIRECT_DEPS = "MAP_DIRECT_DEPS", 9 | _MAP_TRANSITIVE_DEPS = "MAP_TRANSITIVE_DEPS", 10 | _dwyu_make_cc_info_mapping = "dwyu_make_cc_info_mapping", 11 | ) 12 | 13 | dwyu_aspect_factory = _dwyu_aspect_factory 14 | 15 | dwyu_make_cc_info_mapping = _dwyu_make_cc_info_mapping 16 | MAP_DIRECT_DEPS = _MAP_DIRECT_DEPS 17 | MAP_TRANSITIVE_DEPS = _MAP_TRANSITIVE_DEPS 18 | -------------------------------------------------------------------------------- /examples/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "dwyu_examples") 2 | 3 | local_repository( 4 | name = "depend_on_what_you_use", 5 | path = "../", 6 | ) 7 | 8 | load("@depend_on_what_you_use//:setup_step_1.bzl", "setup_step_1") 9 | 10 | setup_step_1() 11 | 12 | load("@depend_on_what_you_use//:setup_step_2.bzl", "setup_step_2") 13 | 14 | setup_step_2() 15 | 16 | ## 17 | ## One can use DWYU without the content below. We simply need some further things so all examples work. 18 | ## 19 | 20 | load("//:support/external_targets.bzl", "load_external_targets") 21 | 22 | load_external_targets() 23 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/test_skip_custom_tag.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//skip_tags:ignored_by_custom_tag", 12 | aspect=self.choose_aspect("//skip_tags:aspect.bzl%dwyu_custom_tags"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "foo", 6 | hdrs = ["foo.h"], 7 | ) 8 | 9 | cc_library( 10 | name = "bar", 11 | hdrs = ["bar.h"], 12 | deps = [":foo"], 13 | ) 14 | 15 | cc_binary( 16 | name = "main", 17 | srcs = ["main.cpp"], 18 | deps = [":bar"], 19 | ) 20 | 21 | cc_library( 22 | name = "transitive_usage_through_impl_deps", 23 | srcs = ["transitive_usage_through_impl_deps.h"], 24 | deps = [":bar"], 25 | ) 26 | -------------------------------------------------------------------------------- /third_party/xz/repository.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 3 | 4 | def xz(): 5 | maybe( 6 | http_archive, 7 | name = "xz", 8 | sha256 = "135c90b934aee8fbc0d467de87a05cb70d627da36abe518c357a873709e5b7d6", 9 | strip_prefix = "xz-5.4.5", 10 | urls = ["https://github.com/tukaani-project/xz/releases/download/v5.4.5/xz-5.4.5.tar.gz"], 11 | patches = [Label("//third_party/xz:bazelization.patch")], 12 | patch_args = ["-p1"], 13 | ) 14 | -------------------------------------------------------------------------------- /dwyu/aspect/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | 3 | bzl_library( 4 | name = "factory", 5 | srcs = [ 6 | "dwyu.bzl", 7 | "factory.bzl", 8 | ], 9 | visibility = ["//visibility:public"], 10 | deps = [ 11 | "//dwyu/cc_info_mapping", 12 | "//dwyu/cc_toolchain_headers", 13 | "@rules_cc//cc:action_names_bzl", 14 | "@rules_cc//cc:find_cc_toolchain_bzl", 15 | "@rules_cc//cc/common", 16 | ], 17 | ) 18 | 19 | exports_files( 20 | ["factory.bzl"], 21 | visibility = ["//docs:__pkg__"], 22 | ) 23 | -------------------------------------------------------------------------------- /dwyu/aspect/private/process_target/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_python//python:py_binary.bzl", "py_binary") 3 | 4 | cc_binary( 5 | name = "main_cc", 6 | srcs = ["main.cpp"], 7 | visibility = ["//visibility:public"], 8 | deps = [ 9 | "//dwyu/private:program_options", 10 | "//dwyu/private:utils", 11 | "@nlohmann_json//:singleheader-json", 12 | ], 13 | ) 14 | 15 | py_binary( 16 | name = "main_py", 17 | srcs = ["main.py"], 18 | main = "main.py", 19 | visibility = ["//visibility:public"], 20 | ) 21 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/test/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:defs.bzl", "py_test") 2 | load(":gather_cc_toolchain_headers_test.bzl", "gather_cc_toolchain_headers_test_suite") 3 | 4 | py_test( 5 | name = "gather_cc_toolchain_headers_tool_test", 6 | srcs = ["gather_cc_toolchain_headers_test.py"], 7 | data = glob(["data/**/*"]), 8 | main = "gather_cc_toolchain_headers_test.py", 9 | deps = ["//dwyu/cc_toolchain_headers/private:gather_cc_toolchain_headers_tool"], 10 | ) 11 | 12 | gather_cc_toolchain_headers_test_suite(name = "gather_cc_toolchain_headers_rule_test") 13 | -------------------------------------------------------------------------------- /test/aspect/version.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | 4 | @dataclass 5 | class TestedVersions: 6 | bazel: str 7 | python: str 8 | is_default: bool = False 9 | 10 | 11 | @dataclass 12 | class CompatibleVersions: 13 | minimum: str = "" 14 | before: str = "" 15 | 16 | def is_compatible_to(self, version: str) -> bool: 17 | comply_with_min_version = version >= self.minimum if self.minimum else True 18 | comply_with_max_version = version < self.before if self.before else True 19 | return comply_with_min_version and comply_with_max_version 20 | -------------------------------------------------------------------------------- /test/aspect/no_preprocessor/test_no_preprocessor.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//no_preprocessor:use_libs", 12 | aspect=self.choose_aspect("//no_preprocessor:aspect.bzl%dwyu_no_preprocessor"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/recursion/test_find_transitive_problem_via_deps.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//recursion:e"]) 10 | actual = self._run_dwyu( 11 | target="//recursion:main", aspect=self.choose_aspect("//recursion:aspect.bzl%dwyu_recursive") 12 | ) 13 | 14 | return self._check_result(actual=actual, expected=expected) 15 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_b_with_direct_deps_mapping.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//target_mapping:use_lib_b", 12 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_direct_deps"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_b_with_specific_mapping.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//target_mapping:use_lib_b", 12 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_specific_deps"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /examples/define_macros/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_binary( 5 | name = "main", 6 | srcs = ["main.cpp"], 7 | deps = ["lib"], 8 | ) 9 | 10 | cc_library( 11 | name = "lib", 12 | hdrs = ["lib.h"], 13 | deps = [ 14 | ":transitive_dep_a", 15 | ":transitive_dep_b", 16 | ], 17 | ) 18 | 19 | cc_library( 20 | name = "transitive_dep_a", 21 | hdrs = ["transitive_dep_a.h"], 22 | ) 23 | 24 | cc_library( 25 | name = "transitive_dep_b", 26 | hdrs = ["transitive_dep_b.h"], 27 | ) 28 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_b_with_transitive_deps_mapping.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//target_mapping:use_lib_b", 12 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_transitive_deps"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_c_with_transitive_deps_mapping.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//target_mapping:use_lib_c", 12 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_transitive_deps"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/benchmark/MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "dwyu_benchmarks") 2 | 3 | bazel_dep(name = "depend_on_what_you_use") 4 | local_path_override( 5 | module_name = "depend_on_what_you_use", 6 | path = "../../", 7 | ) 8 | 9 | bazel_dep(name = "googletest", version = "1.17.0") 10 | 11 | # We specify by design an outdated rules_cc version. 12 | # bzlmod resolves dependencies to the maximum of all requested versions for all involved modules. 13 | # Specifying an ancient version here gives us in the end at least whatever rules_cc version DWYU defines as dependency. 14 | bazel_dep(name = "rules_cc", version = "0.0.1") 15 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/commented_includes/block_comments.h: -------------------------------------------------------------------------------- 1 | /* #include "commented.h" */ 2 | 3 | /* 4 | #include "commented.h" 5 | #include "commented.h" 6 | */ #include "active_a.h" 7 | 8 | /* some text */ #include "active_b.h" 9 | 10 | /* #include "commented.h" */ /**/ /**/ #include "active_c.h" 11 | 12 | /*/* #include "commented.h" */ #include "active_d.h" 13 | 14 | /* 15 | /* 16 | /* 17 | */ 18 | #include "active_e.h" 19 | 20 | #include "active_f.h" /* commented */ 21 | 22 | /* some text */#include /* some other text */ 23 | 24 | #include "active_h.h" /* #include "inactive_h.h" */ 25 | -------------------------------------------------------------------------------- /test/support/result.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Result(ABC): 5 | def __init__(self, error: str = "") -> None: 6 | self.error = error 7 | 8 | @abstractmethod 9 | def is_success(self) -> bool: 10 | pass 11 | 12 | 13 | class Error(Result): 14 | def __init__(self, error: str) -> None: 15 | super().__init__(error) 16 | 17 | def is_success(self) -> bool: 18 | return False 19 | 20 | 21 | class Success(Result): 22 | def __init__(self) -> None: 23 | super().__init__() 24 | 25 | def is_success(self) -> bool: 26 | return True 27 | -------------------------------------------------------------------------------- /test/aspect/generated_code/test_generated_code.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | """ 10 | Show that the aspect properly processes generated code which lives only in the bazel output tree. 11 | """ 12 | expected = ExpectedResult(success=True) 13 | actual = self._run_dwyu(target="//generated_code:foo", aspect=self.default_aspect) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/test_ignore_include_patterns.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//ignore_includes:use_ignored_patterns", 12 | aspect=self.choose_aspect("//ignore_includes:aspect.bzl%extra_ignore_include_patterns_aspect"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/test_custom_ignore_include_paths.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//ignore_includes:use_multiple_ignored_headers", 12 | aspect=self.choose_aspect("//ignore_includes:aspect.bzl%ignore_include_paths_aspect"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/custom_ignored_headers.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//dwyu/cc_toolchain_headers:providers.bzl", "DwyuCcToolchainHeadersInfo") 2 | 3 | def _custom_cc_toolchain_headers_info_impl(ctx): 4 | return DwyuCcToolchainHeadersInfo(headers_info = ctx.file._info) 5 | 6 | custom_cc_toolchain_headers_info = rule( 7 | implementation = _custom_cc_toolchain_headers_info_impl, 8 | provides = [DwyuCcToolchainHeadersInfo], 9 | attrs = {"_info": attr.label( 10 | allow_single_file = True, 11 | default = Label("//ignore_toolchain_headers:custom_ignored_headers.json"), 12 | )}, 13 | ) 14 | -------------------------------------------------------------------------------- /test/apply_fixes/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the integration tests for the automatic fixing tool. 2 | 3 | Each `test_*.py` file represents a test case. The `execute_test.py` is the entry point for the test suite. 4 | 5 | For each test case the workspace template is copied into a temporary directory in which then DWYU is executed to detect 6 | a problem. Afterwards, the `//:apply_fixes` tool is executed and the adapted `BUILD` files are analyzed to check if the 7 | expected change happened.
8 | This approach based on a temporary workspace is chosen to make sure cleaning up the test side effects is not 9 | messing with the source code. 10 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/test_extra_ignore_include_paths.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//ignore_includes:use_ignored_header_and_std_lib", 12 | aspect=self.choose_aspect("//ignore_includes:aspect.bzl%extra_ignore_include_paths_aspect"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /test/aspect/platforms/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "linux", 6 | srcs = ["linux.cpp"], 7 | target_compatible_with = ["@platforms//os:linux"], 8 | ) 9 | 10 | cc_library( 11 | name = "windows", 12 | srcs = ["windows.cpp"], 13 | target_compatible_with = ["@platforms//os:windows"], 14 | ) 15 | 16 | cc_binary( 17 | name = "use_linux", 18 | srcs = ["main.cpp"], 19 | deps = [":linux"], 20 | ) 21 | 22 | cc_binary( 23 | name = "use_windows", 24 | srcs = ["main.cpp"], 25 | deps = [":windows"], 26 | ) 27 | -------------------------------------------------------------------------------- /examples/rule_using_dwyu/rule.bzl: -------------------------------------------------------------------------------- 1 | load("//:aspect.bzl", "dwyu") 2 | 3 | def _dwyu_rule_impl(ctx): 4 | # gather artifacts to make sure the DWYU aspect is executed 5 | dwyu_artifacts = depset(transitive = [dep[OutputGroupInfo].dwyu for dep in ctx.attr.deps]) 6 | return [DefaultInfo(files = dwyu_artifacts)] 7 | 8 | dwyu_rule = rule( 9 | implementation = _dwyu_rule_impl, 10 | attrs = { 11 | # You can control what this rule does (e.g. recursive vs. non recursive analysis) by specifying a DWYU aspect 12 | # which is configured in the desired way here. 13 | "deps": attr.label_list(aspects = [dwyu]), 14 | }, 15 | ) 16 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/tools/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool") 2 | load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map") 3 | 4 | cc_tool( 5 | name = "fake_gcc", 6 | src = "//:gcc_binary", 7 | data = [ 8 | "//data:fizz", 9 | "//data:fizz_buzz", 10 | "//data:foobar", 11 | ], 12 | ) 13 | 14 | cc_tool_map( 15 | name = "compiler_tools", 16 | tools = { 17 | "@rules_cc//cc/toolchains/actions:c_compile": ":fake_gcc", 18 | "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":fake_gcc", 19 | }, 20 | visibility = ["//:__pkg__"], 21 | ) 22 | -------------------------------------------------------------------------------- /setup_step_2.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//lib:versions.bzl", "versions") 2 | load("@rules_python//python:repositories.bzl", "py_repositories") 3 | load("//third_party/rules_boost:rules_boost_step_2.bzl", "rules_boost_step_2") 4 | 5 | def setup_step_2(): 6 | """ 7 | Perform the second setup step. 8 | """ 9 | 10 | # Fail early for incompatible Bazel versions instead of printing obscure errors from within our implementation 11 | versions.check( 12 | # Keep in sync with MODULE.bazel, .bcr/presubmit.yml and the README.md 13 | minimum_bazel_version = "7.2.1", 14 | ) 15 | 16 | py_repositories() 17 | 18 | rules_boost_step_2() 19 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "foo", 6 | hdrs = ["foo.h"], 7 | ) 8 | 9 | cc_library( 10 | name = "bar", 11 | hdrs = ["bar.h"], 12 | ) 13 | 14 | cc_binary( 15 | name = "main", 16 | srcs = ["main.cpp"], 17 | deps = [ 18 | ":bar", 19 | ":foo", # unused dependency 20 | ], 21 | ) 22 | 23 | cc_library( 24 | name = "implementation_deps_lib", 25 | srcs = ["main.cpp"], 26 | implementation_deps = [ 27 | ":bar", 28 | ":foo", # unused dependency 29 | ], 30 | ) 31 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/ext_repo/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "complex_includes", 5 | srcs = ["complex_includes.cpp"], 6 | hdrs = [ 7 | "some/dir/complex_include_a.h", 8 | "some/dir/complex_include_b.h", 9 | ], 10 | include_prefix = "virtual/prefix", 11 | includes = ["some"], 12 | strip_include_prefix = "some", 13 | visibility = ["//visibility:public"], 14 | ) 15 | 16 | cc_library( 17 | name = "use_complex_includes", 18 | srcs = ["use_complex_includes.cpp"], 19 | visibility = ["//visibility:public"], 20 | deps = [":complex_includes"], 21 | ) 22 | -------------------------------------------------------------------------------- /test/aspect/alias/test_invalid_dependency_through_alias.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from expected_result import ExpectedResult 4 | from test_case import TestCaseBase 5 | 6 | from test.support.result import Result 7 | 8 | 9 | class TestCase(TestCaseBase): 10 | def execute_test_logic(self) -> Result: 11 | expected = ExpectedResult( 12 | success=False, 13 | invalid_includes=[f"File='{Path('alias/use_a_and_b.cpp')}', include='alias/a.h'"], 14 | ) 15 | actual = self._run_dwyu(target="//alias:use_a_transitively", aspect=self.default_aspect) 16 | 17 | return self._check_result(actual=actual, expected=expected) 18 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/test_custom_toolchain_headers_info.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//ignore_toolchain_headers:use_custom_toolchain_header", 12 | aspect=self.choose_aspect("//ignore_toolchain_headers:aspect.bzl%dwyu_custom_toolchain_headers_info"), 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /dwyu/apply_fixes/test/utils_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from dwyu.apply_fixes.utils import args_string_to_list 4 | 5 | 6 | class TestArgsStringToList(unittest.TestCase): 7 | def test_no_args(self) -> None: 8 | self.assertEqual(args_string_to_list(None), []) 9 | self.assertEqual(args_string_to_list(""), []) 10 | 11 | def test_single_arg(self) -> None: 12 | self.assertEqual(args_string_to_list("foo"), ["foo"]) 13 | 14 | def test_multiple_args(self) -> None: 15 | self.assertEqual(args_string_to_list("--foo --bar=42 baz 1337"), ["--foo", "--bar=42", "baz", "1337"]) 16 | 17 | 18 | if __name__ == "__main__": 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /dwyu/private/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | bzl_library( 5 | name = "utils_bzl", 6 | srcs = [ 7 | "utils.bzl", 8 | ], 9 | visibility = ["//dwyu:__subpackages__"], 10 | ) 11 | 12 | cc_library( 13 | name = "program_options", 14 | srcs = ["program_options.cpp"], 15 | hdrs = ["program_options.h"], 16 | implementation_deps = [":utils"], 17 | visibility = ["//dwyu:__subpackages__"], 18 | ) 19 | 20 | cc_library( 21 | name = "utils", 22 | srcs = ["utils.cpp"], 23 | hdrs = ["utils.h"], 24 | visibility = ["//dwyu:__subpackages__"], 25 | ) 26 | -------------------------------------------------------------------------------- /test/aspect/unused_dep/test_detect_unused_impl_dep.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_private_deps=["//unused_dep:foo"]) 10 | actual = self._run_dwyu( 11 | target="//unused_dep:implementation_deps_lib", 12 | aspect=self.default_aspect_impl_deps, 13 | extra_args=["--experimental_cc_implementation_deps"], 14 | ) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /test/aspect/rule_using_aspect/test_recursive_dwyu_rule_with_impl_deps.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//rule_using_aspect:c"]) 10 | actual = self._run_bazel_build( 11 | target=self.choose_target("//rule_using_aspect:dwyu_recursive_with_impl_deps"), 12 | extra_args=["--experimental_cc_implementation_deps"], 13 | ) 14 | 15 | return self._check_result(actual=actual, expected=expected) 16 | -------------------------------------------------------------------------------- /dwyu/private/test/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_test.bzl", "cc_test") 2 | load(":utils_test.bzl", "utils_test_suite") 3 | 4 | utils_test_suite(name = "utils_test") 5 | 6 | cc_test( 7 | name = "program_options_test", 8 | srcs = ["program_options_test.cpp"], 9 | data = ["data/multiple_options.txt"], 10 | deps = [ 11 | "//dwyu/private:program_options", 12 | "@googletest//:gtest", 13 | "@googletest//:gtest_main", 14 | ], 15 | ) 16 | 17 | cc_test( 18 | name = "utils_cc_test", 19 | srcs = ["utils_test.cpp"], 20 | deps = [ 21 | "//dwyu/private:utils", 22 | "@googletest//:gtest", 23 | "@googletest//:gtest_main", 24 | ], 25 | ) 26 | -------------------------------------------------------------------------------- /test/aspect/skip_tags/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "unused_lib", 5 | hdrs = ["foo.h"], 6 | ) 7 | 8 | # Inspection this with the default configuration should not fail 9 | cc_library( 10 | name = "ignored_by_default_behavior", 11 | hdrs = ["bar.h"], 12 | tags = ["no-dwyu"], 13 | deps = [":unused_lib"], 14 | ) 15 | 16 | # Inspection this should not fail with aspect configured to skip 'tag_marking_skipping' tags 17 | cc_library( 18 | name = "ignored_by_custom_tag", 19 | hdrs = ["bar.h"], 20 | tags = [ 21 | "some_tag", 22 | "tag_marking_skipping", 23 | ], 24 | deps = [":unused_lib"], 25 | ) 26 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_b_via_impl_deps_with_specific_mapping.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=True) 10 | actual = self._run_dwyu( 11 | target="//target_mapping:use_lib_b_privately", 12 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_specific_deps"), 13 | extra_args=["--experimental_cc_implementation_deps"], 14 | ) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /dwyu/aspect/private/preprocessing/test/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_test.bzl", "cc_test") 2 | 3 | cc_test( 4 | name = "extract_includes_test", 5 | srcs = ["extract_includes_test.cpp"], 6 | data = ["data/commented_includes.h"], 7 | deps = [ 8 | "//dwyu/aspect/private/preprocessing:extract_includes", 9 | "@googletest//:gtest", 10 | "@googletest//:gtest_main", 11 | ], 12 | ) 13 | 14 | cc_test( 15 | name = "preprocessing_hooks_test", 16 | srcs = ["preprocessing_hooks_test.cpp"], 17 | deps = [ 18 | "//dwyu/aspect/private/preprocessing:preprocessing_hooks", 19 | "@googletest//:gtest", 20 | "@googletest//:gtest_main", 21 | ], 22 | ) 23 | -------------------------------------------------------------------------------- /test/aspect/using_transitive_dep/test_detect_using_transitive_dep.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from expected_result import ExpectedResult 4 | from test_case import TestCaseBase 5 | 6 | from test.support.result import Result 7 | 8 | 9 | class TestCase(TestCaseBase): 10 | def execute_test_logic(self) -> Result: 11 | expected = ExpectedResult( 12 | success=False, 13 | invalid_includes=[f"File='{Path('using_transitive_dep/main.cpp')}', include='using_transitive_dep/foo.h'"], 14 | ) 15 | actual = self._run_dwyu(target="//using_transitive_dep:main", aspect=self.default_aspect) 16 | 17 | return self._check_result(actual=actual, expected=expected) 18 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/data/header_with_defines.h: -------------------------------------------------------------------------------- 1 | #define INTERNAL 2 | 3 | #ifdef INTERNAL 4 | #include "has_internal.h" 5 | #else 6 | #include "no_internal.h" 7 | #endif 8 | 9 | #ifdef FOO 10 | #include "has_foo.h" 11 | #else 12 | #include "no_foo.h" 13 | #endif 14 | 15 | /* 16 | #ifdef FOO 17 | #include "should_never_be_active_due_to_being_commented" 18 | #else 19 | #include "should_never_be_active_due_to_being_commented" 20 | #endif 21 | */ 22 | 23 | #ifndef BAR 24 | #include "no_bar.h" 25 | #else 26 | #include "has_bar.h" 27 | #endif 28 | 29 | #if BAZ > 40 30 | #include "baz_greater_40.h" 31 | #elif BAZ > 10 32 | #include "baz_greater_10.h" 33 | #else 34 | #include "no_baz.h" 35 | #endif 36 | -------------------------------------------------------------------------------- /examples/basic_usage/README.md: -------------------------------------------------------------------------------- 1 | Basic example showing correct and wrong dependency management and how DWYU reacts to those. 2 | 3 | Executing DWYU on the correct target succeeds: 4 | 5 | ```shell 6 | bazel build --config=dwyu //basic_usage:correct_dependencies 7 | ``` 8 | 9 | Executing DWYU on the target with faulty dependency management yields a failed build and an error message outlining the two problems of this target: 10 | 11 | ```shell 12 | bazel build --config=dwyu //basic_usage:false_dependencies 13 | ``` 14 | 15 | DWYU can also report that the target under inspection is depending on something, it is not even using: 16 | 17 | ```shell 18 | bazel build --config=dwyu //basic_usage:not_using_lib 19 | ``` 20 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/workspace/configured_lib/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | bool_flag( 5 | name = "custom_config", 6 | build_setting_default = False, 7 | ) 8 | 9 | config_setting( 10 | name = "custom_config_active", 11 | flag_values = {":custom_config": "True"}, 12 | ) 13 | 14 | cc_library( 15 | name = "configured_deps", 16 | hdrs = ["configured_deps.h"], 17 | visibility = ["//visibility:public"], 18 | deps = select({ 19 | ":custom_config_active": ["//ambiguous_lib:lib_a"], 20 | "//conditions:default": ["//ambiguous_lib:lib_b"], 21 | }), 22 | ) 23 | -------------------------------------------------------------------------------- /test/aspect/defines/transitive_defines_from_bazel_target.h: -------------------------------------------------------------------------------- 1 | // Define introduced through target on which we depend. The target uses the attribute 'defines' which is propagated to 2 | // all users of the target. 3 | #ifdef TRANSITIVE_DEFINE 4 | #include "defines/support/a.h" 5 | #else 6 | #include "non/existing/a.h" 7 | #endif 8 | 9 | #include "defines/support/a.h" 10 | #include 11 | 12 | // The following defines shall never be active as they are set though Bazel target attributes 'copts' and 13 | // 'local_defines' which should not leak to users of the target 14 | 15 | #ifdef LOCAL_DEFINE 16 | #include "non/existing/b.h" 17 | #endif 18 | 19 | #ifdef LOCAL_COPT 20 | #include "non/existing/c.h" 21 | #endif 22 | -------------------------------------------------------------------------------- /dwyu/aspect/private/preprocessing/test/data/commented_includes.h: -------------------------------------------------------------------------------- 1 | // #include "commented.h" 2 | // #include 3 | #include "include_a.h" 4 | #include "include_b.h" // 5 | 6 | void Foo(); // #include "commented.h" 7 | 8 | /* #include "commented.h" */ 9 | /* 10 | #include "commented.h" 11 | #include "commented.h" 12 | */ 13 | #include "include_c.h" 14 | 15 | /* #include "commented.h" */ /**/ /**/ #include "include_d.h" 16 | 17 | /*/* #include "commented.h" */ #include "include_e.h" /* #include "commented.h" */ 18 | 19 | /* 20 | /* 21 | */ 22 | #include "include_f.h" 23 | 24 | /* */ // #include "commented.h" 25 | /* // #include "commented.h" */ 26 | // */ */ #include "commented.h" 27 | #include "include_g.h" 28 | -------------------------------------------------------------------------------- /test/apply_fixes/needlessly_public_dependency/workspace/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "lib_a", 5 | hdrs = ["lib_a.h"], 6 | ) 7 | 8 | cc_library( 9 | name = "lib_b", 10 | hdrs = ["lib_b.h"], 11 | ) 12 | 13 | cc_library( 14 | name = "lib_c", 15 | hdrs = ["lib_c.h"], 16 | deps = [ 17 | ":lib_a", 18 | ":lib_b", 19 | ], 20 | ) 21 | 22 | cc_library( 23 | name = "public_dependency_with_private_use", 24 | srcs = ["using_a_and_b.cpp"], 25 | hdrs = ["using_c.h"], 26 | deps = [ 27 | ":lib_a", # only used privately 28 | ":lib_b", # only used privately 29 | ":lib_c", 30 | ], 31 | ) 32 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/test_dry_run_performs_no_change.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:binary" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-unused", "--dry-run"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:lib"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /test/aspect/recursion/test_find_transitive_problem_via_iml_deps.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, unused_public_deps=["//recursion:e"]) 10 | actual = self._run_dwyu( 11 | target="//recursion:use_impl_deps", 12 | aspect=self.choose_aspect("//recursion:aspect.bzl%dwyu_recursive_impl_deps"), 13 | extra_args=["--experimental_cc_implementation_deps"], 14 | ) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/test_superfluous_public_dep.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | expected = ExpectedResult(success=False, deps_which_should_be_private=["//implementation_deps/support:lib_b"]) 10 | actual = self._run_dwyu( 11 | target="//implementation_deps:superfluous_public_dep", 12 | aspect=self.default_aspect_impl_deps, 13 | extra_args=["--experimental_cc_implementation_deps"], 14 | ) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /test/aspect/virtual_includes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_binary.bzl", "cc_binary") 2 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 3 | 4 | cc_library( 5 | name = "prefixed", 6 | srcs = ["prefixed.cpp"], 7 | hdrs = ["prefixed.h"], 8 | include_prefix = "virtual/prefix", 9 | ) 10 | 11 | cc_library( 12 | name = "stripped", 13 | srcs = ["stripped.cpp"], 14 | hdrs = ["some/sub/dir/stripped.h"], 15 | strip_include_prefix = "some", 16 | ) 17 | 18 | cc_binary( 19 | name = "use_prefixed", 20 | srcs = ["use_prefixed.cpp"], 21 | deps = [":prefixed"], 22 | ) 23 | 24 | cc_binary( 25 | name = "use_stripped", 26 | srcs = ["use_stripped.cpp"], 27 | deps = [":stripped"], 28 | ) 29 | -------------------------------------------------------------------------------- /dwyu/apply_fixes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_binary.bzl", "py_binary") 2 | load("@rules_python//python:py_library.bzl", "py_library") 3 | 4 | py_library( 5 | name = "lib", 6 | srcs = [ 7 | "apply_fixes.py", 8 | "bazel_query.py", 9 | "buildozer_executor.py", 10 | "get_dwyu_reports.py", 11 | "search_missing_deps.py", 12 | "summary.py", 13 | "utils.py", 14 | ], 15 | visibility = [":__subpackages__"], 16 | ) 17 | 18 | py_binary( 19 | name = "main", 20 | srcs = ["main.py"], 21 | # Compatibility to --noexperimental_python_import_all_repositories 22 | imports = ["../.."], 23 | visibility = ["//:__pkg__"], 24 | deps = [":lib"], 25 | ) 26 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/test_remove_unused_public_dep.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:unused_public_dep" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-unused-deps"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:lib_a"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /examples/target_mapping/mapping/BUILD: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "MAP_DIRECT_DEPS", "MAP_TRANSITIVE_DEPS", "dwyu_make_cc_info_mapping") 2 | 3 | package(default_visibility = ["//target_mapping:__pkg__"]) 4 | 5 | dwyu_make_cc_info_mapping( 6 | name = "map_specific_deps", 7 | mapping = { 8 | "//target_mapping/libs:a": ["//target_mapping/libs:b"], 9 | }, 10 | ) 11 | 12 | dwyu_make_cc_info_mapping( 13 | name = "map_direct_deps", 14 | mapping = { 15 | "//target_mapping/libs:a": MAP_DIRECT_DEPS, 16 | }, 17 | ) 18 | 19 | dwyu_make_cc_info_mapping( 20 | name = "map_transitive_deps", 21 | mapping = { 22 | "//target_mapping/libs:a": MAP_TRANSITIVE_DEPS, 23 | }, 24 | ) 25 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/select_includes_via_external_macros.cpp: -------------------------------------------------------------------------------- 1 | // One can use a define as indirection for the include path 2 | #include LIB_A_FILE_PATH 3 | 4 | // The existence of a define can decide if we include one file or another 5 | #ifdef TOGGLE 6 | #include "support/lib_b.h" 7 | #else 8 | // If this would be included, it would fail the DWYU analysis 9 | #include "support/transitive.h" 10 | #endif 11 | 12 | // The value of a define can decide if we include one file or another 13 | #if THE_ANSWER > 10 14 | #include "support/lib_c.h" 15 | #else 16 | // If this would be included, it would fail the DWYU analysis 17 | #include "support/transitive.h" 18 | #endif 19 | 20 | int main() { 21 | return libA() + libB() + libC(); 22 | } 23 | -------------------------------------------------------------------------------- /test/aspect/preprocessing/test_preprocessing.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import DwyuImplCompatibility, TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | @property 9 | def dwyu_impl_compatibility(self) -> DwyuImplCompatibility: 10 | # The Python based preprocessor does not support all cases we test here 11 | return DwyuImplCompatibility.CPP_ONLY 12 | 13 | def execute_test_logic(self) -> Result: 14 | expected = ExpectedResult(success=True) 15 | actual = self._run_dwyu(target="//preprocessing:all", aspect=self.default_aspect) 16 | 17 | return self._check_result(actual=actual, expected=expected) 18 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/mapping/BUILD: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "MAP_DIRECT_DEPS", "MAP_TRANSITIVE_DEPS", "dwyu_make_cc_info_mapping") 2 | 3 | package(default_visibility = ["//target_mapping:__pkg__"]) 4 | 5 | dwyu_make_cc_info_mapping( 6 | name = "map_specific_deps", 7 | mapping = { 8 | "//target_mapping/libs:a": ["//target_mapping/libs:b"], 9 | }, 10 | ) 11 | 12 | dwyu_make_cc_info_mapping( 13 | name = "map_direct_deps", 14 | mapping = { 15 | "//target_mapping/libs:a": MAP_DIRECT_DEPS, 16 | }, 17 | ) 18 | 19 | dwyu_make_cc_info_mapping( 20 | name = "map_transitive_deps", 21 | mapping = { 22 | "//target_mapping/libs:a": MAP_TRANSITIVE_DEPS, 23 | }, 24 | ) 25 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/data/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules/directory:directory.bzl", "directory") 2 | load("@bazel_skylib//rules/directory:subdirectory.bzl", "subdirectory") 3 | 4 | directory( 5 | name = "root", 6 | srcs = glob(["**"]), 7 | ) 8 | 9 | subdirectory( 10 | name = "fizz", 11 | parent = ":root", 12 | path = "fizz", 13 | visibility = ["//:__subpackages__"], 14 | ) 15 | 16 | subdirectory( 17 | name = "fizz_buzz", 18 | parent = ":root", 19 | path = "fizz/buzz", 20 | visibility = ["//:__subpackages__"], 21 | ) 22 | 23 | subdirectory( 24 | name = "foobar", 25 | parent = ":root", 26 | path = "foobar", 27 | visibility = ["//:__subpackages__"], 28 | ) 29 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_preprocessor_results/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:defs.bzl", "py_binary") 2 | 3 | # This pulls 'pcpp', although we are not using it. Preventing this would require restructuring the legacy Python implementation. 4 | # Since, this target will either way just live temporarily, we accept this superfluous dependency. 5 | # 'pcpp' is either way a small thing and chap to fetch. 6 | py_binary( 7 | name = "main", 8 | srcs = [ 9 | "lib.py", 10 | "main.py", 11 | ], 12 | # Compatibility to --noexperimental_python_import_all_repositories 13 | imports = ["../../../.."], 14 | visibility = ["//visibility:public"], 15 | deps = ["//dwyu/aspect/private/analyze_includes:lib"], 16 | ) 17 | -------------------------------------------------------------------------------- /test/aspect/skip_external_targets/test_skip_broken_target.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | # If we would not skip al external targets the analysis would find an issue with the broken dependency 10 | expected = ExpectedResult(success=True) 11 | actual = self._run_dwyu( 12 | target="@skip_external_deps_test_repo//:broken_dep", 13 | aspect=self.choose_aspect("//skip_external_targets:aspect.bzl%dwyu_skip_external"), 14 | ) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /dwyu/private/test/utils_test.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") 2 | load("//dwyu/private:utils.bzl", "label_to_name") 3 | 4 | def _label_to_name_test_impl(ctx): 5 | env = unittest.begin(ctx) 6 | 7 | # No changes 8 | asserts.equals(env, "some_unchanged_string", label_to_name("some_unchanged_string")) 9 | 10 | # Replace characters which are not valid for file names 11 | asserts.equals(env, "foo_some_path_to_a_target", label_to_name("@foo//some/path/to/a:target")) 12 | 13 | return unittest.end(env) 14 | 15 | label_to_name_test = unittest.make(_label_to_name_test_impl) 16 | 17 | def utils_test_suite(name): 18 | unittest.suite( 19 | name, 20 | label_to_name_test, 21 | ) 22 | -------------------------------------------------------------------------------- /test/aspect/ignore_toolchain_headers/aspect.bzl: -------------------------------------------------------------------------------- 1 | load("@depend_on_what_you_use//:defs.bzl", "dwyu_aspect_factory") 2 | 3 | dwyu_ignore_toolchain_headers = dwyu_aspect_factory(ignore_cc_toolchain_headers = True) 4 | dwyu_custom_toolchain_headers_info = dwyu_aspect_factory(ignore_cc_toolchain_headers = True, cc_toolchain_headers_info = Label("//ignore_toolchain_headers:custom_cc_toolchain_headers_info")) 5 | 6 | dwyu_ignore_toolchain_headers_cpp = dwyu_aspect_factory(ignore_cc_toolchain_headers = True, use_cpp_implementation = True) 7 | dwyu_custom_toolchain_headers_info_cpp = dwyu_aspect_factory(ignore_cc_toolchain_headers = True, cc_toolchain_headers_info = Label("//ignore_toolchain_headers:custom_cc_toolchain_headers_info"), use_cpp_implementation = True) 8 | -------------------------------------------------------------------------------- /scripts/test/extract_std_headers_test.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import unittest 4 | 5 | from scripts.extract_std_headers import extract_header 6 | 7 | 8 | class TestExtractHeader(unittest.TestCase): 9 | def test_empty_input_yields_empty_list(self) -> None: 10 | self.assertEqual(extract_header(""), []) 11 | 12 | def test_extracting_headers(self) -> None: 13 | headers = extract_header( 14 | """ 15 | unrelated_stuff 16 | 17 | ignore this 18 | 19 | 20 | """.strip() 21 | ) 22 | 23 | self.assertEqual(headers, ["foo", "bar.h", "multiple_header", "in_one_line"]) 24 | 25 | 26 | if __name__ == "__main__": 27 | unittest.main() 28 | -------------------------------------------------------------------------------- /test/aspect/complex_includes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "complex_includes", 5 | srcs = ["complex_includes.cpp"], 6 | hdrs = [ 7 | "some/dir/complex_include_a.h", 8 | "some/dir/complex_include_b.h", 9 | ], 10 | include_prefix = "virtual/prefix", 11 | includes = ["some"], 12 | strip_include_prefix = "some", 13 | ) 14 | 15 | cc_library( 16 | name = "use_complex_includes", 17 | srcs = ["use_complex_includes.cpp"], 18 | deps = [":complex_includes"], 19 | ) 20 | 21 | cc_library( 22 | name = "use_complex_includes_from_extern", 23 | srcs = ["use_complex_includes.cpp"], 24 | deps = ["@complex_includes_test_repo//:complex_includes"], 25 | ) 26 | -------------------------------------------------------------------------------- /test/aspect/ignore_includes/support/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | # Using the headers from 'transitive_dep' will cause a DWYU failure unless those headers are ignored with a custom config 4 | cc_library( 5 | name = "direct_dep", 6 | visibility = ["//ignore_includes:__pkg__"], 7 | deps = [":transitive_dep"], 8 | ) 9 | 10 | cc_library( 11 | name = "transitive_dep", 12 | hdrs = [ 13 | "a_substring_match_does_not_work_here.h", 14 | "do_match_include_end.h", 15 | "ignored_sub_path_1/some_header.h", 16 | "ignored_sub_path_2/some_header.h", 17 | "matching_begin_without_regex_works_example.h", 18 | "some_header.h", 19 | "some_other_header.h", 20 | ], 21 | ) 22 | -------------------------------------------------------------------------------- /dwyu/cc_toolchain_headers/private/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | load("@rules_python//python:defs.bzl", "py_binary") 3 | 4 | py_binary( 5 | name = "gather_cc_toolchain_headers_tool", 6 | srcs = ["gather_cc_toolchain_headers.py"], 7 | main = "gather_cc_toolchain_headers.py", 8 | visibility = ["//visibility:public"], 9 | ) 10 | 11 | bzl_library( 12 | name = "gather_cc_toolchain_headers_bzl", 13 | srcs = ["gather_cc_toolchain_headers.bzl"], 14 | visibility = ["//dwyu/cc_toolchain_headers:__pkg__"], 15 | deps = [ 16 | "@rules_cc//cc:action_names_bzl", 17 | "@rules_cc//cc:find_cc_toolchain_bzl", 18 | "@rules_cc//cc/common", 19 | ], 20 | ) 21 | 22 | exports_files(["empty.cpp"]) 23 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/test_find_generated_code.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:use_generated_code" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-missing-deps"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:generated_code_provider", "//generate_code:foo"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /test/aspect/multiple_deps_for_one_header/test_multiple_deps_for_one_header.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | """ 10 | Multiple dependencies providing the same header can be considered an antipattern. Still, with respect to the 11 | DWYU principles it is not wrong. Such cases should not cause a DWYU error. 12 | """ 13 | expected = ExpectedResult(success=True) 14 | actual = self._run_dwyu(target="//multiple_deps_for_one_header:foo", aspect=self.default_aspect) 15 | 16 | return self._check_result(actual=actual, expected=expected) 17 | -------------------------------------------------------------------------------- /dwyu/aspect/private/cc_toolchain_headers_stub.bzl: -------------------------------------------------------------------------------- 1 | load("//dwyu/cc_toolchain_headers:providers.bzl", "DwyuCcToolchainHeadersInfo") 2 | 3 | visibility("private") 4 | 5 | def _cc_toolchain_headers_stub_impl(ctx): 6 | return DwyuCcToolchainHeadersInfo(headers_info = ctx.file._info) 7 | 8 | cc_toolchain_headers_stub = rule( 9 | implementation = _cc_toolchain_headers_stub_impl, 10 | provides = [DwyuCcToolchainHeadersInfo], 11 | attrs = {"_info": attr.label( 12 | allow_single_file = True, 13 | default = Label("//dwyu/aspect/private:cc_toolchain_headers_info_stub.json"), 14 | )}, 15 | doc = "Stub target doing nothing so the DWYU aspect does not needlessly try to analyze the CC toolchain if the user sets 'ignore_cc_toolchain_headers' to False", 16 | ) 17 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/test_suggest_missing_dep_for_binary.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:use_libs" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-missing-deps"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:libs_provider", "//libs:foo", "//libs:bar", "//:root_file_lib"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /test/aspect/command_length_limit/BUILD: -------------------------------------------------------------------------------- 1 | """ 2 | Show that the DWYU aspect can handle cases where some attributes of the target under inspection are so large that the 3 | resulting command invocations are larger than the system's command length limits. 4 | 5 | We only test the command line length limit for the target processing step. A test for the analysis step would have an 6 | enormous runtime. Such a scenario is unlikely in a real project and thus we skip it for now. 7 | """ 8 | 9 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 10 | load(":make_large_arg.bzl", "make_large_defines") 11 | 12 | CHARACTERS_IN_COMMAND = 5000000 13 | 14 | cc_library( 15 | name = "many_defines", 16 | hdrs = ["foo.h"], 17 | local_defines = make_large_defines(CHARACTERS_IN_COMMAND), 18 | ) 19 | -------------------------------------------------------------------------------- /dwyu/apply_fixes/test/buildozer_executor_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from pathlib import Path 3 | 4 | from dwyu.apply_fixes.buildozer_executor import BuildozerExecutor 5 | 6 | 7 | class TestBuildozerExecutor(unittest.TestCase): 8 | def test_make_simple_base_command(self) -> None: 9 | unit = BuildozerExecutor(buildozer="foo", buildozer_args=[], workspace=Path(), dry=False) 10 | self.assertEqual(unit._base_cmd, ["foo"]) # noqa: SLF001 11 | 12 | def test_make_complex_base_command(self) -> None: 13 | unit = BuildozerExecutor(buildozer="foo", buildozer_args=["riff", "raff"], workspace=Path(), dry=True) 14 | self.assertEqual(unit._base_cmd, ["foo", "riff", "raff", "-stdout"]) # noqa: SLF001 15 | 16 | 17 | if __name__ == "__main__": 18 | unittest.main() 19 | -------------------------------------------------------------------------------- /test/apply_fixes/tool_cli/test_utilize_bazel_info.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:binary" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports(extra_args=["--noexperimental_convenience_symlinks"]) 12 | self._run_automatic_fix(extra_args=["--fix-unused", "--use-bazel-info"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := set()) != target_deps: # type: ignore[var-annotated] 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /test/aspect/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_library.bzl", "py_library") 2 | load("@rules_python//python:py_test.bzl", "py_test") 3 | 4 | py_library( 5 | name = "expected_result", 6 | testonly = True, 7 | srcs = ["expected_result.py"], 8 | deps = ["@depend_on_what_you_use//test/support"], 9 | ) 10 | 11 | py_test( 12 | name = "expected_result_test", 13 | srcs = ["expected_result_test.py"], 14 | deps = [":expected_result"], 15 | ) 16 | 17 | py_test( 18 | name = "test_case_test", 19 | srcs = [ 20 | "test_case.py", 21 | "test_case_test.py", 22 | ], 23 | deps = [":expected_result"], 24 | ) 25 | 26 | py_test( 27 | name = "version_test", 28 | srcs = [ 29 | "version.py", 30 | "version_test.py", 31 | ], 32 | ) 33 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/test_suggest_missing_dep_from_hdrs_and_srcs.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:mixed_libs_usage" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-missing-deps"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:libs_provider", "//libs:foo", "//libs:bar", "//:root_file_lib"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/rule_based/gcc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # verbose output of gcc and clang is piped to stderr 4 | echo_to_stderr() 5 | { 6 | echo "$@" >&2; 7 | } 8 | 9 | # Hard coding this is brittle, but generating this file is also problematic due to it then residing in the bin dir instead of relative to the toolchain root dir 10 | ROOT_DIR="external/test_toolchain_rule_based+" 11 | 12 | echo_to_stderr 'Some unrelated text' 13 | 14 | echo_to_stderr '#include "..." search starts here:' 15 | echo_to_stderr " ${ROOT_DIR}/data/fizz" 16 | echo_to_stderr " ${ROOT_DIR}/data/fizz/buzz" 17 | echo_to_stderr '#include <...> search starts here:' 18 | echo_to_stderr " ${ROOT_DIR}/data/foobar" 19 | echo_to_stderr 'End of search list.' 20 | 21 | echo_to_stderr 'More unrelated stuff' 22 | -------------------------------------------------------------------------------- /test/cc_toolchains/mocked/toolchains/classic/tools/fake_gcc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # verbose output of gcc and clang is piped to stderr 4 | echo_to_stderr() 5 | { 6 | echo "$@" >&2; 7 | } 8 | 9 | # Hard coding this is brittle, but generating this file is also problematic due to it then residing in the bin dir instead of relative to the toolchain root dir 10 | ROOT_DIR="external/test_toolchain_classic+" 11 | 12 | echo_to_stderr 'Some unrelated text' 13 | 14 | echo_to_stderr '#include "..." search starts here:' 15 | echo_to_stderr " ${ROOT_DIR}/data/fizz" 16 | echo_to_stderr " ${ROOT_DIR}/data/fizz/buzz" 17 | echo_to_stderr '#include <...> search starts here:' 18 | echo_to_stderr " ${ROOT_DIR}/data/foobar" 19 | echo_to_stderr 'End of search list.' 20 | 21 | echo_to_stderr 'More unrelated stuff' 22 | -------------------------------------------------------------------------------- /test/cc_toolchains/upstream/bazelrc.tpl: -------------------------------------------------------------------------------- 1 | # Do not waste memory by keeping idle Bazel servers around 2 | startup --max_idle_secs=10 3 | 4 | # Needless noise in the temporary workspaces 5 | common --experimental_convenience_symlinks=ignore 6 | common --lockfile_mode=off 7 | 8 | # We are not interested in dependency resolution here 9 | build --check_direct_dependencies=off 10 | 11 | # Ensure only the hermetic toolchain is available to bazel 12 | build:no_default_toolchain --incompatible_enable_cc_toolchain_resolution # Can be dropped when Bazel 7 is the minimum version 13 | build:no_default_toolchain --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 14 | build:no_default_toolchain --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 15 | 16 | build:dwyu --aspects=//:aspect.bzl%dwyu 17 | build:dwyu --output_groups=dwyu 18 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/test/benchmark/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:defs.bzl", "py_binary", "py_library") 2 | 3 | py_binary( 4 | name = "analyze_many_includes", 5 | srcs = ["analyze_many_includes.py"], 6 | deps = ["//dwyu/aspect/private/analyze_includes:lib"], 7 | ) 8 | 9 | py_binary( 10 | name = "parsing_benchmark_many_files", 11 | srcs = ["parsing_benchmark_many_files.py"], 12 | deps = [":parsing_benchmark_lib"], 13 | ) 14 | 15 | py_binary( 16 | name = "parsing_benchmark_many_macros", 17 | srcs = ["parsing_benchmark_many_macros.py"], 18 | deps = [":parsing_benchmark_lib"], 19 | ) 20 | 21 | py_library( 22 | name = "parsing_benchmark_lib", 23 | srcs = ["parsing_benchmark_lib.py"], 24 | deps = ["//dwyu/aspect/private/analyze_includes:lib"], 25 | ) 26 | -------------------------------------------------------------------------------- /test/apply_fixes/missing_dependency/test_suggest_missing_dep_based_on_fallback_logic_using_header_file_name.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:use_manipulated_bar" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports() 12 | self._run_automatic_fix(extra_args=["--fix-missing-deps"]) 13 | 14 | target_deps = self._get_target_deps(self.test_target) 15 | if (expected := {"//:manipulated_bar_provider", "//libs:manipulated_bar"}) != target_deps: 16 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 17 | return Success() 18 | -------------------------------------------------------------------------------- /examples/ignoring_includes/README.md: -------------------------------------------------------------------------------- 1 | Your project might use headers for which a proper dependency is not possible. 2 | One example for such a case would be a toolchain making headers beyond the C/C++ standard library globally available to your targets. 3 | 4 | You can tell DWYU to ignore certain include statements to skip such headers for which a proper Bazel target dependency is not possible. 5 | 6 | Executing the following succeeds due to ignoring the include statements pointing to not existing headers as configured in [ignore_includes.json](./ignore_includes.json). 7 | See the [bazelrc](/examples/.bazelrc) file and [aspect.bzl](/examples/aspect.bzl) for the definition of the config and the aspect configuration. 8 | 9 | ```shell 10 | bazel build --config=dwyu_ignoring_includes //ignoring_includes:use_unavailable_headers 11 | ``` 12 | -------------------------------------------------------------------------------- /test/aspect/external_repo/test_external_dependencies.py: -------------------------------------------------------------------------------- 1 | from expected_result import ExpectedResult 2 | from test_case import TestCaseBase 3 | 4 | from test.support.result import Result 5 | 6 | 7 | class TestCase(TestCaseBase): 8 | def execute_test_logic(self) -> Result: 9 | """ 10 | Working with external repositories has its own challenges due to some paths behaving different compared to 11 | working inside the own workspace. This test shows DWYU can be invoked on targets using libraries from external 12 | workspaces without failing unexpectedly. 13 | """ 14 | expected = ExpectedResult(success=True) 15 | actual = self._run_dwyu(target="//external_repo:use_external_libs", aspect=self.default_aspect) 16 | 17 | return self._check_result(actual=actual, expected=expected) 18 | -------------------------------------------------------------------------------- /scripts/release.md: -------------------------------------------------------------------------------- 1 | # Semi automatic release process 2 | 3 | ## Release creation 4 | 5 | 1. `git tag VERSION` 6 | 1. `git push origin VERSION` 7 | 1. The CI will automatically create a draft PR 8 | 1. Check the release notes and fill manual sections 9 | 1. TODO do we have to set to 'pre-release', or can we continue with Draft for adding to BCR? 10 | 11 | ## Adding to BCR 12 | 13 | 1. Execute [scripts/deploy_to_bcr.py](/scripts/deploy_to_bcr.py) and provide version when asked for 14 | 1. Follow lnk in terminal and open PR on https://github.com/bazelbuild/bazel-central-registry 15 | 16 | ## Finish release 17 | 18 | 1. Wait until release is available via BCR 19 | 1. Make sure the release works via the [test repo](https://github.com/martis42/test_dwyu) 20 | 1. Finish release notes: 21 | - Remove BCR warning 22 | - Set to latest release 23 | -------------------------------------------------------------------------------- /test/aspect/implementation_deps/external_repo/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "ext_lib", 5 | hdrs = ["ext_lib.h"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_library( 10 | name = "lib_with_includes", 11 | hdrs = ["ext/dir/ext_lib_with_includes.h"], 12 | includes = ["ext"], 13 | visibility = ["//visibility:public"], 14 | ) 15 | 16 | cc_library( 17 | name = "lib_with_strip_prefix", 18 | hdrs = ["ext/dir/ext_lib_with_strip_prefix.h"], 19 | strip_include_prefix = "ext/dir", 20 | visibility = ["//visibility:public"], 21 | ) 22 | 23 | cc_library( 24 | name = "lib_with_add_prefix", 25 | hdrs = ["ext/dir/ext_lib_with_add_prefix.h"], 26 | include_prefix = "some/prefix", 27 | visibility = ["//visibility:public"], 28 | ) 29 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/test_remove_unused_private_dep.py: -------------------------------------------------------------------------------- 1 | from test.apply_fixes.test_case import TestCaseBase 2 | from test.support.result import Result, Success 3 | 4 | 5 | class TestCase(TestCaseBase): 6 | @property 7 | def test_target(self) -> str: 8 | return "//:unused_private_dep" 9 | 10 | def execute_test_logic(self) -> Result: 11 | self._create_reports( 12 | aspect="use_implementation_deps_aspect", extra_args=["--experimental_cc_implementation_deps"] 13 | ) 14 | self._run_automatic_fix(extra_args=["--fix-unused-deps"]) 15 | 16 | target_deps = self._get_target_impl_deps(self.test_target) 17 | if (expected := {"//:lib_a"}) != target_deps: 18 | return self._make_unexpected_deps_error(expected_deps=expected, actual_deps=target_deps) 19 | return Success() 20 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_c_with_direct_deps_mapping.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from expected_result import ExpectedResult 4 | from test_case import TestCaseBase 5 | 6 | from test.support.result import Result 7 | 8 | 9 | class TestCase(TestCaseBase): 10 | def execute_test_logic(self) -> Result: 11 | expected = ExpectedResult( 12 | success=False, 13 | invalid_includes=[f"File='{Path('target_mapping/use_lib_c.cpp')}', include='target_mapping/libs/c.h'"], 14 | unused_public_deps=["//target_mapping/libs:a"], 15 | ) 16 | actual = self._run_dwyu( 17 | target="//target_mapping:use_lib_c", 18 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_direct_deps"), 19 | ) 20 | 21 | return self._check_result(actual=actual, expected=expected) 22 | -------------------------------------------------------------------------------- /test/aspect/target_mapping/test_use_c_with_specific_mapping.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from expected_result import ExpectedResult 4 | from test_case import TestCaseBase 5 | 6 | from test.support.result import Result 7 | 8 | 9 | class TestCase(TestCaseBase): 10 | def execute_test_logic(self) -> Result: 11 | expected = ExpectedResult( 12 | success=False, 13 | invalid_includes=[f"File='{Path('target_mapping/use_lib_c.cpp')}', include='target_mapping/libs/c.h'"], 14 | unused_public_deps=["//target_mapping/libs:a"], 15 | ) 16 | actual = self._run_dwyu( 17 | target="//target_mapping:use_lib_c", 18 | aspect=self.choose_aspect("//target_mapping:aspect.bzl%map_specific_deps"), 19 | ) 20 | 21 | return self._check_result(actual=actual, expected=expected) 22 | -------------------------------------------------------------------------------- /test/apply_fixes/unused_dependency/workspace/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | cc_library( 4 | name = "lib_a", 5 | hdrs = ["lib_a.h"], 6 | ) 7 | 8 | cc_library( 9 | name = "lib_b", 10 | hdrs = ["lib_b.h"], 11 | ) 12 | 13 | cc_library( 14 | name = "lib_c", 15 | hdrs = ["lib_c.h"], 16 | deps = [ 17 | ":lib_a", 18 | ":lib_b", 19 | ], 20 | ) 21 | 22 | cc_library( 23 | name = "unused_public_dep", 24 | srcs = ["using_a.cpp"], 25 | deps = [ 26 | ":lib_a", 27 | ":lib_b", # unused 28 | ":lib_c", # unused 29 | ], 30 | ) 31 | 32 | cc_library( 33 | name = "unused_private_dep", 34 | srcs = ["using_a.cpp"], 35 | implementation_deps = [ 36 | ":lib_a", 37 | ":lib_b", # unused 38 | ":lib_c", # unused 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /dwyu/private/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef DWYU_PRIVATE_UTILS_H 2 | #define DWYU_PRIVATE_UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace dwyu { 11 | 12 | template 13 | void printToError(T&& arg) { 14 | std::cerr << arg; 15 | } 16 | 17 | template 18 | void printToError(T&& first, Args&&... rest) { 19 | printToError(std::forward(first)); 20 | printToError(std::forward(rest)...); 21 | } 22 | 23 | template 24 | void abortWithError(Args&&... args) { 25 | std::cerr << "ERROR: "; 26 | printToError(std::forward(args)...); 27 | std::cerr << "\n"; 28 | std::exit(1); 29 | } 30 | 31 | std::string listToStr(const std::vector& list); 32 | 33 | } // namespace dwyu 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /dwyu/aspect/private/analyze_includes/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:py_binary.bzl", "py_binary") 2 | load("@rules_python//python:py_library.bzl", "py_library") 3 | 4 | py_library( 5 | name = "lib", 6 | srcs = [ 7 | "evaluate_includes.py", 8 | "parse_config.py", 9 | "parse_source.py", 10 | "result.py", 11 | "std_header.py", 12 | "system_under_inspection.py", 13 | ], 14 | visibility = ["//dwyu/aspect/private:__subpackages__"], 15 | deps = ["@dwyu_pcpp//:pcpp"], 16 | ) 17 | 18 | py_binary( 19 | name = "analyze_includes", 20 | srcs = ["main.py"], 21 | # Compatibility to --noexperimental_python_import_all_repositories 22 | imports = ["../../../.."], 23 | legacy_create_init = False, 24 | main = "main.py", 25 | visibility = ["//visibility:public"], 26 | deps = [":lib"], 27 | ) 28 | -------------------------------------------------------------------------------- /test/aspect/defines/support/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:cc_library.bzl", "cc_library") 2 | 3 | package(default_visibility = ["//defines:__pkg__"]) 4 | 5 | cc_library( 6 | name = "transitive_define", 7 | copts = ["-DLOCAL_COPT"], # should not influence other targets 8 | defines = ["TRANSITIVE_DEFINE"], 9 | local_defines = ["LOCAL_DEFINE"], # should not influence other targets 10 | ) 11 | 12 | cc_library( 13 | name = "conditional_defines", 14 | hdrs = ["conditional_defines.h"], 15 | deps = [":some_defines"], 16 | ) 17 | 18 | cc_library( 19 | name = "some_defines", 20 | hdrs = ["some_defines.h"], 21 | ) 22 | 23 | cc_library( 24 | name = "lib_a", 25 | hdrs = ["a.h"], 26 | ) 27 | 28 | cc_library( 29 | name = "lib_b", 30 | hdrs = ["b.h"], 31 | ) 32 | 33 | cc_library( 34 | name = "lib_c", 35 | hdrs = ["c.h"], 36 | ) 37 | --------------------------------------------------------------------------------