Skip to content

CMake: Build the MkDocs documentation site - #7719

Merged
petrasovaa merged 3 commits into
OSGeo:mainfrom
petrasovaa:cmake-mkdocs-site
Jul 16, 2026
Merged

petrasovaa merged 3 commits into
OSGeo:mainfrom
petrasovaa:cmake-mkdocs-site

Conversation

@petrasovaa

Copy link
Copy Markdown
Contributor

Follow-up to #7674, part of the transition to markdown-based documentation.

Make the markdown documentation tree generated by the CMake build complete enough to build the MkDocs site, and add build-mkdocs and serve-mkdocs targets matching the Autotools ones (both run mkdocs from PATH and are not part of the default build).

  • Copy the site files from man/mkdocs (mkdocs.yml, index and keywords pages, theme overrides, CSS, logo) into the markdown tree.
  • Add an MD_ONLY mode to generate_docs for the web-only guides from doc/ and doc/development/, which have no HTML source and no man page, and exclude those pages from man page generation with a new --exclude option in build_manpages.py.
  • Copy the assets linked from the pages (GUI icons, color tables, barscale and north arrow thumbnails, grass_logo.txt) into the markdown tree.
  • Narrow the doc/ paths-ignore of the CMake workflow to content file types, so changes to the CMakeLists.txt files now under doc/ trigger it.

Verified by building the site from a CMake build and comparing mkdocs warnings against the Autotools tree.

Generated with AI assistance (Claude Fable).

Make the markdown documentation tree complete enough to build the
MkDocs site, and add build-mkdocs and serve-mkdocs targets matching
the Autotools ones (both run mkdocs from PATH and are not part of the
default build).

Copy the site files from man/mkdocs (mkdocs.yml, index and keywords
pages, theme overrides, CSS, logo) into the markdown tree. Add an
MD_ONLY mode to generate_docs for the web-only guides from doc/ and
doc/development/, which have no HTML source and no man page. Exclude
those pages from man page generation with a new --exclude option in
build_manpages.py, derived from the doc/ directories like WEB_ONLY_MD
in man/Makefile. Copy the assets linked from the pages (GUI icons,
color tables, barscale and north arrow thumbnails, grass_logo.txt)
into the markdown tree alongside their existing html copies.

Narrow the doc/ paths-ignore of the CMake workflow to content file
types, so that changes to the CMakeLists.txt files now under doc/
trigger the workflow.

Generated with AI assistance (Claude Fable); verified by building the
site from a CMake build and comparing mkdocs warnings against the
Autotools tree.
@github-actions github-actions Bot added GUI wxGUI related CI Continuous integration Python Related code is in Python module docs display CMake labels Jul 15, 2026
@petrasovaa
petrasovaa requested review from nilason and wenzeslaus July 15, 2026 21:09

@wenzeslaus wenzeslaus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a AI-review you requested (reads as reasonable to me):

Overview

The PR completes the CMake markdown tree so mkdocs build can run against it, and adds build-mkdocs / serve-mkdocs targets mirroring the Autotools ones. Three mechanisms: a copy_mkdocs_files target for the site scaffolding (mkdocs.yml, overrides, theme assets), an MD_ONLY mode in generate_docs for web-only guides that have no .html source and no man page, and asset copies (icons, colortables, barscales, north arrows, grass_logo.txt) into the markdown tree.

The design is sound and the Autotools parity is real. The following were verified rather than assumed:

  • $<SEMICOLON> + cmake -E env works. In a scratch project, COPYRIGHT=&copy; 2003-2026 GRASS Development Team, ... and SITE_NAME come out byte-identical to what man/Makefile's build-mkdocs exports. The genex is the right fix for the ; list-separator problem, and the comment explaining it is worth keeping.
  • --exclude ${web_only_pages} expands correctly into separate argv entries.
  • add_custom_target(... DEPENDS <target-name>) does create a target-level dependency, despite the CMake docs describing DEPENDS as file-level. Confirmed with a scratch build; the codebase already relies on this (build_full_index DEPENDS ALL_MODULES).
  • MD_ONLY matches Autotools. include/Make/Html.make:9 builds $(MDDIR)/source/%.md through mkmarkdown.py, and doc/development/Makefile's default target asks only for the md files, no man pages. Dropping mkhtml/md2man from the MD_ONLY branch reproduces that exactly.
  • cmake_path needs CMake >= 3.20; the project requires 3.22 and utils/CMakeLists.txt:15 already uses it.
  • doc/**/*.md does match doc/grass_database.md (no intermediate directory), since GitHub's ** matches zero or more directories. The repo already depends on this in codeql-analysis.yml:11.

Findings

1. cmake_path(GET ... STEM ...) splits at the first dot, $(basename) at the last - man/CMakeLists.txt

The Makefile comment this mirrors uses $(basename $(notdir $(DOC_MD))), which strips only the final suffix. cmake_path's STEM without LAST_ONLY strips from the first dot. Verified:

/a/b/dotted.v2.md -> STEM='dotted' STEM_LAST_ONLY='dotted.v2'

No current doc page has a dot in its name, so this is latent. But the failure would be silent and in the wrong direction: a future doc/foo.v2.md would be excluded under the name foo, and build_manpages.py would emit a man page for a web-only guide. LAST_ONLY makes the CMake side match $(basename):

cmake_path(GET doc_file STEM LAST_ONLY page_name)

2. The comment claims automatic exclusion; file(GLOB) is configure-time - man/CMakeLists.txt

The guides are derived from the doc/ source directories so a newly added guide is excluded automatically

$(wildcard) re-evaluates on every make run, so the Makefile comment is true there. file(GLOB) without CONFIGURE_DEPENDS is evaluated once at configure time. In practice it works out, because a new guide also has to be added to doc/CMakeLists.txt to be generated at all, and that edit triggers a reconfigure. But the comment promises more than the code delivers. Either add CONFIGURE_DEPENDS, or reword to something like "excluded automatically once CMake reconfigures (which adding the guide to doc/CMakeLists.txt triggers)".

3. The paths-ignore enumeration is incomplete and slightly inconsistent - .github/workflows/cmake.yml

The comment correctly notes that paths-ignore does not support negation. But enumerating content types means the list has to be maintained, and it is already missing types that exist today: doc/grass_database.svg, doc/project.svg, doc/debugging.txt, doc/html_documentation.txt, plus .odg and .fig. Editing any of those now runs the full CMake matrix. It is also inconsistent in a way that reads as accidental: doc/**/*.py ignores doc/examples/python/**, while doc/examples/**/*.c and the example Makefiles do trigger.

The direction of the error is safe (extra CI runs, not missed ones), so this is not a blocker. But GitHub does support ! in the paths filter, which expresses the intent directly and never needs updating for a new file type:

    paths:
      - "**"
      - "!doc/**"
      - "doc/CMakeLists.txt"
      - "doc/**/CMakeLists.txt"

The tradeoff is that paths and paths-ignore are mutually exclusive per event, and "**" is a blunt opener. If paths-ignore is preferred, adding doc/**/*.svg and doc/**/*.txt would cover the known gaps.

4. build-mkdocs does not depend on the docs being generated - man/CMakeLists.txt

It depends only on copy_mkdocs_files, so cmake --build build --target build-mkdocs on a fresh tree renders a site from a source directory holding nothing but the scaffolding. Autotools has the same shape (build-mkdocs: has no prerequisites), so this is parity rather than a regression, and in a normal workflow the default build has already run. Still, CMake makes the fix nearly free (DEPENDS copy_mkdocs_files build_check), and it would turn a confusing empty site into a correct one. Worth a deliberate decision either way; if the answer is parity with Autotools, the existing comment could say so.

Nits

  • generate_docs.cmake: the MD_ONLY branch duplicates the D_TARGET branch. Ten lines, and the shared prefix (md_descr_command, mkmarkdown_cmd, copy_images_command_md, tmp cleanup) is identical. A later fix to the markdown pipeline in the first branch could easily miss the second. Low urgency given the size, but this is a shared helper.
  • generate_docs.cmake docs. [MD_ONLY] is added to the generate_docs signature but only described in the generate_docs_list paragraph above it. A one-line description under generate_docs would close that.
  • MD_ONLY is silently ignored when generate_docs is called with OUTPUT instead of TARGET. Only generate_docs_list uses it today, and it always passes TARGET, so this is fine. Noted only so the boundary is known.
  • The colortables copy sits outside the WITH_DOCS guard (CMakeLists.txt). r_colors_thumbnails is defined after the if(WITH_DOCS) block, so a -DWITH_DOCS=OFF build now populates docs/mkdocs/source/colortables. Harmless, since GRASSInstallDirs.cmake:130 creates the directory unconditionally anyway; just untidy.

Risk and coverage

Low risk overall: build plumbing only, no runtime code, and no new dependency in the default build (mkdocs is only invoked by the two on-demand targets).

One coverage observation, not a request: nothing in CI exercises build-mkdocs. documentation.yml builds the site from an Autotools tree and invokes mkdocs build directly rather than going through the build-mkdocs target, so neither build system's target is tested. This parity is therefore maintained by hand and can rot quietly. The PR body says it was verified by comparing mkdocs warnings against the Autotools tree, which is the right check; it is just not repeatable by CI.

The asset list cross-checks out: documentation.yml:213-219 copies every directory under ${MKDOCS_DIR}/source into addons, which is exactly the set this PR adds (colortables, icons, barscales, northarrows), so the CMake tree should produce the shape the site build expects.

Nothing here blocks merge. Findings 1 and 2 are the two worth fixing first, since both are small and both are cases of the code not matching what the comment claims.

@petrasovaa

Copy link
Copy Markdown
Contributor Author
  1. STEM vs basename: fixed with LAST_ONLY.
  2. Glob comment: reworded to say exclusion applies after a reconfigure (which adding a guide to doc/CMakeLists.txt triggers anyway); CONFIGURE_DEPENDS didn't seem worth the per-build glob re-check.
  3. paths-ignore: switched to the suggested paths + negation form — nothing under doc/ except the CMakeLists.txt files affects this build, so it expresses the intent directly and needs no maintenance.
  4. build-mkdocs dependencies: added build_check to both build-mkdocs and serve-mkdocs, with a comment noting the deliberate difference from Autotools.

Nits: added an MD_ONLY description to the generate_docs docs (also documents that it only applies with TARGET). Left the MD_ONLY branch duplication as is — the branches converge once the html halves are removed in the html-removal phase. The colortables copy outside WITH_DOCS mirrors the pre-existing unguarded r_colors_thumbnails target; that spot gets restructured in the same phase.

On CI coverage of build-mkdocs: agreed, a smoke test is on the list as a follow-up once the site ships in the distribution.

@wenzeslaus wenzeslaus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looking forward to see this in action.

@petrasovaa
petrasovaa enabled auto-merge (squash) July 16, 2026 13:00

@nilason nilason left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: "The colortables copy sits outside the WITH_DOCS guard" issue –– the color tables are not only used as documentation but by r.colors tool ( I believe it was), so they need to be installed with/without WITH_DOCS. This will by the way necessitate a duplication of the files with FHS installation.

@petrasovaa
petrasovaa merged commit 36f3025 into OSGeo:main Jul 16, 2026
27 checks passed
@github-actions github-actions Bot added this to the 8.6.0 milestone Jul 16, 2026
@petrasovaa
petrasovaa deleted the cmake-mkdocs-site branch July 17, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI Continuous integration CMake display docs GUI wxGUI related module Python Related code is in Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants