feat: support plugins - #1256
Conversation
`MRDOCS_DECL` expanded to nothing in a static build, so it marked nothing and its misuse went unnoticed: it was applied to some classes *and* some of their members, which MSVC rejects. `MRDOCS_TOOL`, which says MrDocs itself is being built, now comes first in every library that exports part of the API, so the symbols a plugin calls end up in the tool's export table, while a static consumer still sees plain declarations. `assert_failed`, the out-of-line members of `Corpus`, and the comparison operators a plugin reaches through the headers gain an attribute instead, since nothing else marks them and a plugin cannot call what the tool does not export. Exporting the API also makes MSVC warn about the standard library members of the exported types, which the libraries now suppress as mrdocs-core already did. The attributes move to an include of their own because Platform.hpp includes Assert.hpp first.
🧾 Changes by Scope
🔝 Top Files
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1256 +/- ##
========================================
Coverage 83.12% 83.12%
========================================
Files 35 35
Lines 3662 3662
Branches 844 844
========================================
Hits 3044 3044
Misses 410 410
Partials 208 208
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
An automated preview of the documentation is available at https://1256.mrdocs.prtest2.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-08-17 19:55:35 UTC |
e42cbfa to
11bfb49
Compare
73371cd to
b22ac45
Compare
MrDocs loads the shared libraries in the plugins subdirectory of each addon root as it starts up, and lets each one install a generator. A plugin resolves the MrDocs symbols it calls against the tool, so writing an output format takes the MrDocs headers and nothing else: no LLVM, no Clang, no separate library to ship. Closes cppalliance#58.
A plugin could install a generator, so it could add an output format but not change what any format sees. This adds support for corpus transforms, filling the gap with extension scripts. Plugin transforms run before the script ones, since a plugin is loaded before any script is read.
b22ac45 to
a8fc0fc
Compare
|
I think the doc preview isn't working. We need to debug that for this PR. In any case, I read the adoc file, and I'm not sure I understand the user workflow. As far as I understand, the user would need an mrdocs installation and a way to link whatever they need to their own project to write a plugin. And tests would have to emulate that. This can't be tested from the inside before mrdocs is installed. |
|
It seems that the doc preview stopped working around 5-6 June 2026. About the user workflow, your reading is right: the author needs an install. But I'm not sure what you mean by "can't be tested from the inside"; isn't that what tests/plugin-api does? However, I noticed that the docs prescribe |
Please hang on a little bit then, because I've been already working on precisely this issue for the last two weeks. My fork is nothing but CI tests for test/cmake-package lately. |
This PR adds support for plugins, i.e. shared libraries written in C++ that can be written and compiled without needing Clang/LLVM headers.
Changes
PluginContext). It also providesMRDOCS_PLUGIN_MAIN, a macro that writes those exported functions for the plugin author.ENABLE_EXPORTS. It also lists, on its interface, the include directories and compile options a plugin needs.Testing
Each test checks something the others cannot.
generator: stats. That name only exists if the plugin was found, loaded, and installed its generator, so the test fails if any step in that chain breaks.Writing the link test found a real problem. The comparison operators of the symbol kinds were not exported, so a plugin that sorts members could not link. The first commit fixes that.
The two ctest tests run in suites that CI already runs. The link test has no ctest entry, because it does not need one: it is a library, and a missing symbol makes the build fail. So CI needs no change.
The link test only detects a missing export on Windows, where a plugin gets its symbols from the tool's export table. On Linux and macOS, it still checks that the public headers compile the way a plugin compiles them, and that such a library links against the executable.
One thing is not tested: the cases where the loader refuses a plugin, that is, a wrong interface version, a wrong toolchain, or a missing entry point. Testing those needs a library built the wrong way on purpose.
Documentation
A new Plugins page under Extensions covers where plugins live, the entry point, the generator, and how to build one. Its code comes from the example through tag includes, so the page cannot drift from something that compiles. The plugins directory that ships with MrDocs gets a README saying what belongs in it.
Closes #58.