# cmake-init: generating a FetchContent-ready CMake project from prompts

> cmake-init is a Python-based project initializer that scaffolds CMake projects with separated developer and consumer targets. It is aimed at C and C++ authors who want install rules and package-manager friendly layouts without writing them by hand.

**friendlyanon/cmake-init** — The missing CMake project initializer

- Repository: https://github.com/friendlyanon/cmake-init
- Stars: 2,548 · Forks: 94
- Language: CMake
- License: GPL-3.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/friendlyanon-cmake-init

## The gap cmake-init fills between an empty directory and a packagable CMake project

Writing a CMakeLists.txt that builds locally is easy. Writing one that a package maintainer can consume without patching is not. The README states the project's purpose directly: it generates CMake projects which are FetchContent ready, with separate consumer and developer targets, install rules, and proper relocatable CMake packages. That is a specific set of properties, and each one has its own failure mode when hand-written. A missing install rule means the library cannot be packaged. A single set of targets shared between local development and downstream consumption means warning flags and test dependencies leak into the consumer's build. cmake-init exists to make those defaults rather than afterthoughts.

The intended audience is C and C++ developers who are starting a new project and are willing to accept the author's opinions about layout. The README calls the tool opinionated, and the goals list explains why: the script lets you mash enter to get a correctly set up executable project, with single-letter answers for header-only and static or shared library variants. The non-goals matter just as much. Covering every possible project structure is explicitly rejected, on the grounds that if you have special needs you already know CMake and can set the project up yourself. This is a tool for the common case, not a general-purpose build system generator.

## How the generator is structured and what it produces

cmake-init is a Python package distributed on PyPI, and the repository keeps the generated content separate from the script that copies it: the top-level entries include cmake-init/ for the Python code, package/ for the project templates, tools/ and hooks/ alongside COPYING and README.md. The README points readers to the wiki for example outputs, so the canonical way to see what you get is to generate a project rather than read a specification.

The output is a CMake project targeting modern CMake, defined in the goals as 3.14 and newer. The two structural ideas are FetchContent readiness and the developer/consumer split. FetchContent readiness means another CMake project can pull yours in as a dependency; the README ties this to the expectation that CMake may eventually consume projects as trivially as npm does. The target split means a developer can run tests, add warning flags and run benchmarks while a consumer, such as a package maintainer, builds only the library or executable. Presets are the mechanism that keeps those two modes apart, and the README shows VSCode and CLion integrating with minimal configuration by selecting the dev preset.

The generated project also wires in optional tooling: clang-tidy, cppcheck, Doxygen with m.css, LCOV for gcov coverage, clang-format, codespell, and Conan or vcpkg. Each is opt-in at generation time, and the README is explicit that CI always runs clang-tidy and cppcheck regardless, so installing them locally is convenient rather than required.

## Installing cmake-init and generating your first project

The README lists the prerequisites plainly: Python 3.8 or newer, CMake 3.20 or newer (3.21 or newer for C17 or newer projects), and git. The optional tools are clang-tidy 18, cppcheck, Doxygen below 1.9, LCOV, clang-format 18, codespell, and Conan or vcpkg. Install the package from PyPI with pip:

```bash
pip install cmake-init
```

After that, the script is interactive. The README describes the flow as answering prompts, where pressing enter gives you a correctly set up executable project, `h` selects a header-only library, and `s` selects a static or shared library. Run it in the directory where you want the project created and answer the questions about project name, type and optional tooling.

One detail worth knowing before you start: the README states that some of the optional tools work on Windows with Visual Studio only through add-ins, linking clangpowertools.com and the cppcheck Visual Studio add-in. If you want clang-tidy or cppcheck to actually run locally on Windows, the README requires Ninja as the generator, because CMake supports those tools only with Makefiles and Ninja. For other generators the feature is a no-op, which is a quiet failure rather than an error. Set the generator field in your dev preset accordingly:

```json
{
  "version": 3,
  "configurePresets": [
    { "name": "dev", "generator": "Ninja" }
  ]
}
```

Once generated, the README describes a docs target in developer mode that builds documentation into the binary directory's docs/html folder, and a docs job in the generated CI workflow that can deploy to GitHub Pages after you follow the comments left in the job.

## Where cmake-init stops being the right answer

The most honest limitation is the one the author states as a non-goal: the tool does not try to cover every possible project structure. If your build has requirements outside the templates, you are expected to write CMake yourself. There is no supported path described in the README for extending the generator to a custom layout, which means a project with an unusual source tree, a nonstandard packaging story, or a build that must integrate with an existing superbuild will spend more time fighting the template than writing the file from scratch.

The optional tooling has sharper edges. Doxygen support depends on m.css, and the README states that m.css does not work with Doxygen 1.9 or newer, recommending 1.8.20 instead and pointing to issues 41 and 48. That is a pinned dependency on an older release, and it affects anyone who wants the docs target. On Windows, clang-tidy and cppcheck integration only functions with Makefiles or Ninja as the generator; with anything else the option silently does nothing. If you select those tools and then wonder why no analysis runs, the generator choice is the first thing to check.

There is also a version floor that is easy to miss: CMake 3.20 or newer, and 3.21 or newer if you want C17 or later. A machine with an older CMake will not be able to configure the generated project even though the generated CMake itself claims compatibility with 3.14 and newer. Those two numbers describe different things, and conflating them is a common source of confusion.

## How it compares with copying a known-good project or using a full build framework

The obvious alternative is to copy an existing project that already has install rules and presets, strip out its source, and rename things. That gives you exactly the layout you have already reviewed, and it costs nothing to set up. The difference is maintenance: a copied skeleton carries whatever CMake version, preset schema and CI configuration it had when you copied it, and nothing tells you when upstream practice moves on. cmake-init is a versioned package on PyPI with releases tracked in the repository, so regenerating a project or comparing against a fresh generation is a concrete operation rather than an archaeology exercise.

A second alternative is a build framework that generates the build description from a higher-level specification, such as a meta-build system that emits CMake. Those tools own more of the build and can express things cmake-init deliberately refuses to, but they also insert themselves between you and CMake. Since the point of cmake-init is that the output is ordinary modern CMake that a package maintainer can consume unmodified, a meta-build layer works against that goal. The README's framing is that outdated and plainly wrong CMake examples are widespread and the tool exists to produce correct ones, not to hide CMake behind an abstraction.

The narrower comparison is with the package managers the templates integrate with. Conan and vcpkg are optional at generation time and are listed as prerequisites rather than dependencies. cmake-init does not replace them; it produces a project that is easier for them to package.

## Licence, maintenance and the cost of regenerating

cmake-init is licensed under GPL-3.0, and the repository carries the COPYING file at the top level. The practical question for most readers is what the licence means for generated projects. The README does not address the licensing of generated output, and no exception for it is stated, so anyone intending to ship generated code under different terms should read COPYING and the project's own statements rather than assume. This is a question for your own legal review, not something the README settles.

On maintenance, the last push to the default branch was on 2026-04-15, and the most recent release listed is v0.41.1 from 2025-02-17, preceded by v0.41.0 on 2025-01-12 and v0.40.9 on 2024-09-12. The repository is not archived. Release cadence in that window is uneven: roughly nine months separate v0.40.9 from v0.41.0, and the gap between the last release and the last push is several months. That is not abandonment, but it does mean you should not expect fixes to land on a tight schedule.

The upgrade cost is mostly in the generated projects, not the tool. Because the output is a snapshot of the templates at generation time, an existing project does not inherit new template behaviour when you upgrade cmake-init. Regenerating gives you a fresh project, and merging that into a repository with real source and history is manual work. Teams that adopt this should decide up front whether they treat the generated files as a starting point they now own, or as something they intend to regenerate periodically. The README does not document a rollback or upgrade path between generated versions.

## Conclusion

Adopt cmake-init if you are starting a C or C++ library or executable and want install rules, presets and separated consumer and developer targets from the first commit. Skip it if your build is unusual enough that you already know CMake well, since the README lists covering every project structure as a non-goal. Before committing to it, install Python 3.8 or newer and CMake 3.20 or newer, run the prompt once, and read the generated CMakeLists.txt and preset files to confirm the layout matches how your project will be consumed.

## FAQ

### How do I install cmake-init?

Install it from PyPI with pip, as shown in the README: pip install cmake-init. You need Python 3.8 or newer, CMake 3.20 or newer, and git, with CMake 3.21 or newer if you want C17 or later projects.

### What does cmake-init generate by default?

The README states that pressing enter at the prompts produces a correctly set up executable project, while answering h gives a header-only library and s gives a static or shared library. The generated projects are FetchContent ready and separate developer and consumer targets.

### Does cmake-init work on Windows with Visual Studio?

The README notes that some optional tools work on Windows with Visual Studio only through add-ins, and that clang-tidy and cppcheck require Ninja as the generator because CMake supports them only with Makefiles and Ninja. With other generators the feature is a no-op.

### Why does the docs target fail with a newer Doxygen?

The generated documentation uses m.css, and the README states that m.css does not work with Doxygen 1.9 or newer, recommending 1.8.20 instead and referencing issues 41 and 48. The doxygen executable also has to be on PATH or you may see confusing error messages.

## Sources

- [friendlyanon/cmake-init on GitHub](https://github.com/friendlyanon/cmake-init)
- [Issues](https://github.com/friendlyanon/cmake-init/issues)
- [License: GPL-3.0](https://github.com/friendlyanon/cmake-init/blob/master/LICENSE)
- [README](https://github.com/friendlyanon/cmake-init/blob/master/README.md)
- [Releases](https://github.com/friendlyanon/cmake-init/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/friendlyanon-cmake-init
