# C++ workspaces

Static CMake package discovery, version edits, internal link ordering, and current limits.

Source: https://semifold.noctisynth.org/docs/workspace/cpp/
Language: en



The built-in C++ adapter targets CMake projects that can be analyzed statically. It does not run CMake or try to interpret directories and targets that exist only at build time.

## Root project requirement [#root-project-requirement]

The project root must contain `CMakeLists.txt` with a numeric version in `project(...)`:

```cmake
project(my_library VERSION 1.4.0 LANGUAGES CXX)
```

A root project without `VERSION` cannot serve as the current C++ workspace entry point. The `project` name is the manifest name used for matching packages within the C++ workspace.

## Subproject discovery [#subproject-discovery]

Semifold recursively follows literal calls such as:

```cmake
add_subdirectory(libs/core)
```

An intermediate directory may only group other directories. Every reachable directory whose own `CMakeLists.txt` contains `project(... VERSION ...)` is discovered as a package.

To keep discovery deterministic and safe, the adapter does not interpret:

* subdirectories assembled from variables;
* generator expressions;
* paths downloaded or generated by scripts or the configure phase;
* relative paths that escape the project root.

A resolved path outside the project root fails discovery instead of reading an external project.

## Internal dependencies [#internal-dependencies]

The adapter recognizes a static call whose first argument is the current project name:

```cmake
target_link_libraries(my_library PRIVATE support_library)
```

When `support_library` is another discovered `project` name in the same workspace, an internal edge is created. `PUBLIC`, `PRIVATE`, and `INTERFACE` all affect dependency order only and do not automatically propagate versions.

The adapter does not guess relationships from variables, alias targets, generator expressions, or other indirect links. Add `depends-on` to Semifold configuration when a release must propagate.

## Version edits [#version-edits]

Semifold edits `project(... VERSION ...)` in the corresponding `CMakeLists.txt`. When the package directory also contains `vcpkg.json`, it synchronizes the root `version` field so the two public version sources do not drift.

The current CMake adapter accepts stable numeric versions only. Named channels such as `alpha`, `beta`, and `rc` are unsupported. Setting a named `channel` for a C++ package fails version planning; for custom prerelease formats, first evaluate whether a plugin and custom publish workflow can represent the complete format.

## Publishing [#publishing]

CMake describes a build graph but does not define one registry, so built-in discovery treats C++ packages as publishable by default. Set `publish = false` explicitly for a package that should not enter the registry flow. Semifold keeps checks, builds, uploads, and publish behavior in `[resolver.cpp]` command configuration and runs it in dependency order through the unified publish plan.

Use `smif publish --dry-run` to inspect preflight and command behavior. Commands run in the package directory. Put compound CMake configuration, packaging, or registry-client logic in a repository script instead of placing shell operators in `args`.

## When to use a plugin [#when-to-use-a-plugin]

The following cases are generally outside the built-in static rules:

* the version is not in `project(... VERSION ...)`;
* workspace members come from custom metadata or runtime scripts;
* internal dependencies use CMake logic that cannot be expanded statically;
* versions require non-numeric or custom prerelease formats.

A plugin can define discovery, inspection, and candidate version edits for these repositories. Publish commands remain in resolver configuration.

