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.0a2.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.0a2-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

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

File metadata

  • Download URL: inclean-0.4.0a2.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.0a2.tar.gz
Algorithm Hash digest
SHA256 18bd4e4fe2c8b6b5533174bdd7fe75550c01e717d666b8b3b8a36ee880a1a618
MD5 c6337492218127d345b158b1c9cdd7d6
BLAKE2b-256 9da656ef9ca81c3de4fdf12d14ba9c02e734d6c8d0c1ad23511bb19ac329b6ca

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: inclean-0.4.0a2-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.0a2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d17e2dbf3da8c80524f6e8a4293adb8ec9c8a4638e8a222a0bb5354a0bb60805
MD5 85ca084555d85bfa399380490de48f15
BLAKE2b-256 afaaf41162a9d1793a0694a98914b1cce5b99869f7d476ddba2ca4209f1868ce

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for inclean-0.4.0a2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f76f48a2ccf36b6d474f146cf1a629239c1b20237d6f03e5c01b6ffe0938177c
MD5 2e6c21cd21816287fb09781a713c6ab6
BLAKE2b-256 c62abfed3859e6010fe3c9a4688be79d31cd85675bc3dad57b0e75f0be90f7c1

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for inclean-0.4.0a2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 aab98db73f5185336a940d7126c0972fcd9bd0bc87a4cf0ed0ca04880c9d2daa
MD5 4bc1235cee753d41f624cd9b2ecc4577
BLAKE2b-256 0da7908216286521b908f71bf92bbee065700e36bff470001ac79e81db2ab0c9

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for inclean-0.4.0a2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7975c4a8fe08e19b3ec49f73c4cc17882d7075d4eb22a10c80755ac9fe2de7ea
MD5 a6291ddd77d6276bd738ee23b537e0c6
BLAKE2b-256 de018ba8c3995795ada3cf637a03ba2df9ed8974bd7257daa4233c886005e9f5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for inclean-0.4.0a2-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f6f5ab7a8aa891a7a48eb1adfd7913c37e98a92a98258f7d605ad4239c5861d7
MD5 029689649f40112a9dc42158e50f093b
BLAKE2b-256 efe5bde161cc7078db0954716a0d522417d6c50f1afd25745aab11ed1fd120f3

See more details on using hashes here.

Provenance

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