{"id":51396036,"url":"https://github.com/halide/cmtk","last_synced_at":"2026-07-04T02:33:09.485Z","repository":{"id":360524337,"uuid":"1250546756","full_name":"halide/cmtk","owner":"halide","description":"CMake ToolKit (for Halide)","archived":false,"fork":false,"pushed_at":"2026-06-08T18:19:25.000Z","size":267,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-04T02:33:07.623Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/halide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-26T18:33:38.000Z","updated_at":"2026-06-08T18:19:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/halide/cmtk","commit_stats":null,"previous_names":["halide/cmtk"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/halide/cmtk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halide%2Fcmtk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halide%2Fcmtk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halide%2Fcmtk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halide%2Fcmtk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/halide","download_url":"https://codeload.github.com/halide/cmtk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halide%2Fcmtk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35108298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-04T02:33:06.423Z","updated_at":"2026-07-04T02:33:09.476Z","avatar_url":"https://github.com/halide.png","language":"CMake","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cmtk 🛠️\n\n[![Rust](https://img.shields.io/badge/rust-2024-orange.svg)](https://www.rust-lang.org)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n`cmtk` (CMake Toolkit) is a high-performance, schema-driven CMake code formatter and analyzer built in Rust. It utilizes a lossless Concrete Syntax Tree (CST) pipeline to guarantee that formatting operations never destroy comments, whitespace, or any other source details.\n\nUnlike general-purpose formatters or simple regular-expression tools, `cmtk` formats CMake files according to known function signature schemas. It can automatically discover schemas for custom CMake functions/macros by analyzing the codebase (e.g. looking for uses of `cmake_parse_arguments`), allowing for precise, semantic layouts without tedious manual configuration.\n\n---\n\n## Key Features\n\n- **Lossless CST Architecture**: Built on top of the [Rowan](https://github.com/rust-analyzer/rowan) library (used in `rust-analyzer`) and the [Logos](https://github.com/maciejhirsz/logos) lexer. The formatting pipeline guarantees `tree.to_string() == original_source` prior to styling, meaning comments, bracket arguments, and trivia are fully preserved.\n- **Schema-Driven Formatting**: Employs structural layouts based on CMake commands' signatures. It distinguishes positional arguments, options (flags), one-value keywords, and list keywords.\n- **Auto-Schema Discovery**: The `cmtk scan` subcommand inspects your macros and functions, parsing their inner `cmake_parse_arguments` calls to automatically generate configuration schemas.\n- **Advanced List Wrapping Rules**:\n  - **Packed**: Packed by width (default for target names, components).\n  - **Path**: One-per-line formatting for file lists, keeping singletons inline.\n  - **Command Arguments (`command_argv`)**: Retains executable and initial flags on the same line, wrapping trailing arguments.\n  - **N per Line**: Groups arguments into sets of `n` (e.g., `n = 2` for properties key-value pairs).\n- **Searchability Preservation**: Keeps the first argument (e.g., target names in `set_target_properties`, or variable names in `set` / `option`) on the opening line to maintain searchability via simple tools like `grep`.\n- **Configurable**: Settings are easily configured using a `.cmtkrc` file or a `[tool.cmtk]` section in `pyproject.toml`.\n\n---\n\n## Installation\n\nEnsure you have the Rust toolchain installed. Build the project using `cargo`:\n\n```bash\ngit clone https://github.com/halide/cmtk.git\ncd cmtk\ncargo build --release\n```\n\nThe resulting binary will be available at `target/release/cmtk`.\n\n---\n\n## Usage\n\n`cmtk` provides a CLI with three subcommands: `format`, `scan`, and `parse`.\n\n### 1. Formatting Files\n\nTo format a CMake file and print the result to stdout:\n```bash\ncmtk format CMakeLists.txt\n```\n\nTo format files in-place:\n```bash\ncmtk format -i CMakeLists.txt src/CMakeLists.txt\n```\n\nTo check if files are formatted (useful in CI pipelines):\n```bash\ncmtk format --check CMakeLists.txt\n```\n\n#### Automated Schema Discovery during Format\nYou can point the formatter to files containing custom definitions (`--scan-only`) to teach it your custom command signatures on-the-fly:\n```bash\ncmtk format CMakeLists.txt --scan-only cmake/MyMacros.cmake\n```\n\nYou can also instruct it to find all CMake files in your Git repository automatically:\n```bash\ncmtk format CMakeLists.txt --discover=git\n```\n\n### 2. Scanning / Schema Discovery\n\nTo scan custom CMake files, extract schemas, and output them in TOML:\n```bash\ncmtk scan cmake/MyMacros.cmake\n```\n\nTo write/append the scanned schemas directly to your local `.cmtkrc`:\n```bash\ncmtk scan cmake/MyMacros.cmake --write\n```\n\n### 3. Parsing (Debug representation)\n\nTo inspect the raw lossless syntax tree produced by the parser:\n```bash\ncmtk parse CMakeLists.txt\n```\n\n---\n\n## Formatting Style Guidelines\n\nFor multiline commands, `cmtk` avoids visually random continuation indentation or alignment under the opening parenthesis. Instead, it aligns the closing parenthesis with the command name and applies block indentation.\n\n### Preferred (Block Indentation)\n```cmake\nfind_package(\n    Halide_LLVM 21...99 REQUIRED\n    COMPONENTS WebAssembly X86\n    OPTIONAL_COMPONENTS AArch64 ARM Hexagon NVPTX PowerPC RISCV\n)\n```\n\n### List Layouts (`list_type`)\n\n* **`packed`** (Default): Packs items as long as they fit the line, wrapping them when they exceed the limit:\n  ```cmake\n  target_link_libraries(\n      MyTarget\n      PUBLIC Halide_Runtime Halide_Headers Halide_Compiler Halide_Tools\n      PRIVATE LLVMCore LLVMSupport LLVMAnalysis LLVMTarget\n  )\n  ```\n* **`path`**: Paths format one-per-line when multiple, but singletons stay inline.\n\n  When there are multiple keyword blocks, they are all indented:\n  ```cmake\n  target_sources(\n      MyTarget\n      PUBLIC\n          include/Halide.h\n          include/HalideBuffer.h\n      PRIVATE\n          src/Argument.cpp\n          src/Bounds.cpp\n          src/Buffer.cpp\n  )\n  ```\n\n  When a list is at the end of the argument list (the last block) and no prior blocks were indented, it is flattened/de-dented to align with the keyword:\n  ```cmake\n  target_sources(\n      MyTarget\n      PRIVATE\n      src/file1.cpp\n      src/file2.cpp\n      src/file3.cpp\n  )\n  ```\n\n  Similarly, if a singleton path is too long to fit inline and is in the last block, it wraps and is de-dented:\n  ```cmake\n  target_sources(\n      MyTarget\n      PRIVATE\n      extremely/long/path/to/some/nested/source/file/that/will/definitely/exceed/the/column/limit/to/verify/the/dedented/singleton/rule.cpp\n  )\n  ```\n* **`n_per_line`** (e.g. `n = 2` for property pairs):\n  ```cmake\n  set_target_properties(MyTarget\n      PROPERTIES\n      CXX_STANDARD 17\n      CXX_STANDARD_REQUIRED YES\n      EXPORT_NAME MyTarget\n  )\n  ```\n\n---\n\n## Configuration\n\n`cmtk` automatically discovers configuration by searching for `.cmtkrc` in the current directory first, then fallback to `[tool.cmtk]` in `pyproject.toml`.\n\n### Configuration Options\n\n| Option | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `indent_style` | string | `\"space\"` | Indentation style: `\"space\"` or `\"tab\"` |\n| `indent_width` | integer | `4` | Indent size in spaces |\n| `line_width` | integer | `100` | Target column boundary for wrapping |\n| `source_vertical_list_threshold` | integer | `3` | Number of items in the source after which packed lists are forced vertical (`-1` to disable) |\n| `function_schemas` | table | `{}` | Mappings of lowercase CMake functions to custom format schemas |\n\n### Example `.cmtkrc` (TOML)\n\n```toml\nindent_style = \"space\"\nindent_width = 4\nline_width = 100\nsource_vertical_list_threshold = 3\n\n[function_schemas.my_custom_install]\nno_break_first_argument = true\noptions = [\"FORCE\", \"VERBOSE\"]\none_value_keywords = [\"DESTINATION\", \"RENAME\"]\nmulti_value_keywords = [\n    { name = \"TARGETS\", list_type = \"packed\" },\n    { name = \"FILES\", list_type = \"path\" }\n]\n```\n\n### Example `pyproject.toml` integration\n\n```toml\n[tool.cmtk]\nindent_style = \"space\"\nindent_width = 4\nline_width = 80\n\n[tool.cmtk.function_schemas.add_halide_library]\nno_break_first_argument = true\none_value_keywords = [\"GENERATOR\"]\nmulti_value_keywords = [\n    { name = \"SOURCES\", list_type = \"path\" }\n]\n```\n\n---\n\n## Architecture Overview\n\n1. **`syntax.rs`**: Defines token and node types (`SyntaxKind`) via `logos` derive macros and implements the `rowan::Language` trait (`CmakeLanguage`).\n2. **`lexer.rs`**: Feeds tokens, whitespace, and comments to the parser.\n3. **`parser.rs`**: Lossless recursive-descent parser that constructs a `rowan::GreenNode` syntax tree.\n4. **`cst.rs`**: Strongly typed AST wrappers for raw Rowans (such as `CommandNode`).\n5. **`schema.rs`**: Definitions for schema representations of CMake commands.\n6. **`analyzer.rs`**: Infers custom schemas by analyzing local CMake source trees.\n7. **`formatter.rs`**: Implements the layout engine, making formatting decisions based on line widths and schemas.\n\n---\n\n## Development\n\nRun tests, check formatting, and lint with the following cargo commands:\n\n```bash\n# Run unit, integration, and golden tests\ncargo test\n\n# Force-update the golden test specs\nUPDATE_GOLDENS=1 cargo test\n\n# Verify formatting\ncargo fmt -- --check\n\n# Run lints\ncargo clippy -- -D warnings\n```\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE) or project files for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalide%2Fcmtk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhalide%2Fcmtk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalide%2Fcmtk/lists"}