![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
Functions | |
| has_unbuilt_branch (text) | |
| read (path) | |
| project_files () | |
| strip_comments_and_strings (text) | |
| declared_names (text) | |
| resolve (inc, from_path, known) | |
| analyse () | |
| _all_targets () | |
| ninja_target_for (path) | |
| verify (results, limit) | |
| main () | |
| _strip (path, incs) | |
| _build (targets=None) | |
| _implicated (log, owned) | |
| _apply_only (subset, originals, targets) | |
| _bisect_set (files, originals, targets) | |
| apply_mode (results, prefix, skip_guarded) | |
| _object_to_source () | |
| _failing_sources (log, obj2src) | |
| _consumers_of (header) | |
| push_down (results) | |
Variables | |
| str | SRC = 'src' |
| str | BUILD = 'build' |
| INCLUDE_RE = re.compile(r'^([ \t]*#[ \t]*include[ \t]+")([^"]+)(".*)$', re.M) | |
| IDENT_RE = re.compile(r'\b[A-Za-z_][A-Za-z0-9_]*\b') | |
| dict | SIDE_EFFECT_HEADERS |
| list | DECL_PATTERNS |
| tuple | OS_MACROS |
| OS_COND_RE = re.compile(r'^[ \t]*#[ \t]*(?:if|ifdef|ifndef|elif)\b[^\n]*\b(?:' + OS_MACROS + r')\b', re.M) | |
| COND_RE = re.compile(r'^[ \t]*#[ \t]*(if|ifdef|ifndef|elif|else|endif)\b([^\n]*)', re.M) | |
| FEATURE_RE = re.compile(r'\b(?:HAVE_[A-Z0-9_]+|__SSE2__|__ARM_NEON|_OPENMP)\b') | |
| ATTRIBUTE_RE = re.compile(r'__attribute__\s*\(\((?:[^()]|\([^()]*\))*\)\)') | |
| _TARGETS_CACHE = None | |
Find `#include`s that a file does not need.
Two stages, because neither alone is trustworthy:
1. STATIC (fast, whole tree, no build). Index every project header by the names it
DECLARES (macros, typedefs, tags, enum constants, function and variable
declarations). For each file F and each header H that F includes directly, if F
mentions none of H's own names, H is a *candidate* for removal.
This over-reports: F may include H legitimately to reach something H itself
includes (a transitive dependency). That is exactly the coupling we want to make
explicit, but removing such an include still breaks the build, so a candidate is
a question, never a verdict.
2. VERIFY (slow, exact w.r.t. the current build config). Actually comment the
include out, recompile the affected object with ninja, and keep the removal only
if it still compiles. Run this on the candidates from stage 1.
The verify stage cannot prove an include is unneeded on OTHER platforms: an include
used only inside `#ifdef _WIN32` looks removable on Linux and is not. Candidates whose
symbol use is under a conditional are flagged `platform-guarded` and must never be
removed on the strength of a Linux-only build. See doc/include-hygiene-roadmap.md.
Usage:
python3 tools/include_unused.py # static pass, summary
python3 tools/include_unused.py --headers # only .h files
python3 tools/include_unused.py --sources # only .c/.cc files
python3 tools/include_unused.py --file src/iop/x.c # one file, verbose
python3 tools/include_unused.py --json out.json # machine-readable
python3 tools/include_unused.py --verify --limit 40 # empirically test candidates
|
protected |
Definition at line 202 of file include_unused.py.
Referenced by ninja_target_for().
|
protected |
Restore every touched file, then re-strip just `subset`.
Definition at line 383 of file include_unused.py.
References _strip().
Referenced by _bisect_set().
|
protected |
Largest subset of `files` whose removals still build. Removals are independent in practice, so recursive halving is sound; the caller re-verifies the union.
Definition at line 392 of file include_unused.py.
References _apply_only(), _bisect_set(), and _build().
Referenced by _bisect_set(), and apply_mode().
|
protected |
Definition at line 359 of file include_unused.py.
Referenced by _bisect_set(), apply_mode(), and push_down().
|
protected |
Files that include `header` directly (either spelling).
Definition at line 542 of file include_unused.py.
References read().
Referenced by push_down().
|
protected |
Definition at line 533 of file include_unused.py.
Referenced by push_down().
|
protected |
Source files in `owned` that the build log blames, directly or through a generated introspection_*.c that textually includes them.
Definition at line 365 of file include_unused.py.
Referenced by apply_mode().
|
protected |
Reverse-map ninja object targets back to source files, via compdb.
Definition at line 511 of file include_unused.py.
Referenced by push_down().
|
protected |
Remove whole #include lines. Returns the ones actually removed. Must match the LINE, not the exact string `#include "x"\n`: an include carrying a trailing comment would silently fail to match, and the caller would then report a removal that never happened -- which is how this tool once claimed 7 removals for a 3-line diff.
Definition at line 340 of file include_unused.py.
References read().
Referenced by _apply_only(), apply_mode(), and push_down().
| include_unused.analyse | ( | ) |
Definition at line 165 of file include_unused.py.
References declared_names(), has_unbuilt_branch(), project_files(), read(), resolve(), and strip_comments_and_strings().
Referenced by main().
| include_unused.apply_mode | ( | results, | |
| prefix, | |||
| skip_guarded | |||
| ) |
Definition at line 416 of file include_unused.py.
References _bisect_set(), _build(), _implicated(), _strip(), and read().
Referenced by main().
| include_unused.declared_names | ( | text | ) |
Definition at line 134 of file include_unused.py.
References strip_comments_and_strings().
Referenced by analyse().
| include_unused.has_unbuilt_branch | ( | text | ) |
True if the file contains a branch this build does not compile.
Definition at line 89 of file include_unused.py.
Referenced by analyse().
| include_unused.main | ( | void | ) |
Definition at line 253 of file include_unused.py.
References analyse(), apply_mode(), push_down(), and verify().
Referenced by push_down().
| include_unused.ninja_target_for | ( | path | ) |
Best-effort mapping from a source file to one ninja object target.
Definition at line 214 of file include_unused.py.
References _all_targets().
Referenced by verify().
| include_unused.project_files | ( | ) |
Definition at line 113 of file include_unused.py.
Referenced by analyse().
| include_unused.push_down | ( | results | ) |
Definition at line 559 of file include_unused.py.
References _build(), _consumers_of(), _failing_sources(), _object_to_source(), _strip(), main(), and read().
Referenced by main().
| include_unused.read | ( | path | ) |
Definition at line 108 of file include_unused.py.
Referenced by _consumers_of(), _strip(), analyse(), apply_mode(), push_down(), and verify().
| include_unused.resolve | ( | inc, | |
| from_path, | |||
| known | |||
| ) |
Definition at line 155 of file include_unused.py.
Referenced by analyse().
| include_unused.strip_comments_and_strings | ( | text | ) |
Crude but adequate: we only need identifier presence, not exact syntax.
Definition at line 123 of file include_unused.py.
Referenced by analyse(), and declared_names().
| include_unused.verify | ( | results, | |
| limit | |||
| ) |
Comment each candidate out, rebuild its object, keep only what still compiles.
Definition at line 223 of file include_unused.py.
References ninja_target_for(), and read().
Referenced by main().
|
protected |
Definition at line 199 of file include_unused.py.
| include_unused.ATTRIBUTE_RE = re.compile(r'__attribute__\s*\(\((?:[^()]|\([^()]*\))*\)\)') |
Definition at line 131 of file include_unused.py.
| str include_unused.BUILD = 'build' |
Definition at line 41 of file include_unused.py.
| include_unused.COND_RE = re.compile(r'^[ \t]*#[ \t]*(if|ifdef|ifndef|elif|else|endif)\b([^\n]*)', re.M) |
Definition at line 85 of file include_unused.py.
| list include_unused.DECL_PATTERNS |
Definition at line 63 of file include_unused.py.
Definition at line 86 of file include_unused.py.
Definition at line 44 of file include_unused.py.
Definition at line 43 of file include_unused.py.
| include_unused.OS_COND_RE = re.compile(r'^[ \t]*#[ \t]*(?:if|ifdef|ifndef|elif)\b[^\n]*\b(?:' + OS_MACROS + r')\b', re.M) |
Definition at line 84 of file include_unused.py.
| tuple include_unused.OS_MACROS |
Definition at line 82 of file include_unused.py.
| dict include_unused.SIDE_EFFECT_HEADERS |
Definition at line 48 of file include_unused.py.
| str include_unused.SRC = 'src' |
Definition at line 40 of file include_unused.py.