From 38bd9314cc3992c285f0010b172aa61f253a7e61 Mon Sep 17 00:00:00 2001 From: "Christopher M. Punches" Date: Sat, 15 Aug 2026 20:45:47 -0400 Subject: [PATCH] Release version 1.0.0; keep generated documentation source-derived The project version moves to 1.0.0, which the library soname, the reported version, the test expectations, and the generated document filename all derive from. SOVERSION now matches the major version. The generated reference is built from the source and its documentation comments alone. Prose from docs/ was briefly part of the input and is removed: development notes are written and read on their own, and a generator that reproduces them adds nothing. The reference opens on a front page declared in the public header, followed by the module contract. One target builds it. Both PDF and HTML are produced by default, the finished documents land in the build tree under docs/pdf and docs/html, and the generators work in docs/tmp. The internal namespace is dpm_core, matching the artifact name as closely as a C++ identifier permits. --- CMakeLists.txt | 24 ++++++++++-------------- docs/DOCUMENTATION.md | 10 ++++++---- include/dpm/core.h | 15 +++++++++++++++ include/internal/context.hpp | 4 ++-- include/internal/modules.hpp | 4 ++-- include/internal/version.hpp | 4 ++-- src/context.cpp | 6 +++--- src/modules.cpp | 12 ++++++------ src/version.cpp | 4 ++-- 9 files changed, 48 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b28fb2f..a06b59f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.22) -project(dpm-core VERSION 0.1.0 LANGUAGES CXX) +project(dpm-core VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -159,7 +159,7 @@ set_tests_properties(cli_rejects_invalid_module PROPERTIES WILL_FAIL TRUE) # --------------------------------------------------------------------- # Code reference (Doxygen) — optional 'docs' target # --------------------------------------------------------------------- -option(DPM_DOCS_HTML "Generate the code reference in HTML" OFF) +option(DPM_DOCS_HTML "Generate the code reference in HTML" ON) option(DPM_DOCS_PDF "Generate the code reference as PDF (requires LaTeX)" ON) find_package(Doxygen) @@ -188,22 +188,18 @@ if(DOXYGEN_FOUND) set(DOXYGEN_GENERATE_LATEX NO) endif() - # OVERVIEW.md becomes the reference's front page, so the generated - # document opens on the project description instead of a bare index. - set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${CMAKE_CURRENT_SOURCE_DIR}/docs/OVERVIEW.md) - - doxygen_add_docs(docs-generate + # The reference is generated from the source and its documentation + # comments. The markdown in docs/ is written and read on its own and + # stays out of the input. + # One target, so `cmake --build --target docs` is the whole + # procedure and the IDE lists a single entry for it. The commands + # below run after Doxygen and place the finished documents. + doxygen_add_docs(docs ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src - ${CMAKE_CURRENT_SOURCE_DIR}/docs - COMMENT "Generating code reference with Doxygen" + COMMENT "Generating the code reference with Doxygen" ) - # The one target a user builds. Everything below hangs off it, so - # `cmake --build --target docs` produces finished documents. - add_custom_target(docs COMMENT "Building the code reference") - add_dependencies(docs docs-generate) - if(DPM_DOCS_PDF) find_program(PDFLATEX_EXECUTABLE pdflatex) if(PDFLATEX_EXECUTABLE) diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index ca33641..2884b01 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -1,6 +1,8 @@ # Generating the Code Reference -When Doxygen is present, the build offers a `docs` target that produces the reference from the documentation comments carried in the headers and sources, together with the markdown documents in `docs/`. OVERVIEW.md becomes its front page, and DESIGN.md, MODULES.md, CONSUMERS.md, BUILD.md, and this file follow as chapters ahead of the namespace, class, and file reference. +When Doxygen is present, the build offers a `docs` target that generates the API and source reference from the documentation comments carried in the headers and sources. It opens on a front page declared in `include/dpm/core.h`, followed by the module contract, then the namespace, class, and file reference. + +The markdown documents in this directory are written and read on their own and stay out of the generated reference. One command generates it: @@ -18,12 +20,12 @@ The finished documents land in `/docs/`: Doxygen and LaTeX both work under `docs/tmp/`, and the finished document is copied up into `docs/`. `cmake --build --target clean` removes the whole tree. -Two output formats are available as configure-time options: +Both formats are produced by default. Either can be turned off at configure time: - **`-DDPM_DOCS_PDF`** (default ON) — PDF reference, via Doxygen's native LaTeX output; requires `pdflatex` and `makeindex` -- **`-DDPM_DOCS_HTML`** (default OFF) — HTML reference +- **`-DDPM_DOCS_HTML`** (default ON) — HTML reference ``` -cmake -B -DDPM_DOCS_HTML=ON +cmake -B -DDPM_DOCS_PDF=OFF cmake --build --target docs ``` diff --git a/include/dpm/core.h b/include/dpm/core.h index 296aa2a..f1f8e90 100644 --- a/include/dpm/core.h +++ b/include/dpm/core.h @@ -320,6 +320,21 @@ DPM_API const char* dpm_last_error(dpm_ctx* ctx); /* Module contract (implemented by modules, called by libdpm-core) */ /* ------------------------------------------------------------------ */ +/** + * @mainpage libdpm-core.so — API reference + * + * This is the generated reference for libdpm-core.so, extracted from + * the source. It covers the public C API in , the library's + * internals, and the module contract. + * + * Start at core.h for the API a consumer or a module calls, and at + * @ref module_contract for what a module implements. + * + * The project's prose documentation — overview, design, build, module + * authoring, and consumer guide — lives in the docs/ directory of the + * repository and is read there. + */ + /** * @page module_contract The module contract * diff --git a/include/internal/context.hpp b/include/internal/context.hpp index f2d5359..caa8521 100644 --- a/include/internal/context.hpp +++ b/include/internal/context.hpp @@ -62,7 +62,7 @@ struct dpm_ctx { std::string last_error; }; -namespace dpmcore { +namespace dpm_core { /** * @brief Records a failure reason on the context @@ -82,4 +82,4 @@ void set_error(dpm_ctx* ctx, const std::string& msg); */ void load_config_dir(dpm_ctx* ctx); -} // namespace dpmcore +} // namespace dpm_core diff --git a/include/internal/modules.hpp b/include/internal/modules.hpp index f5f351a..13ed70d 100644 --- a/include/internal/modules.hpp +++ b/include/internal/modules.hpp @@ -64,7 +64,7 @@ struct dpm_cursor { */ void dpm_internal_unload(void* handle); -namespace dpmcore { +namespace dpm_core { /** * @brief Runs the full load-time validation sequence against a module @@ -81,4 +81,4 @@ std::unique_ptr validate_and_load(dpm_ctx* ctx, const std::string& name, std::string& reason); -} // namespace dpmcore +} // namespace dpm_core diff --git a/include/internal/version.hpp b/include/internal/version.hpp index 87b64be..a1bcdca 100644 --- a/include/internal/version.hpp +++ b/include/internal/version.hpp @@ -22,7 +22,7 @@ */ #pragma once -namespace dpmcore { +namespace dpm_core { /** * @brief Parses a strict X.Y.Z version string @@ -33,4 +33,4 @@ namespace dpmcore { */ bool parse_version(const char* s, long out[3]); -} // namespace dpmcore +} // namespace dpm_core diff --git a/src/context.cpp b/src/context.cpp index 52ec7a4..5725d19 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -139,7 +139,7 @@ void parse_config_file(dpm_ctx* ctx, const fs::path& file, } // namespace -namespace dpmcore { +namespace dpm_core { void set_error(dpm_ctx* ctx, const std::string& msg) { @@ -169,7 +169,7 @@ void load_config_dir(dpm_ctx* ctx) } } -} // namespace dpmcore +} // namespace dpm_core extern "C" { @@ -199,7 +199,7 @@ dpm_ctx* dpm_open(const dpm_open_overrides* overrides) ctx->config_dir = with_trailing_slash(overrides->config_dir); } - dpmcore::load_config_dir(ctx); + dpm_core::load_config_dir(ctx); /* Logging: config, then override. */ ctx->log_level = DPM_LOG_INFO; diff --git a/src/modules.cpp b/src/modules.cpp index f7710e8..45a0a40 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -70,7 +70,7 @@ void* resolve(void* handle, const char* symbol) } // namespace -namespace dpmcore { +namespace dpm_core { std::unique_ptr validate_and_load(dpm_ctx* ctx, const std::string& name, @@ -141,7 +141,7 @@ std::unique_ptr validate_and_load(dpm_ctx* ctx, return mod; } -} // namespace dpmcore +} // namespace dpm_core extern "C" { @@ -157,9 +157,9 @@ dpm_module* dpm_require(dpm_ctx* ctx, const char* name) } std::string reason; - auto loaded = dpmcore::validate_and_load(ctx, name, reason); + auto loaded = dpm_core::validate_and_load(ctx, name, reason); if (!loaded) { - dpmcore::set_error(ctx, std::string("module '") + name + + dpm_core::set_error(ctx, std::string("module '") + name + "': " + reason); return nullptr; } @@ -198,7 +198,7 @@ dpm_cursor* dpm_list_modules(dpm_ctx* ctx) std::error_code ec; if (!fs::is_directory(ctx->module_path, ec)) { - dpmcore::set_error(ctx, "module path is not a readable directory: " + + dpm_core::set_error(ctx, "module path is not a readable directory: " + ctx->module_path); return nullptr; } @@ -230,7 +230,7 @@ dpm_cursor* dpm_list_modules(dpm_ctx* ctx) mod = it->second.get(); } else { std::string reason; - auto loaded = dpmcore::validate_and_load(ctx, name, reason); + auto loaded = dpm_core::validate_and_load(ctx, name, reason); if (!loaded) { dpm_log(ctx, DPM_LOG_WARN, ("module '" + name + "' failed validation: " + diff --git a/src/version.cpp b/src/version.cpp index 4d09177..2beaef7 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -25,7 +25,7 @@ #include #include -namespace dpmcore { +namespace dpm_core { bool parse_version(const char* s, long out[3]) { @@ -60,4 +60,4 @@ bool parse_version(const char* s, long out[3]) return true; } -} // namespace dpmcore +} // namespace dpm_core