Share Doxygen docs

Doxygen is the default answer for documenting a C or C++ codebase, and it produces an output shape that is uniquely hostile to sharing: an html/ directory containing several thousand files, which is meaningful only when served over HTTP.

For an open-source project, that's a Pages deploy and you're done. For an internal library — which is where most Doxygen lives — you get a choice between standing up an internal web server, emailing a 40 MB zip, or telling people to run doxygen themselves.

Generate it

doxygen Doxyfile          # → html/
html/
├── index.html
├── classFoo.html            # one page per class
├── functions.html  files.html
├── doxygen.css  doxygen.svg
├── search/                  # the client-side search index
└── *.png / *.svg            # call graphs, inheritance diagrams

Drop the folder in

Drag html/ (or a zip of it) into Comma:

  • index.html becomes the report body — the page carrying the comment layer.
  • Class pages, stylesheets, the search index and the graph images upload alongside it, with relative references rewritten to the uploaded copies.
  • Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the client-side search and the collapsible member sections keep working.

Two Doxyfile settings matter here:

SERVER_BASED_SEARCH = NO     # the CGI backend won't exist; keep search client-side
DOT_IMAGE_FORMAT    = svg    # graphs stay sharp when zoomed

Keep it under the asset limit

This is the one real constraint. A report holds 500 assets, and a large C++ project's Doxygen output blows past that without trying.

The fix is also good documentation practice — narrow the input to the public surface people actually consume:

INPUT           = include/
EXCLUDE         = src/internal/
SOURCE_BROWSER  = NO         # drops one generated page per source file

Docs scoped to the public headers are both publishable and more useful than docs that also describe every static helper.

From the release job

doxygen Doxyfile

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html html/index.html \
        --arg title "API docs — $VERSION" \
        '{title: $title, html: $html}')"

The API is JSON-only, so the class pages and graphs go up through POST /api/v1/reports/$REPORT_ID/assets as base64 — one call per file, worth scripting once. See the API reference and publishing from CI.

PATCHing one saved id gives the library a permanent URL that tracks the current release, with a revision per publish — a readable record of how the public API changed, which is a better answer to "when did that signature change?" than git log over a header.

Docs review, on the docs

Doxygen comments rot in a specific way: the signature changes, the @param block doesn't, and nobody notices because nobody reads the generated output. Publishing it is what makes the rot visible.

Select the description, leave a thread — "this says it returns NULL on error, it returns -1" — and it stays anchored to that function across docs builds. See commenting on HTML.

Who can see it

Per report: private, your team, any signed-in user with the link, or public. An internal library gets a team report; a partner SDK gets a link-only one for the integration window. Domain-gating, password gates and expiring links are Enterprise. See sharing & access control.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total — the binding constraint for Doxygen; scope INPUT accordingly.
  • Scripts run, sandboxed — no same-origin access.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish Doxygen docs →

Related