Skip to content

build: wipe the doxygen xml dir before regenerating the jsonapi bindings - #370

Open
jolavillette wants to merge 1 commit into
RetroShare:masterfrom
jolavillette:fix/jsonapi-stale-doxygen-xml
Open

build: wipe the doxygen xml dir before regenerating the jsonapi bindings#370
jolavillette wants to merge 1 commit into
RetroShare:masterfrom
jolavillette:fix/jsonapi-stale-doxygen-xml

Conversation

@jolavillette

@jolavillette jolavillette commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

A build directory that predates the removal or rename of a public header keeps failing with:

jsonapi-includes.inl:11:10: fatal error: retroshare/rsmsgs.h: No such file or directory

rsmsgs.h was removed by fd79225 ("started separating rsMsgs into rsMail and rsChats"), and grepping the sources for it finds nothing — because it is not in the sources. Doxygen never purges its OUTPUT_DIRECTORY, so rsmsgs_8h.xml is still sitting in the build tree, and both generators emit one #include per *_8h.xml file they find there, built from that XML's <location file=...>. The dead header is re-included on every rebuild, and jsonapi-wrappers.inl gets the matching dead wrappers.

make clean does not cure it: genjsonapi.clean lists only the two .inl files, never the xml/ directory. The clean deletes the outputs, doxygen reruns, and the same #include comes back from the surviving XML. The only workaround is deleting the whole build directory, which is not something the error message suggests.

So delete the *_8h.xml files right before invoking doxygen, in both build systems. Only those files drive the generators (jsonapi-generator.cpp iterates *8h.xml, jsonapi-generator.py filters on endswith("8h.xml")); every other XML they open is reached through a live header's XML, which doxygen has just regenerated. This costs nothing: doxygen re-parses its whole input on every run anyway, it just stops reusing the stale header files.

cmake -E rm does not expand wildcards, so the CMake side does the glob in a small script generated next to the doxyfile.

Reproduced by dropping a single crafted rsmsgs_8h.xml into an otherwise up-to-date xml directory — the generator emits #include "retroshare/rsmsgs.h" again; with the deletion in place the output is clean.

Reported by Cyril on the dev chat.

Comment thread src/libretroshare.pro Outdated
} else {
genjsonapi.commands = \
mkdir -p $${JSONAPI_GENERATOR_OUT} && \
rm -rf $${JSONAPI_GENERATOR_OUT}/xml && \

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.

Could you rather use something like "rm $${JSONAPI_GENERATOR_OUT}/xml/*_8h.xml" ? That line looks dangerous, if something ever happens to the JSONAPI_GENERATOR_OUT variable

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, done — no more directory removal anywhere.

Both generators only ever pick up the header XML (jsonapi-generator.cpp iterates *8h.xml, jsonapi-generator.py filters on endswith("8h.xml")), so deleting just those is enough: every other XML they open is reached through a live header'''s XML, which doxygen has just regenerated.

  • sh branch: rm -f $${JSONAPI_GENERATOR_OUT}/xml/*_8h.xml (-f so an unexpanded glob is not an error)
  • win32 no-sh branch: -$(DEL_FILE) ... /xml/*_8h.xml
  • CMake: cmake -E rm does not expand wildcards, so the glob is done by a tiny script generated next to the doxyfile (file(GLOB ...) + file(REMOVE ...), guarded against an empty match).

Force-pushed.

… bindings

A build directory that predates the removal or rename of a public header
keeps failing with:

    jsonapi-includes.inl:11:10: fatal error: retroshare/rsmsgs.h:
    No such file or directory

Doxygen never purges its OUTPUT_DIRECTORY, and both generators emit one
#include per *_8h.xml file found there, built from that XML's
<location file=...>. So the XML of a header that no longer exists is
re-read on every rebuild and turned back into a dead #include, with the
matching dead wrappers in jsonapi-wrappers.inl.

The generated clean rule lists only the two .inl files, never the xml/
directory, so a clean rebuild does not cure it: only deleting the whole
build directory does.

Delete the *_8h.xml files right before invoking doxygen, in both build
systems. Only those files drive the generators; every other XML they read
is reached through a live header's freshly regenerated XML. This costs
nothing, doxygen re-parses its whole input on every run anyway.

cmake -E rm does not expand wildcards, so the CMake side does the glob in
a small script generated next to the doxyfile.

Reported by Cyril on the dev chat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jolavillette
jolavillette force-pushed the fix/jsonapi-stale-doxygen-xml branch from 3dc48d5 to 29620c6 Compare August 28, 2026 09:45
@csoler

csoler commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Given this change, does the compilation always regenerate the xml files, or does it keep the existing ones when the .h files haven't changed?

@csoler

csoler commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Maybe that cleaning step should be in the make clean, not in the compilation.

@jolavillette

Copy link
Copy Markdown
Contributor Author

Doxygen has no incremental mode and never purges: every run re-parses the whole INPUT and rewrites the XML of everything it parses, leaving behind the XML of whatever is gone (checked with 1.9.8). That leftover is the bug.

The deletion is a command inside the same rule as doxygen, so it runs if and only if doxygen runs, and it only removes files doxygen is about to rewrite anyway, plus those leftovers. No extra work, no extra run.

On make clean: it cannot be cured there, and it is not cured there today either. Reproduced on a two-header sample with the real jsonapi-generator.py and jsonapi-generator-doxygen.conf:

  1. two headers -> both #includes generated
  2. delete rsbbb.h, delete both .inl (which is all genjsonapi.clean does), rerun -> #include "retroshare/rsbbb.h" is back, plus the wrappers for its methods
  3. same state, but purging the *_8h.xml first -> only the live include, no dead wrapper

Step 2 is a clean build tree as far as the clean rule is concerned; someone still has to know to delete the xml directory by hand. The stale XML is an input of the generation step, so purging it belongs to that step.

If you want make clean to drop the xml as well, I'll add that on top.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants