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>. Path rewrites for these includes update the macro definition value, while trailing comments stay on the #include MACRO use site. 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.0a1.tar.gz (34.2 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.0a1-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

inclean-0.4.0a1-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.0a1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

inclean-0.4.0a1-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.0a1.tar.gz.

File metadata

  • Download URL: inclean-0.4.0a1.tar.gz
  • Upload date:
  • Size: 34.2 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.0a1.tar.gz
Algorithm Hash digest
SHA256 a292472ae1aca77b268b78d21a392daf63ad0f9ebd32d9a6a84cce831826356f
MD5 0eeca676f0b42163ebd1feb2f01e36db
BLAKE2b-256 1441fb6d4ca23f945427a4410c4eafa7fb52b5d149762ac43156fc32bddc9e05

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1.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.0a1-py3-none-win_amd64.whl.

File metadata

  • Download URL: inclean-0.4.0a1-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.0a1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 830f7db4513e1fb526c3c81fd0d74e80ccbfda08d5b9bb0553bb9999c9d9c126
MD5 7abbabe9642fcaef8544eb4d9a83a1e4
BLAKE2b-256 fba2e60ad830294a9a802e7e24c5d7a02d224e00c61174688e04f4c80810d5f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1-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.0a1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b3c98e9a807eb90503a26a5195a366b5deea8711db023c63d9227d603ec3728c
MD5 6c65b248fc322da44e05f420f0e034ac
BLAKE2b-256 b38f0285f6e01f3075c7f437a2b99a46ec0f26908572b648b267cd9b28497c3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1-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.0a1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c4e2bbf00b6b3b27476d144901ac0f933f92d093bb6662cbf2e34dcb0ec5c30a
MD5 e95bf0bfded5ca11e7a4e71adfab6712
BLAKE2b-256 bdbe6330d2afa101fda693dc4e2400b1a0e9c0144aacd93fbe6083b3d8bbc0c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1-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.0a1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bac5009535bd3173c4b52a8650e0e378f9501c9f5fba8c6f5d3c623a7859513a
MD5 42966cfc25c8dbd8633a48c61142f4aa
BLAKE2b-256 5899320f0b6384f10110edc632205ceb0a6b76ab7a9d5c3997d14d00fb9b1584

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1-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.0a1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.4.0a1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5fe5b5a6fcb70a3b084025809fe6a31a4400d09e3d7e32f9e0a2485630360ab8
MD5 f921b7f29a3b7e729064b3abc1688bc2
BLAKE2b-256 8dfbce2b1030976d054099830c128196ed148c41e1b31deb9a9ebc2d1ac0b4e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.4.0a1-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