cpdocs 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. {cpdocs-0.1.0 → cpdocs-0.2.0}/.github/workflows/docs.yml +2 -3
  2. {cpdocs-0.1.0 → cpdocs-0.2.0}/.github/workflows/test.yml +2 -0
  3. {cpdocs-0.1.0 → cpdocs-0.2.0}/PKG-INFO +13 -10
  4. cpdocs-0.2.0/docs/cpdocs.yml +17 -0
  5. cpdocs-0.2.0/docs/web/examples/index.md +24 -0
  6. cpdocs-0.2.0/docs/web/explanation/architecture.md +23 -0
  7. cpdocs-0.2.0/docs/web/explanation/feature-sets.md +21 -0
  8. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/how-to/ci.md +4 -3
  9. cpdocs-0.2.0/docs/web/how-to/feature-sets.md +44 -0
  10. cpdocs-0.2.0/docs/web/how-to/generated-headers.md +36 -0
  11. cpdocs-0.2.0/docs/web/how-to/other-build-systems.md +69 -0
  12. cpdocs-0.2.0/docs/web/how-to/properdocs.md +47 -0
  13. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/index.md +4 -4
  14. cpdocs-0.2.0/docs/web/reference/cli.md +30 -0
  15. cpdocs-0.2.0/docs/web/reference/cmake.md +58 -0
  16. cpdocs-0.2.0/docs/web/reference/configuration.md +49 -0
  17. cpdocs-0.2.0/docs/web/reference/contract.md +127 -0
  18. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/reference/extraction.md +15 -5
  19. cpdocs-0.2.0/docs/web/tutorials/first-reference.md +80 -0
  20. cpdocs-0.2.0/examples/basic-cpp/CMakeLists.txt +34 -0
  21. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/docs/api/index.md +1 -1
  22. cpdocs-0.2.0/examples/basic-cpp/docs/cpdocs.yml +20 -0
  23. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/docs/web/index.md +1 -1
  24. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/readme.md +1 -1
  25. cpdocs-0.2.0/examples/c-basic/CMakeLists.txt +33 -0
  26. cpdocs-0.2.0/examples/c-basic/docs/cpdocs.yml +17 -0
  27. cpdocs-0.2.0/examples/cpp-features/CMakeLists.txt +78 -0
  28. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/docs/api/index.md +1 -1
  29. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/docs/cpdocs-minibuild.yml +5 -3
  30. cpdocs-0.2.0/examples/cpp-features/docs/cpdocs.yml +25 -0
  31. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/docs/web/index.md +1 -1
  32. cpdocs-0.2.0/examples/cpp-features/readme.md +12 -0
  33. cpdocs-0.2.0/examples/cpp-features/tools/minibuild.py +62 -0
  34. cpdocs-0.2.0/examples/cpp-templates/CMakeLists.txt +32 -0
  35. cpdocs-0.2.0/examples/cpp-templates/docs/cpdocs.yml +21 -0
  36. cpdocs-0.2.0/examples/fortran-basic/CMakeLists.txt +26 -0
  37. cpdocs-0.2.0/examples/fortran-basic/docs/cpdocs.yml +17 -0
  38. cpdocs-0.2.0/examples/fortran-basic/docs/index.md +11 -0
  39. cpdocs-0.2.0/examples/fortran-basic/lib/normalize.f90 +14 -0
  40. cpdocs-0.2.0/examples/fortran-basic/mod/geometry.f90 +25 -0
  41. cpdocs-0.2.0/examples/fortran-basic/properdocs.yml +22 -0
  42. cpdocs-0.2.0/examples/fortran-basic/readme.md +9 -0
  43. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/CMakeLists.txt +22 -5
  44. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/docs/api/index.md +1 -1
  45. cpdocs-0.2.0/examples/generated-cpp/docs/cpdocs.yml +18 -0
  46. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/docs/web/index.md +1 -1
  47. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/readme.md +1 -1
  48. cpdocs-0.2.0/examples/mixed/CMakeLists.txt +61 -0
  49. cpdocs-0.2.0/examples/mixed/docs/cpdocs.yml +17 -0
  50. cpdocs-0.2.0/examples/python-basic/docs/cpdocs.yml +18 -0
  51. cpdocs-0.2.0/examples/rust-basic/Cargo.lock +7 -0
  52. cpdocs-0.2.0/examples/rust-basic/Cargo.toml +11 -0
  53. cpdocs-0.2.0/examples/rust-basic/docs/api.md +11 -0
  54. cpdocs-0.2.0/examples/rust-basic/docs/cpdocs.yml +16 -0
  55. cpdocs-0.2.0/examples/rust-basic/docs/index.md +14 -0
  56. cpdocs-0.2.0/examples/rust-basic/properdocs.yml +21 -0
  57. cpdocs-0.2.0/examples/rust-basic/readme.md +10 -0
  58. cpdocs-0.2.0/examples/rust-basic/rust-toolchain.toml +6 -0
  59. cpdocs-0.2.0/examples/rust-basic/src/geometry.rs +41 -0
  60. cpdocs-0.2.0/examples/rust-basic/src/internal.rs +9 -0
  61. cpdocs-0.2.0/examples/rust-basic/src/lib.rs +9 -0
  62. {cpdocs-0.1.0 → cpdocs-0.2.0}/properdocs.yml +14 -4
  63. {cpdocs-0.1.0 → cpdocs-0.2.0}/pyproject.toml +1 -2
  64. cpdocs-0.2.0/readme.md +36 -0
  65. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/__init__.py +1 -1
  66. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/build.py +256 -211
  67. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/clang_backend.py +29 -19
  68. cpdocs-0.2.0/src/cpdocs/cli.py +122 -0
  69. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/config.py +36 -56
  70. cpdocs-0.2.0/src/cpdocs/contract.py +330 -0
  71. cpdocs-0.2.0/src/cpdocs/fortran_backend.py +289 -0
  72. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/html_renderer.py +163 -181
  73. cpdocs-0.2.0/src/cpdocs/html_renderer.py.rej +12 -0
  74. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/model.py +26 -19
  75. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/properdocs_plugin.py +173 -7
  76. cpdocs-0.2.0/src/cpdocs/python_manifest.py +62 -0
  77. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/render.py +18 -10
  78. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/rust_backend.py +175 -23
  79. cpdocs-0.2.0/src/cpdocs/rust_manifest.py +281 -0
  80. cpdocs-0.2.0/src/cpdocs/versioning.py +86 -0
  81. {cpdocs-0.1.0 → cpdocs-0.2.0}/test/conftest.py +20 -24
  82. {cpdocs-0.1.0 → cpdocs-0.2.0}/test/test_api_reference.py +35 -37
  83. cpdocs-0.2.0/test/test_api_reference.py.rej +9 -0
  84. cpdocs-0.2.0/test/test_build.py +155 -0
  85. {cpdocs-0.1.0 → cpdocs-0.2.0}/test/test_config.py +25 -40
  86. cpdocs-0.2.0/test/test_contract.py +186 -0
  87. {cpdocs-0.1.0 → cpdocs-0.2.0}/test/test_examples.py +136 -42
  88. cpdocs-0.2.0/test/test_feature_set_signatures.py +112 -0
  89. {cpdocs-0.1.0 → cpdocs-0.2.0}/test/test_properdocs_core.py +66 -0
  90. cpdocs-0.2.0/test/test_rust_example.py +80 -0
  91. cpdocs-0.2.0/test/test_rust_provider.py +377 -0
  92. cpdocs-0.2.0/test/test_versioning.py +54 -0
  93. {cpdocs-0.1.0 → cpdocs-0.2.0}/uv.lock +0 -2
  94. cpdocs-0.1.0/docs/cpdocs.yml +0 -19
  95. cpdocs-0.1.0/docs/web/examples/index.md +0 -25
  96. cpdocs-0.1.0/docs/web/explanation/architecture.md +0 -20
  97. cpdocs-0.1.0/docs/web/explanation/variants.md +0 -17
  98. cpdocs-0.1.0/docs/web/how-to/generated-headers.md +0 -19
  99. cpdocs-0.1.0/docs/web/how-to/other-build-systems.md +0 -40
  100. cpdocs-0.1.0/docs/web/how-to/properdocs.md +0 -23
  101. cpdocs-0.1.0/docs/web/how-to/variants.md +0 -53
  102. cpdocs-0.1.0/docs/web/reference/cli.md +0 -28
  103. cpdocs-0.1.0/docs/web/reference/cmake.md +0 -51
  104. cpdocs-0.1.0/docs/web/reference/configuration.md +0 -67
  105. cpdocs-0.1.0/docs/web/reference/contract.md +0 -106
  106. cpdocs-0.1.0/docs/web/tutorials/first-reference.md +0 -88
  107. cpdocs-0.1.0/examples/basic-cpp/CMakeLists.txt +0 -14
  108. cpdocs-0.1.0/examples/basic-cpp/docs/cpdocs.yml +0 -28
  109. cpdocs-0.1.0/examples/c-basic/CMakeLists.txt +0 -14
  110. cpdocs-0.1.0/examples/c-basic/docs/cpdocs.yml +0 -25
  111. cpdocs-0.1.0/examples/cpp-features/CMakeLists.txt +0 -40
  112. cpdocs-0.1.0/examples/cpp-features/cmake/feature.cmake +0 -109
  113. cpdocs-0.1.0/examples/cpp-features/docs/cpdocs.yml +0 -33
  114. cpdocs-0.1.0/examples/cpp-features/readme.md +0 -12
  115. cpdocs-0.1.0/examples/cpp-features/tools/minibuild.py +0 -76
  116. cpdocs-0.1.0/examples/cpp-templates/CMakeLists.txt +0 -14
  117. cpdocs-0.1.0/examples/cpp-templates/docs/cpdocs.yml +0 -29
  118. cpdocs-0.1.0/examples/generated-cpp/docs/cpdocs.yml +0 -25
  119. cpdocs-0.1.0/examples/mixed/CMakeLists.txt +0 -26
  120. cpdocs-0.1.0/examples/mixed/cmake/feature.cmake +0 -109
  121. cpdocs-0.1.0/examples/mixed/docs/cpdocs.yml +0 -25
  122. cpdocs-0.1.0/examples/python-basic/docs/cpdocs.yml +0 -27
  123. cpdocs-0.1.0/readme.md +0 -32
  124. cpdocs-0.1.0/src/cpdocs/cli.py +0 -78
  125. cpdocs-0.1.0/src/cpdocs/contract.py +0 -407
  126. cpdocs-0.1.0/src/cpdocs/python_manifest.py +0 -84
  127. cpdocs-0.1.0/src/cpdocs/share/cmake/cpdocs.cmake +0 -464
  128. cpdocs-0.1.0/src/cpdocs/versioning.py +0 -201
  129. cpdocs-0.1.0/test/test_build.py +0 -158
  130. cpdocs-0.1.0/test/test_contract.py +0 -171
  131. cpdocs-0.1.0/test/test_versioning.py +0 -76
  132. cpdocs-0.1.0/tools/build_example_sites.py +0 -59
  133. cpdocs-0.1.0/tools/build_examples.py +0 -44
  134. {cpdocs-0.1.0 → cpdocs-0.2.0}/.gitignore +0 -0
  135. {cpdocs-0.1.0 → cpdocs-0.2.0}/LICENSES/Apache-2.0.txt +0 -0
  136. {cpdocs-0.1.0 → cpdocs-0.2.0}/REUSE.toml +0 -0
  137. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/api/index.md +0 -0
  138. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/reference/api.md +0 -0
  139. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/reference/comments.md +0 -0
  140. {cpdocs-0.1.0 → cpdocs-0.2.0}/docs/web/reference/links.md +0 -0
  141. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/.gitignore +0 -0
  142. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/docs/web/api.md +0 -0
  143. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/include/acme/math.hpp +0 -0
  144. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/properdocs.yml +0 -0
  145. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/basic-cpp/src/math.cpp +0 -0
  146. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/.gitignore +0 -0
  147. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/docs/api/index.md +0 -0
  148. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/docs/web/api.md +0 -0
  149. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/docs/web/index.md +0 -0
  150. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/include/ring/ring.h +0 -0
  151. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/properdocs.yml +0 -0
  152. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/readme.md +0 -0
  153. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/c-basic/src/ring.c +0 -0
  154. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/.gitignore +0 -0
  155. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/docs/web/api.md +0 -0
  156. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/include/demo/solver.hpp +0 -0
  157. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-features/properdocs.yml +0 -0
  158. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/.gitignore +0 -0
  159. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/docs/api/index.md +0 -0
  160. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/docs/web/api.md +0 -0
  161. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/docs/web/index.md +0 -0
  162. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/include/meta/meta.hpp +0 -0
  163. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/properdocs.yml +0 -0
  164. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/cpp-templates/readme.md +0 -0
  165. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/.gitignore +0 -0
  166. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/docs/web/api.md +0 -0
  167. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/generated-template/generated.hpp +0 -0
  168. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/include/acme/core.hpp +0 -0
  169. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/properdocs.yml +0 -0
  170. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/generated-cpp/src/generated.cpp +0 -0
  171. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/.gitignore +0 -0
  172. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/docs/api/index.md +0 -0
  173. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/docs/web/api.md +0 -0
  174. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/docs/web/index.md +0 -0
  175. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/include/geom/vector.hpp +0 -0
  176. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/properdocs.yml +0 -0
  177. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/python/pygeom/__init__.py +0 -0
  178. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/readme.md +0 -0
  179. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/mixed/src/geom.cpp +0 -0
  180. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/.gitignore +0 -0
  181. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/docs/api/index.md +0 -0
  182. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/docs/web/api.md +0 -0
  183. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/docs/web/index.md +0 -0
  184. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/properdocs.yml +0 -0
  185. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/pyproject.toml +0 -0
  186. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/readme.md +0 -0
  187. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/src/dice/__init__.py +0 -0
  188. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/src/dice/_rng.py +0 -0
  189. {cpdocs-0.1.0 → cpdocs-0.2.0}/examples/python-basic/src/dice/core.py +0 -0
  190. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/__main__.py +0 -0
  191. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/properdocs_core.py +0 -0
  192. {cpdocs-0.1.0 → cpdocs-0.2.0}/src/cpdocs/python_backend.py +0 -0
@@ -42,11 +42,10 @@ jobs:
42
42
  - uses: astral-sh/setup-uv@v6
43
43
  - name: Install toolchain for the C and C++ examples
44
44
  run: sudo apt-get install -y --no-install-recommends clang cmake ninja-build
45
+ - name: Install toolchain for the Rust example
46
+ run: rustup toolchain install nightly-2026-10-01 --profile minimal
45
47
  - name: Build documentation
46
48
  run: uv run properdocs build --strict
47
- # Each example is published below examples/<name>/ as its own versioned site.
48
- - name: Build example sites
49
- run: uv run python tools/build_example_sites.py --output build/site/examples
50
49
  - uses: actions/upload-pages-artifact@v3
51
50
  with:
52
51
  path: build/site
@@ -14,6 +14,8 @@ jobs:
14
14
  - uses: astral-sh/setup-uv@v6
15
15
  - name: Install toolchain for the C and C++ examples
16
16
  run: sudo apt-get install -y --no-install-recommends clang cmake ninja-build
17
+ - name: Install toolchain for the Rust example
18
+ run: rustup toolchain install nightly-2026-10-01 --profile minimal
17
19
  - name: Lint
18
20
  run: uv run ruff check && uv run ruff format --check
19
21
  - name: Test
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cpdocs
3
- Version: 0.1.0
4
- Summary: Semantic, versioned API documentation for C, C++, Python and Rust projects
3
+ Version: 0.2.0
4
+ Summary: Semantic, versioned API documentation for C, C++, CUDA, HIP, Fortran, Python and Rust projects
5
5
  Project-URL: Source, https://github.com/ambhora/cpdocs
6
6
  Author-email: Jayesh Badwaik <j.badwaik@fz-juelich.de>
7
7
  License-Expression: Apache-2.0
8
8
  Requires-Python: >=3.11
9
9
  Requires-Dist: markdown-it-py>=3
10
- Requires-Dist: packaging>=24
11
10
  Requires-Dist: pygments>=2.17
12
11
  Requires-Dist: pyyaml>=6
13
12
  Provides-Extra: properdocs
@@ -20,16 +19,19 @@ SPDX-License-Identifier: Apache-2.0
20
19
  -->
21
20
  # cpdocs
22
21
 
23
- cpdocs generates semantic, versioned API documentation for C, C++, Python and Rust projects.
22
+ cpdocs generates semantic, versioned API documentation for C, C++, CUDA, HIP, Fortran, Python and Rust projects.
24
23
 
25
- It asks the project's build system, through a small JSON contract, which variants of the API exist
26
- and how to read each of them. It then extracts every variant, Clang for C and C++, `ast` for Python
27
- and rustdoc JSON for Rust, merges them into one reference, and publishes one version per configured
28
- branch and tag. A CMake adapter ships with cpdocs; other build systems implement the same contract.
24
+ It asks the project's build system, through a small JSON contract, for the concrete feature sets to
25
+ document. It builds each feature set independently, consumes the resulting manifest, extracts the API
26
+ with Clang for C-family languages, source modules for Fortran, `ast` for Python or rustdoc JSON for
27
+ Rust, and merges the results. Implementation files from the manifest are kept in the file hierarchy
28
+ without becoming API entities.
29
+ Feature-set availability and API language are tracked independently. The versions
30
+ to publish are an explicit ordered list in `cpdocs.yml`.
29
31
 
30
32
  ```console
31
33
  cpdocs build # document the working tree into build/cpdocs/current
32
- cpdocs versions # document the configured branches and tags
34
+ cpdocs versions # document the configured versions
33
35
  properdocs build # project website with the versioned API mounted
34
36
  ```
35
37
 
@@ -45,4 +47,5 @@ uv run pytest
45
47
  uv run ruff check && uv run ruff format --check
46
48
  ```
47
49
 
48
- The C and C++ tests need `clang++`, `cmake` and `ninja`; they are skipped when these are missing.
50
+ The C and C++ tests need `clang++`, `cmake` and `ninja`. Building the Rust example/site also needs
51
+ the nightly toolchain pinned by `examples/rust-basic/rust-toolchain.toml`.
@@ -0,0 +1,17 @@
1
+ # SPDX-FileCopyrightText: 2026 cpdocs developers
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ contract: 3
4
+
5
+ build:
6
+ feature-sets: >
7
+ "{{python}}" -m cpdocs manifest python feature-sets
8
+ --source "{{source}}" --output "{{output-file}}"
9
+ build: >
10
+ "{{python}}" -m cpdocs manifest python build
11
+ --source "{{source}}" --feature-set "{{feature-set}}" --output "{{output-file}}"
12
+ --package cpdocs --package-source src/cpdocs
13
+
14
+ versions: [main]
15
+
16
+ site:
17
+ copyright: Copyright © cpdocs developers · Apache-2.0
@@ -0,0 +1,24 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Examples
6
+
7
+ Every directory in `examples/` is a standalone project with its own `docs/cpdocs.yml` and
8
+ ProperDocs site. The test suite builds them, and the root ProperDocs site mounts each example directly during its
9
+ own build. Each example site is versioned with its explicit `versions:` list.
10
+
11
+ | Example | Shows | Site |
12
+ | --- | --- | --- |
13
+ | `basic-cpp` | one compiled C++ library | [basic-cpp](basic-cpp/) |
14
+ | `cpp-templates` | specializations, concepts, requires-clauses, SFINAE and deduction guides | [cpp-templates](cpp-templates/) |
15
+ | `cpp-features` | feature-dependent API across three feature sets; the same project through `tools/minibuild.py` | [cpp-features](cpp-features/) |
16
+ | `generated-cpp` | headers generated during the build | [generated-cpp](generated-cpp/) |
17
+ | `c-basic` | a C library | [c-basic](c-basic/) |
18
+ | `mixed` | a C++ unit and a Python unit in one project | [mixed](mixed/) |
19
+ | `fortran-basic` | a Fortran module plus an implementation-only source file | [fortran-basic](fortran-basic/) |
20
+ | `python-basic` | a plain Python package, answered by `cpdocs manifest python` | [python-basic](python-basic/) |
21
+ | `rust-basic` | Cargo features plus nightly rustdoc JSON, with private implementation source still browseable | [rust-basic](rust-basic/) |
22
+
23
+ There is no separate example-site build step. Both `properdocs build` and `properdocs serve` build
24
+ these sites directly at `examples/<name>/`; during `serve`, they use the checked-out working tree.
@@ -0,0 +1,23 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Architecture
6
+
7
+ cpdocs is a pipeline with a single boundary to the outside:
8
+
9
+ 1. **Contract.** The build system enumerates concrete feature sets and builds one selected feature set at a time.
10
+ cpdocs only reads the resulting JSON files.
11
+ 2. **Extraction.** Each unit of each feature set becomes an API graph. The manifest's semantic
12
+ language (`c`, `cpp`, `cuda`, `hip`, ...) is kept separate from the parser frontend used to
13
+ extract it. Clang handles the current C-family frontends, `ast` handles Python, and rustdoc JSON
14
+ handles Rust.
15
+ 3. **Merge.** The graphs of all units of a feature set are combined; feature-set graphs are then
16
+ merged. Identical definitions accumulate feature-set availability, while definitions in different
17
+ semantic languages remain distinct API entries.
18
+ 4. **Rendering.** The merged graph becomes a standalone HTML site. Versions are rendered
19
+ independently and joined by `versions.json`.
20
+
21
+ The API graph, @apidocs::cpdocs.model.ApiGraph, is the only interface between the stages; the
22
+ whole pipeline for one ref is @apidocs::cpdocs.build.build_graph. Adding a language means adding an
23
+ extractor that produces it; adding a build system means implementing the contract.
@@ -0,0 +1,21 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Why the build system owns feature sets
6
+
7
+ Only the build system knows which feature combinations are valid, which generators must run, and
8
+ which headers are public in a concrete configuration. Repeating that knowledge in cpdocs would
9
+ create a second configuration language that inevitably drifts from the project.
10
+
11
+ cpdocs therefore consumes an enumerable list of **unnamed feature sets** and passes one selection
12
+ back to the build system at a time. It uses the feature list only to record availability.
13
+
14
+ Programming language is a separate property of the manifest unit. A `gpu` feature can expose a
15
+ `CUDA` unit; several different feature sets can expose the same CUDA definition; and a C++
16
+ definition can be available in every feature set. During merging, identical definitions accumulate
17
+ feature-set availability, while definitions with different semantic languages remain distinct.
18
+
19
+ Version policy is equally explicit: `versions:` is simply the ordered list of Git branches/tags to
20
+ publish. There is no second selector language for branches, tags, ranges, aliases, or feature-set
21
+ policies.
@@ -4,7 +4,7 @@ SPDX-License-Identifier: Apache-2.0
4
4
  -->
5
5
  # Build the documentation in CI
6
6
 
7
- cpdocs runs from a fresh checkout: it configures every variant of every selected ref itself. The
7
+ cpdocs runs from a fresh checkout: it builds every feature set of every selected ref itself. The
8
8
  checkout needs the history, tags and branches it documents, and the job needs Clang for C and C++
9
9
  units.
10
10
 
@@ -40,8 +40,9 @@ read from `CI_COMMIT_BRANCH`, `GITHUB_HEAD_REF` or `GITHUB_REF_NAME`, so the det
40
40
  CI job is documented as its working tree. `CPDOCS_CURRENT_BRANCH` overrides all three.
41
41
 
42
42
  A project may live in a subdirectory of its repository. Every ref is then checked out as a whole
43
- and the same subdirectory is documented; refs in which it does not exist are skipped. The examples
44
- in the cpdocs repository are published this way, with the branches and tags of cpdocs.
43
+ and the same subdirectory is documented. Because `versions` is explicit, a configured ref that does not
44
+ contain the project is an error rather than being silently skipped. The examples in the cpdocs repository
45
+ use this same mechanism.
45
46
 
46
47
  A build system that runs cpdocs itself passes its own build directory:
47
48
 
@@ -0,0 +1,44 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Document feature-dependent APIs
6
+
7
+ The build system owns the finite feature space worth documenting. cpdocs asks for the concrete
8
+ feature sets, builds each one independently, and records where each extracted definition exists.
9
+
10
+ Features and API languages are different concepts. With BESA, for example, a project can define a
11
+ host/GPU implementation choice and optional MPI independently:
12
+
13
+ ```cmake
14
+ foreach(_feature IN ITEMS host gpu mpi)
15
+ besa_add_feature("${_feature}")
16
+ endforeach()
17
+
18
+ besa_add_variant(implementation ONE_OF host gpu)
19
+ besa_add_variant(parallel ZERO_OR_ONE mpi)
20
+ besa_keyso_create_feature_set(supported PRODUCT implementation parallel)
21
+ besa_set_feature_set(supported)
22
+ ```
23
+
24
+ The resulting feature sets can be `host`, `host + mpi`, `gpu`, and `gpu + mpi`. The units selected
25
+ by those sets carry their own semantic language (`cpp`, `cuda`, and so on) in the manifest.
26
+
27
+ The cpdocs configuration repeats none of this project logic:
28
+
29
+ ```yaml
30
+ contract: 3
31
+ build:
32
+ feature-sets: >
33
+ cmake -S "{{source}}" -B "{{tmpdir}}"
34
+ -DBESA_CPDOCS_FEATURE_SETS_OUTPUT="{{output-file}}"
35
+ build: >
36
+ cmake -S "{{source}}" -B "{{tmpdir}}"
37
+ -DBESA_CPDOCS_FEATURE_SET="{{feature-set}}"
38
+ -DBESA_CPDOCS_MANIFEST_OUTPUT="{{output-file}}"
39
+ && cmake --build "{{tmpdir}}" --target besa.cpdocs
40
+ ```
41
+
42
+ If the same qualified function has a C++ definition and a CUDA definition, cpdocs renders two API
43
+ entries and marks them **C++** and **CUDA**. If the CUDA definition is identical in both `gpu` and
44
+ `gpu + mpi`, it is rendered once and both feature sets are listed in its availability section.
@@ -0,0 +1,36 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Document generated headers
6
+
7
+ Generated API files must exist before the build command returns. The project provider lists the
8
+ generated directory in `manifest.json` with `generated: true`, and the configured build command runs
9
+ the target that produces it before cpdocs starts extraction.
10
+
11
+ For example:
12
+
13
+ ```yaml
14
+ build:
15
+ build: >
16
+ cmake -S "{{source}}" -B "{{tmpdir}}" -G Ninja
17
+ -DCPDOCS_FEATURE_SET="{{feature-set}}"
18
+ -DCPDOCS_MANIFEST_OUTPUT="{{output-file}}"
19
+ && cmake --build "{{tmpdir}}" --target generate-api-header
20
+ ```
21
+
22
+ The corresponding manifest can expose both checked-in and generated API roots:
23
+
24
+ ```json
25
+ {
26
+ "id": "acme",
27
+ "language": "cpp",
28
+ "api": [
29
+ {"path": "/src/include"},
30
+ {"path": "/tmp/build/generated/include", "generated": true}
31
+ ]
32
+ }
33
+ ```
34
+
35
+ Generated files are rendered like other source files and marked as generated because they have no
36
+ location in the repository. The complete example is `examples/generated-cpp`.
@@ -0,0 +1,69 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Integrate another build system
6
+
7
+ A build system integrates with cpdocs by producing the two JSON files in the
8
+ [build-system contract](../reference/contract.md). cpdocs does not require CMake.
9
+
10
+ For example, a small project-specific adapter can be configured as:
11
+
12
+ ```yaml
13
+ contract: 3
14
+ build:
15
+ feature-sets: >
16
+ python tools/minibuild.py feature-sets "{{output-file}}"
17
+ build: >
18
+ python tools/minibuild.py build "{{feature-set}}" "{{output-file}}"
19
+ ```
20
+
21
+ The first command writes every configuration worth documenting. The second receives one selected
22
+ `feature-set.json`; it may configure, build, run generators, or inspect the build system in any way
23
+ needed before writing `manifest.json`.
24
+
25
+ Python projects can use cpdocs' bundled helper:
26
+
27
+ ```yaml
28
+ contract: 3
29
+ build:
30
+ feature-sets: >
31
+ "{{python}}" -m cpdocs manifest python feature-sets
32
+ --source "{{source}}" --output "{{output-file}}"
33
+ build: >
34
+ "{{python}}" -m cpdocs manifest python build
35
+ --source "{{source}}" --feature-set "{{feature-set}}" --output "{{output-file}}"
36
+ --package mypackage --package-source src/mypackage
37
+ ```
38
+
39
+ Rust projects need no project-local adapter. The bundled Cargo provider implements the same two
40
+ commands directly:
41
+
42
+ ```yaml
43
+ contract: 3
44
+ build:
45
+ feature-sets: >
46
+ cpdocs rust feature-sets
47
+ --source "{{source}}" --output "{{output-file}}"
48
+ build: >
49
+ cpdocs rust build
50
+ --source "{{source}}" --feature-set "{{feature-set}}" --output "{{output-file}}"
51
+ ```
52
+
53
+ The build command uses Cargo's nightly rustdoc JSON output. Pin a nightly toolchain with
54
+ `rust-toolchain.toml`, or pass `--toolchain nightly-YYYY-MM-DD` to both commands when a project
55
+ needs an exact schema version.
56
+
57
+ Without additional configuration, every Cargo feature is considered independent and becomes one
58
+ cpdocs feature set. For example, `simd` and `mpi` produce `features: [simd]` and `features: [mpi]`,
59
+ not their Cartesian product. If the real project supports coupled configurations, declare the exact
60
+ sets explicitly:
61
+
62
+ ```toml
63
+ [package.metadata.cpdocs]
64
+ feature-sets = [
65
+ ["mpi"],
66
+ ["cuda"],
67
+ ["mpi", "cuda"],
68
+ ]
69
+ ```
@@ -0,0 +1,47 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Mount the API in a ProperDocs site
6
+
7
+ The project website lives in `docs/web`; the plugin builds the versioned API and mounts it:
8
+
9
+ ```yaml
10
+ docs_dir: docs/web
11
+
12
+ plugins:
13
+ - search
14
+ - cpdocs:
15
+ mount: reference/api
16
+ ```
17
+
18
+ The plugin options and their defaults are `config: docs/cpdocs.yml`, `output: build` and
19
+ `mount: reference/api`. `properdocs serve` also documents the checked-out working tree in situ,
20
+ even when that branch is not selected by `versions.branches.include`. That working-tree version is
21
+ the default during the development server, so local and uncommitted API changes are immediately
22
+ visible. The plugin also registers the project source directories with ProperDocs' live-reload
23
+ server, so changing source files triggers a rebuild automatically. `properdocs build` keeps the
24
+ configured version-selection and default-version policy unchanged.
25
+
26
+ Pages refer to API entities with `@apidocs::demo::solve`; see
27
+ [semantic links](../reference/links.md). With `checks.broken-references: fail`, a reference to an
28
+ entity that does not exist fails the build.
29
+
30
+ ## Mount nested ProperDocs sites
31
+
32
+ A root site can ask the cpdocs plugin to build nested ProperDocs projects directly into the same
33
+ output tree:
34
+
35
+ ```yaml
36
+ plugins:
37
+ - cpdocs:
38
+ mount: reference/python-api
39
+ subsites:
40
+ - examples/basic-cpp
41
+ - examples/python-basic
42
+ ```
43
+
44
+ Each path is relative to the root `properdocs.yml` and must contain its own `properdocs.yml`. No
45
+ separate pre-build command is needed. `properdocs build` writes the nested site at that same path
46
+ under `site_dir`; `properdocs serve` does the same on every relevant live rebuild and gives the
47
+ nested cpdocs plugin the current-working-tree semantics used by the parent development server.
@@ -4,17 +4,17 @@ SPDX-License-Identifier: Apache-2.0
4
4
  -->
5
5
  # cpdocs
6
6
 
7
- cpdocs generates semantic, versioned API documentation for C, C++, Python and Rust projects. It
8
- reads declarations the way the compiler or interpreter sees them, merges every documented variant
7
+ cpdocs generates semantic, versioned API documentation for C, C++, CUDA, HIP, Fortran, Python and Rust projects. It
8
+ reads declarations the way the compiler or interpreter sees them, merges every documented feature set
9
9
  of the API into one reference, and publishes one directory per Git branch or tag.
10
10
 
11
11
  cpdocs does not know how a project is built. It asks the project's build system, through a small
12
- [contract](reference/contract.md), which variants exist and how to read each of them. CMake support
12
+ [contract](reference/contract.md), which feature sets exist and how to build each of them. CMake support
13
13
  ships with cpdocs; any other build system implements the same two JSON manifests.
14
14
 
15
15
  ```console
16
16
  cpdocs build # document the working tree
17
- cpdocs versions # document the configured branches and tags
17
+ cpdocs versions # document the configured versions
18
18
  properdocs build # build the project website with the API mounted
19
19
  ```
20
20
 
@@ -0,0 +1,30 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # Command line
6
+
7
+ ```text
8
+ cpdocs build [--config docs/cpdocs.yml] [--output build] [--label main]
9
+ cpdocs versions [--config docs/cpdocs.yml] [--output build]
10
+ cpdocs manifest python feature-sets ...
11
+ cpdocs manifest python build ...
12
+ cpdocs rust feature-sets --source <project> --output <feature-sets.json>
13
+ cpdocs rust build --source <project> --feature-set <feature-set.json> --output <manifest.json>
14
+ ```
15
+
16
+ `build` documents the working tree into `<output>/cpdocs/current`. It always documents every
17
+ feature set returned by `build.feature-sets`.
18
+
19
+ `versions` documents the exact ordered `versions:` list from `cpdocs.yml` into
20
+ `<output>/cpdocs/versions`.
21
+
22
+ `manifest python` is a small provider for plain Python projects.
23
+
24
+ `rust` is the built-in Cargo provider. `rust feature-sets` reads Cargo metadata. By default every
25
+ declared Cargo feature is treated as a disjoint feature set and documented once; projects that need
26
+ specific combinations can list them in `[package.metadata.cpdocs]`. `rust build` runs Cargo rustdoc
27
+ with nightly JSON output and writes a normal cpdocs manifest.
28
+
29
+ Feature-set inputs, manifests, scratch/build directories and command logs are kept below
30
+ `<output>/cpdocs/work/<version>/feature-sets/`.
@@ -0,0 +1,58 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # CMake integration
6
+
7
+ cpdocs does not inject a CMake module and does not add CMake commands to a project. A CMake project
8
+ or a build framework used by that project implements the same two-file
9
+ [build-system contract](contract.md) as any other build system.
10
+
11
+ A project-local provider can be as small as ordinary `CMakeLists.txt` code which writes
12
+ `feature-sets.json` when `CPDOCS_FEATURE_SETS_OUTPUT` is set and writes `manifest.json` when
13
+ `CPDOCS_FEATURE_SET` and `CPDOCS_MANIFEST_OUTPUT` are set. The checked-in C and C++ examples use
14
+ this pattern directly, so a normal CMake configuration exercises exactly the same project logic as
15
+ cpdocs.
16
+
17
+ For example, a project with one feature set can expose discovery with:
18
+
19
+ ```cmake
20
+ if(CPDOCS_FEATURE_SETS_OUTPUT)
21
+ file(WRITE "${CPDOCS_FEATURE_SETS_OUTPUT}" "{\n"
22
+ " \"cpdocs-feature-sets\": 1,\n"
23
+ " \"project\": {\"name\": \"${PROJECT_NAME}\", \"version\": \"${PROJECT_VERSION}\"},\n"
24
+ " \"feature-sets\": [{\"features\": []}]\n"
25
+ "}\n")
26
+ endif()
27
+ ```
28
+
29
+ and configure cpdocs with ordinary CMake invocations:
30
+
31
+ ```yaml
32
+ build:
33
+ feature-sets: >
34
+ cmake -S "{{source}}" -B "{{tmpdir}}" -G Ninja
35
+ -DCPDOCS_FEATURE_SETS_OUTPUT="{{output-file}}"
36
+ build: >
37
+ cmake -S "{{source}}" -B "{{tmpdir}}" -G Ninja
38
+ -DCPDOCS_FEATURE_SET="{{feature-set}}"
39
+ -DCPDOCS_MANIFEST_OUTPUT="{{output-file}}"
40
+ ```
41
+
42
+ A framework such as BESA can provide the contract natively. In that case the project does not need
43
+ cpdocs-specific provider code at all:
44
+
45
+ ```yaml
46
+ build:
47
+ feature-sets: >
48
+ cmake -S "{{source}}" -B "{{tmpdir}}"
49
+ -DBESA_CPDOCS_FEATURE_SETS_OUTPUT="{{output-file}}"
50
+ build: >
51
+ cmake -S "{{source}}" -B "{{tmpdir}}"
52
+ -DBESA_CPDOCS_FEATURE_SET="{{feature-set}}"
53
+ -DBESA_CPDOCS_MANIFEST_OUTPUT="{{output-file}}"
54
+ && cmake --build "{{tmpdir}}" --target besa.cpdocs
55
+ ```
56
+
57
+ The important boundary is the JSON contract, not CMake itself. cpdocs remains independent of BESA
58
+ and of any other build framework.
@@ -0,0 +1,49 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 cpdocs developers
3
+ SPDX-License-Identifier: Apache-2.0
4
+ -->
5
+ # cpdocs.yml
6
+
7
+ `docs/cpdocs.yml` contains only cpdocs orchestration and presentation policy. The build system owns
8
+ all project semantics: features, valid feature combinations, generated code, targets, headers and
9
+ sources.
10
+
11
+ A minimal configuration is:
12
+
13
+ ```yaml
14
+ contract: 3
15
+
16
+ build:
17
+ feature-sets: >
18
+ cmake -S "{{source}}" -B "{{tmpdir}}"
19
+ -DBESA_CPDOCS_FEATURE_SETS_OUTPUT="{{output-file}}"
20
+ build: >
21
+ cmake -S "{{source}}" -B "{{tmpdir}}"
22
+ -DBESA_CPDOCS_FEATURE_SET="{{feature-set}}"
23
+ -DBESA_CPDOCS_MANIFEST_OUTPUT="{{output-file}}"
24
+ && cmake --build "{{tmpdir}}" --target besa.cpdocs
25
+
26
+ versions: [main, v2.0.0, v1.0.0]
27
+ ```
28
+
29
+ The two commands are the whole build-system interface. `build.feature-sets` runs once per source
30
+ version. `build.build` runs once for every feature set returned by the first command.
31
+
32
+ | Key | Default | Meaning |
33
+ | --- | --- | --- |
34
+ | `build.feature-sets` | required | command that writes `feature-sets.json` |
35
+ | `build.build` | required | command that consumes one `feature-set.json` and writes one `manifest.json` |
36
+ | `versions` | `[main]` | exact branch/tag names to document, in publication/default order |
37
+ | `site.index` | `docs/api/index.md` | introduction of the API reference |
38
+ | `site.copyright` | project developers | footer text |
39
+ | `site.project-docs` | `auto` | URL of the project website |
40
+ | `api.hide.cpp-namespaces` | none | glob patterns of C++ namespaces omitted with their contents |
41
+ | `api.hide.python-modules` | `private` | `private` hides modules beginning with `_`; `none` shows them |
42
+ | `checks.undocumented` | `ignore` | `warn` or `fail` when public entities have no documentation |
43
+ | `checks.broken-references` | `warn` | `ignore`, `warn` or `fail` for unknown `@apidocs` targets |
44
+
45
+ The same current `cpdocs.yml` orchestration commands are used for every checkout in `versions`; old tags do not need to carry their own cpdocs configuration.
46
+
47
+ The first entry in `versions` is the default version of the published API site.
48
+ For local ProperDocs serving, the current working tree is temporarily placed first so uncommitted
49
+ changes are visible.