|
| 1 | +# Copilot Instructions for Doxygen |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +Doxygen is the de facto standard tool for generating documentation from annotated source code. It supports C++, C, Objective-C, C#, PHP, Java, Python, IDL, Fortran, VHDL, and more. The project is written primarily in C++ (C++17) and uses Flex (`.l` files) for lexical scanning, Python scripts for code generation, and CMake as its build system. |
| 6 | + |
| 7 | +Current version can be found in the VERSION file in the root of the repository. This is typically the development version (to be released version). |
| 8 | + |
| 9 | +## Repository Structure |
| 10 | + |
| 11 | +``` |
| 12 | +/ |
| 13 | +├── src/ # Main source code (C++, Flex .l files, Python scripts) |
| 14 | +├── addon/ # Optional components |
| 15 | +│ ├── doxywizard/ # Qt-based GUI frontend |
| 16 | +│ ├── doxmlparser/ # XML output parser library |
| 17 | +│ ├── doxyapp/ # Example embedding doxygen |
| 18 | +│ ├── doxyparse/ # Source dependency parser |
| 19 | +│ └── doxysearch/ # External search tools (doxyindexer, doxysearch) |
| 20 | +├── deps/ # Bundled third-party libraries (spdlog, fmt, sqlite3, etc.) |
| 21 | +├── cmake/ # CMake modules and helpers |
| 22 | +├── testing/ # Regression tests (numbered NNN_name.ext pattern) |
| 23 | +├── doc/ # User manual source |
| 24 | +├── doc_internal/ # Developer/internal documentation (architecture overview) |
| 25 | +├── templates/ # HTML/other output templates |
| 26 | +├── vhdlparser/ # VHDL-specific parser |
| 27 | +└── libxml/ # Bundled XML library |
| 28 | +``` |
| 29 | + |
| 30 | +## Build System |
| 31 | + |
| 32 | +Doxygen uses **CMake** (minimum 3.14). Always build out-of-source: |
| 33 | + |
| 34 | +```bash |
| 35 | +mkdir build && cd build |
| 36 | +cmake -G "Unix Makefiles" .. |
| 37 | +make |
| 38 | +``` |
| 39 | + |
| 40 | +### Key CMake Options |
| 41 | + |
| 42 | +| Option | Description | |
| 43 | +|---|---| |
| 44 | +| `build_wizard=ON` | Build doxywizard (Qt GUI), requires Qt5 or Qt6 | |
| 45 | +| `build_app=ON` | Build doxyapp example | |
| 46 | +| `build_parse=ON` | Build doxyparse | |
| 47 | +| `build_search=ON` | Build doxysearch/doxyindexer | |
| 48 | +| `build_doc=ON` | Build user manual (requires LaTeX) | |
| 49 | +| `use_libclang=ON` | Add libclang-based parsing support | |
| 50 | +| `use_sys_spdlog=ON` | Use system spdlog instead of bundled | |
| 51 | +| `use_sys_fmt=ON` | Use system fmt instead of bundled | |
| 52 | +| `use_sys_sqlite3=ON` | Use system sqlite3 instead of bundled | |
| 53 | +| `static_libclang=ON` | Link statically against libclang | |
| 54 | +| `CMAKE_BUILD_TYPE=Debug` | Debug build (enables debug/tracing capabilities) | |
| 55 | +| `enable_tracing=ON` | Enable tracing in release builds | |
| 56 | +| `enable_lex_debug=ON` | Enable lex debug output in release builds | |
| 57 | +| `enable_coverage=ON` | Enable coverage reporting (requires separate build dir) | |
| 58 | + |
| 59 | +### Running Tests |
| 60 | + |
| 61 | +```bash |
| 62 | +# Build first, then from the build directory: |
| 63 | +make tests # Run all regression tests sequentially |
| 64 | +ctest # Run via CTest (supports parallel: ctest -j4) |
| 65 | +``` |
| 66 | + |
| 67 | +Tests are Python-driven via `testing/runtests.py`. Each test is a numbered file in `testing/` matching `NNN_*.ext`. Tests run doxygen and compare XML output. |
| 68 | + |
| 69 | +To run a single test by number: |
| 70 | +```bash |
| 71 | +python testing/runtests.py --id 001 --doxygen ./bin/doxygen \ |
| 72 | + --inputdir ../testing --outputdir ./testing |
| 73 | +``` |
| 74 | + |
| 75 | +## Code Style |
| 76 | + |
| 77 | +- **Language**: C++17 |
| 78 | +- **Formatter**: clang-format (see `.clang-format`). Run `clang-format -i <file>` to format. |
| 79 | +- **Style highlights**: |
| 80 | + - Allman brace style (braces on new lines for functions/classes/control flow) |
| 81 | + - 2-space indentation, no tabs |
| 82 | + - `ColumnLimit: 0` (no automatic line wrapping) |
| 83 | + - Pointers/references right-aligned: `Type *ptr`, `Type &ref` |
| 84 | + - Short functions/if/loops allowed on single line |
| 85 | +- **Static analysis**: clang-tidy (see `.clang-tidy`). Enable with `-DENABLE_CLANG_TIDY=ON`. |
| 86 | + |
| 87 | +## Architecture Overview (Key Concepts) |
| 88 | + |
| 89 | +### Configuration System |
| 90 | +- Defined in `src/config.xml` (XML schema) |
| 91 | +- Python script `src/configgen.py` generates `configoptions.cpp`, `configvalues.h`, `configvalues.cpp` at build time |
| 92 | +- Access config values with macros: `Config_getString()`, `Config_getInt()`, `Config_getList()`, `Config_getEnum()`, `Config_getBool()` |
| 93 | +- Config singleton class: `Config` |
| 94 | + |
| 95 | +### Processing Pipeline |
| 96 | +1. **Config parsing** – `Config::parse()` |
| 97 | +2. **Input file discovery** – `searchInputFiles()` |
| 98 | +3. **Tag file reading** – `readTagFile()` |
| 99 | +4. **Preprocessing** – `Preprocessor::processFile()` (C/C++ only) |
| 100 | +5. **Comment conversion** – `convertCppComments()` (C++ → C style + alias resolution) |
| 101 | +6. **Language parsing** – `OutlineParserInterface::parseInput()` → tree of `Entry` objects |
| 102 | +7. **Comment parsing** – `CommentScanner::parseCommentBlock()` + `Markdown::process()` |
| 103 | +8. **Symbol resolution** – Multiple tree walks over `Entry` nodes → `Definition` objects |
| 104 | +9. **Output generation** – Format-specific generators |
| 105 | + |
| 106 | +### Key Class Hierarchy |
| 107 | +- `Definition` (abstract base) → `ClassDef`, `NamespaceDef`, `FileDef`, `DirDef`, `GroupDef`, `PageDef`, `ConceptDef` |
| 108 | +- `MemberDef` – for functions, variables, enums, etc. |
| 109 | +- `ParserManager` – singleton factory for language parsers |
| 110 | +- `OutlineParserInterface` / `CodeParserInterface` – parser interfaces |
| 111 | + |
| 112 | +### Lexical Scanners (Flex `.l` files in `src/`) |
| 113 | +Key scanners: `commentscan.l`, `commentcnv.l`, `code.l`, `configimpl.l`, `constexp.l`, `declinfo.l`, `defargs.l`, `doctokenizer.l`, `fortranscanner.l`, `pre.l`, etc. |
| 114 | + |
| 115 | +Python scripts pre/post-process the `.l` files: `pre_lex.py`, `post_lex.py`, `scan_states.py`. |
| 116 | + |
| 117 | +### Output Generators |
| 118 | +Each output format has a generator class and a doc visitor: |
| 119 | +- HTML: `HtmlGenerator` + `HtmlDocVisitor` |
| 120 | +- LaTeX: `LatexGenerator` + `LatexDocVisitor` |
| 121 | +- RTF: `RTFGenerator` + `RTFDocVisitor` |
| 122 | +- Man: `ManGenerator` + `ManDocVisitor` |
| 123 | +- XML: `generateXML()` + `XmlDocVisitor` |
| 124 | +- DocBook, perlmod also supported |
| 125 | + |
| 126 | +## Debugging Doxygen |
| 127 | + |
| 128 | +Use `-d <option>` on the command line for debug output: |
| 129 | + |
| 130 | +| Option | Description | |
| 131 | +|---|---| |
| 132 | +| `-d preprocessor` | Preprocessing results | |
| 133 | +| `-d commentcnv` | Comment conversion results | |
| 134 | +| `-d commentscan` | Comment scanning before/after | |
| 135 | +| `-d printtree` | Entry tree dump | |
| 136 | +| `-d time` | Timing of stages | |
| 137 | +| `-d markdown` | Markdown processing | |
| 138 | +| `-d lex` | Lexer start/stop info | |
| 139 | +| `-d lex:lexername` | Specific lexer debug output | |
| 140 | +| `-d entries` | Entry tree dump | |
| 141 | + |
| 142 | +Use `-t [tracefile]` for full tracing output (very verbose; useful for experts). |
| 143 | + |
| 144 | +## Common Workflows |
| 145 | + |
| 146 | +### Adding a New Configuration Option |
| 147 | +1. Edit `src/config.xml` to add the option definition |
| 148 | +2. Rebuild – `configgen.py` auto-generates the C++ files |
| 149 | +3. Use the appropriate `Config_get*()` macro in source code |
| 150 | + |
| 151 | +### Adding a New Doxygen Command |
| 152 | +1. Add the command to `src/cmdmapper.cpp` and `src/cmdmapper.h` |
| 153 | +2. Handle it in `src/commentscan.l` (or relevant lexer) |
| 154 | +3. Add documentation handling in `src/docparser.cpp` |
| 155 | + |
| 156 | +### Adding a Regression Test |
| 157 | +1. Create `testing/NNN_description.ext` with the input source |
| 158 | +2. Add comment headers: `// objective: ...` and `// check: filename.xml` |
| 159 | +3. Create `testing/NNN/` directory structure with expected XML output |
| 160 | +4. Run test: `python testing/runtests.py --id NNN --doxygen ./bin/doxygen --inputdir ../testing --outputdir ./testing` |
| 161 | +5. Use `--noreg` flag to generate reference output on first run |
| 162 | + |
| 163 | +### Modifying a Flex Scanner |
| 164 | +1. Edit the `.l` file in `src/` |
| 165 | +2. The build system automatically runs flex and applies pre/post processing scripts |
| 166 | +3. Do not edit the generated `.cpp` files directly |
| 167 | + |
| 168 | +## Generated Files (Do Not Edit Manually) |
| 169 | +- `<build>/generated_src/configvalues.h` – from `config.xml` via `configgen.py` |
| 170 | +- `<build>/generated_src/configvalues.cpp` – from `config.xml` via `configgen.py` |
| 171 | +- `<build>/generated_src/configoptions.cpp` – from `config.xml` via `configgen.py` |
| 172 | +- `<build>/generated_src/settings.h` – from CMake configuration |
| 173 | +- Scanner `.cpp` files – generated from `.l` files by GNU flex |
| 174 | +- `<build>/generate_src/ce_parse.cpp` - from `constexp.y` generated by GNU bison |
| 175 | +- files in `vhdlparser` directory that have `Generated By:JavaCC:` in the header are generated by JavaCC. |
| 176 | +- Python files in `addon/doxmlparser/doxmlparser` are generated by generateDS (https://www.davekuhlman.org/generateDS.html) |
| 177 | + |
| 178 | +## CI/CD |
| 179 | + |
| 180 | +GitHub Actions workflow: `.github/workflows/build_cmake.yml` |
| 181 | + |
| 182 | +Tests run on: Ubuntu (GCC & Clang, Intel & ARM), macOS (Intel & Apple Silicon), Windows (MSVC). Both Debug and Release build types are tested. |
| 183 | + |
| 184 | +## Dependencies |
| 185 | + |
| 186 | +### Bundled (in `deps/`) |
| 187 | +- `spdlog` – logging |
| 188 | +- `fmt` – string formatting |
| 189 | +- `sqlite3` – for SQLite output format |
| 190 | +- `TinyDeflate` – compression |
| 191 | +- `liblodepng` – PNG generation |
| 192 | +- `libmscgen` – MSC diagram rendering |
| 193 | +- `libmd5` – MD5 hashing |
| 194 | + |
| 195 | +### External (optional) |
| 196 | +- Qt 5 or Qt 6 – for doxywizard GUI |
| 197 | +- LLVM/libclang – for enhanced C/C++ parsing (`use_libclang=ON`) |
| 198 | +- Graphviz dot – for diagram generation at runtime |
| 199 | +- LaTeX – for PDF output at runtime |
| 200 | +- Python 3 – required for build (code generation scripts) |
| 201 | + |
| 202 | +## Known Issues / Workarounds |
| 203 | + |
| 204 | +- **In-place builds not supported with `enable_coverage=ON`**: Always use a separate build directory. |
| 205 | +- **Windows**: libiconv must be downloaded separately (the CI fetches it from `pffang/libiconv-for-Windows`). |
| 206 | +- **Flex buffer size**: Controlled by `enlarge_lex_buffers` CMake variable (default 262144). Increase if parsing very large files. |
| 207 | +- **CMake < 3.21**: `DEPFILE` support is disabled automatically; no action needed. |
| 208 | +- **Snap conflicts on Ubuntu CI**: The workflow removes `firefox` and `snapd` snaps before installing LaTeX to prevent hangs. |
| 209 | + |
| 210 | +## Useful References |
| 211 | + |
| 212 | +- Internal architecture: `doc_internal/doxygen.md` |
| 213 | +- User manual: https://www.doxygen.nl/manual/ |
| 214 | +- Internal docs (generated): https://doxygen.github.io/doxygen-docs/ |
| 215 | +- Issue tracker: https://github.com/doxygen/doxygen/issues |
| 216 | +- Repository with workflow to generate official binaries: https://github.com/doxygen/doxygen-release/ |
0 commit comments