Skip to main content

A C/C++ #include path normalizer that rewrites includes to resolve cleanly against a minimal -I set.

Project description

inclean

English | 简体中文

A C/C++ #include path normalizer.

Many legacy C/C++ libraries #include headers by bare filename (#include "bar.h") even though the actual header lives several directories deep (src/internal/bar.h). To consume such a library a caller must add every internal directory to their -I list — which pollutes their include namespace and breaks the library's encapsulation.

inclean does a one-shot, source-level normalization. It scans every source file in the library and rewrites each #include so it resolves cleanly against a small, explicit set of allowed include directories. After running inclean, consumers only -I the allowed directories.

Why inclean?

When using legacy libraries like some-old-lib, consumers often have to leak the library's internal directory structure into their own build configuration.

Without inclean: You have to add internal library paths to your own -I search paths to compile successfully.

gcc main.c -o main -I third_party -I third_party/some-old-lib/internal

Without inclean

Using inclean: inclean automatically cleans up and standardizes the #include paths inside some-old-lib. Consumers only need to include the top-level directory.

gcc main.c -o main -I third_party

Using inclean


Install

inclean is published to crates.io, PyPI, and as prebuilt binaries on GitHub Releases. Pick whichever ecosystem you already have on your machine.

Via PyPI (Python wheels — no Rust toolchain needed)

Three options:

uv tool install inclean      # isolated, fastest
pipx install inclean         # isolated
pip install inclean          # into the current environment

The wheels ship the native binary built by maturin; inclean lands on your PATH the same way ruff or uv do. Requires Python ≥ 3.8.

Via cargo

Two options:

cargo binstall inclean       # prebuilt binary from GitHub Releases (no compilation)
cargo install inclean        # build from crates.io

cargo binstall fetches inclean's binstall metadata from crates.io and downloads the matching prebuilt archive from this repo's GitHub Releases (no compilation). cargo binstall is a third-party cargo subcommand — install it first via cargo-bins/cargo-binstall if you don't already have it.

cargo install downloads the source from crates.io and compiles it locally.

Prebuilt binaries (no package manager)

Download a tarball for your platform from the latest GitHub Release and put inclean (or inclean.exe) on your PATH.

From repo source

Clone this repo and build from source:

git clone https://github.com/inaku-Gyan/inclean.git
cd inclean
cargo install --path .

Quick start

inclean is driven by an inclean.toml placed at the root of the library you want to clean up. A typical workflow:

inclean init                # write a documented starter inclean.toml
$EDITOR inclean.toml        # tell it where your headers live
inclean check               # dry-run: report every proposed change
inclean diff                # see the rewrites as a unified diff
inclean apply               # write the rewrites in place

check / diff / apply optionally take [PATHS...] to restrict which files are processed; with no paths they consider every source file under the project root. -c PATH overrides the upward inclean.toml walk; -j N sets the worker thread count.

Rule matching first checks file_paths, file_suffixes, include_forms, and include_match. include_resolved_match applies later to resolved header paths. Globs are anchored and use literal separators: foo.h only matches foo.h, while **/foo.h matches at any depth. Glob lists are ordered: a leading unescaped ! excludes, and the last matching pattern wins. Use TOML single quotes for a literal leading bang, for example '\!weird.h'; in double quotes, write "\\!weird.h". When include_directories is set, inclean then probes those literal directories, filters resolved project-relative header paths through include_resolved_match (default ["**"]), and applies include_on_unresolved (error / skip / allow) and include_on_ambiguous (error / skip / first). For #include MACRO, inclean statically expands simple header-like definitions such as #define MACRO "foo.h" or #define MACRO <foo.h>. Each matching definition is treated as a possible branch using the #include MACRO use-site context. By default path rewrites update the matching #define value(s), while trailing comments stay on the use site. Set macro_rewrite = "use_site" to rewrite #include MACRO itself; all matching definition branches must agree on the same final include argument. For rules that are meant to affect only one side of a rewrite, the whole field values action = "skip" and trailing_comment = "skip" make that side opt out of conflict detection. keep still participates in conflict checks; skip does not. For a rule without copied_from, both fields default to skip when omitted.

For the complete field-by-field syntax, see the configuration reference.

Example

A simple replace-action config that rewrites #include "foo.h" to #include "lib/foo.h":

[project]
root = "."
version = "0.3.0"
min_inclean_version = "0.3.0"

[[rule]]
name = "lib-prefix"
file_paths = ["src/**/*"]
include_match = ["foo.h", "bar.h"]
action = { type = "replace", with = "lib/${original}" }

See tests/golden_tests/ for runnable end-to-end examples.

Editor support

inclean.toml ships with a JSON Schema for editor completion and validation. Editors that understand the #:schema directive (VS Code with Tombi or Even Better TOML, Helix, Zed) automatically pick it up:

#:schema https://raw.githubusercontent.com/inaku-Gyan/inclean/v1.2.3/schemas/inclean.toml.schema.json

[project]
root = "."
version = "1.2.3"
min_inclean_version = "1.1.0"

(The above version numbers are just examples.)

inclean init writes both the #:schema line (for the editor) and the [project].version + [project].min_inclean_version fields, each pinned to the CLI version that generated the file. To upgrade schema validation, edit the version segment in the URL to a newer release tag.

#:schema and the [project] version fields are independent. The #:schema URL is purely for editor tooling; the CLI runs its own two-direction compatibility check (CLI_COMPAT_MIN <= cfg.version AND cfg.min_inclean_version <= CLI_CURRENT). inclean is pre-1.0 and does not ship migration shims for breaking schema changes — see CLAUDE.md.

You can also dump a local copy:

inclean config schema --output inclean.toml.schema.json

Documentation

License

BSD 3-Clause.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inclean-0.4.0a3.tar.gz (8.3 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

inclean-0.4.0a3-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

inclean-0.4.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

inclean-0.4.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

inclean-0.4.0a3-py3-none-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

inclean-0.4.0a3-py3-none-macosx_10_12_x86_64.whl (1.8 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file inclean-0.4.0a3.tar.gz.

File metadata

  • Download URL: inclean-0.4.0a3.tar.gz
  • Upload date:
  • Size: 8.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inclean-0.4.0a3.tar.gz
Algorithm Hash digest
SHA256 1401e74a655e31d531aa329342d36178c2be6604d81c858bea9deffeffea164d
MD5 77e56306391bbe110fbf49d5162c5c7c
BLAKE2b-256 8e720728207aed49d9e5b3d32f905d26c2d3a06e33da8aa11993a64953eeb1c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3.tar.gz:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.4.0a3-py3-none-win_amd64.whl.

File metadata

  • Download URL: inclean-0.4.0a3-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inclean-0.4.0a3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 1f0a9d3f6528d249d58e3d2c8052b73c3ccb8ea853715afd3e90df987ca594a4
MD5 2a455cc78ca9d1ab94be77efeec35515
BLAKE2b-256 9d7f8225ff9ad2b2015a95af33c252ca490f3169c33e2b10138d5c4baa6c1241

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3-py3-none-win_amd64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.4.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ee2e79874d4e9bb50e29061f37347f03fb24dda713cc49631fa49deaed17a4b3
MD5 fa2c89965688083f581a41a11114c1be
BLAKE2b-256 f5dc50e6f0b47985f3607146817cb12e6f82ed35991c9fe57d4fe06ec49633dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.4.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8a846da609860e037fb8d3f5d4c54acb93d92c5c208b4ffbf844d37386380293
MD5 e7e2a1338defda6537ae77cd14f63073
BLAKE2b-256 7512c6cb8fa6f72854a5b9fca3fad2b9e4badc5ff97ba596d18e97978e62149f

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.4.0a3-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 21fc8569fe3ef10a34cd9d8f3f9d5d6722a277fee1ddcccdd2262d343f709811
MD5 d3a7abea888c7db099b0f2ee4203ffba
BLAKE2b-256 47e91bd149333e7b13c7001ad80d542ef45acbb7637572783c5b9c77aafed11f

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.4.0a3-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a3-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 58720dd9492095d2722a4565d0906faec92205408b48d2a01beffad1045c1d8f
MD5 df952d2d9ea533e8e68cd93cb369cacf
BLAKE2b-256 c7c967413155abd5ee6801e41e0666370ca8d395fe06d3976a416dbc17e7e2a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a3-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page