Guten Morgen, gibt es in Doxygen die Möglichkeit, alle Zweige von Präprozessor-Makros in die Dokumentation aufzunehmen? Oder andersherum: Gibt eine Möglichkeit, den Präprozessor komplett abzuschalten, ohne dass die Include-Graphen verloren gehen?
Es gibt bei Stackoverflow ein zwei vorschläge dazu: https://stackoverflow.com/questions/26043007/make-doxygen-doxument-the-ifdef-parts-too Ansonsten im Makefile halt was hinzufügen, das die Dateien kopiert und die ifdefs entfernt: (ungetestet)
1 | SOURCES=$(wildcard src/*.c) $(wildcard src/**/*.c) |
2 | SOURCES=$(wildcard src/*.h) $(wildcard src/**/*.h) |
3 | |
4 | docs: $(patsubst src/%,build/docsrc/%,$(SOURCES)) |
5 | doxygen Doxyfile |
6 | |
7 | build/docsrc/%: src/% |
8 | mkdir -p "$(dir "$@")" |
9 | sed '/^#if/d;/#endif/d;/#else/d' <"$<" >"$@" |
Aber wozu will man sowas überhaupt? Sollte man in der Doku nicht drin haben, was tatsächlich drin ist? Gibt es eventuell bessere alternativen zum Einsatz der ifdefs für das, wofür du diese momentan einsetzt?
DPA schrieb: > Es gibt bei Stackoverflow ein zwei vorschläge dazu Der schlägt ja vor, Preprocessing zu deaktivieren, was mich die Baumdiagramme kostet. Letztere waren allerdings der Grund, überhaupt mit Doxygen zu arbeiten. DPA schrieb: > Sollte man in der Doku nicht drin > haben, was tatsächlich drin ist Naja, in der Doku des Quelltextes sollte drin sein, was implementiert wurde. Wenn es von einer Funktion zwei Varianten (z.B. für unterschiedliche Targets gibt), sollten natürlich beide dokumentiert sein. Momentan behelfe ich mir damit, statt
1 | #if TARGET == TARGET1
|
2 | ...
|
3 | #elif TARGET == TARGET2
|
4 | ...
|
5 | #else
|
6 | error ... |
7 | #endif
|
im Quelltext
1 | #ifdef( TARGET1 )
|
2 | ...
|
3 | #endif
|
4 | #ifdef( TARGET2 )
|
5 | ...
|
6 | #endif
|
und dann in Doxygen alle Targets zu definieren. Ist nur im Quelltext deutlich weniger geradlinig.
Ich mache in der regel ein Verzeichnis mit Unterverzeichnissen für jedes Target, und tue den Platformabhängigen Code dann in Dateien dort drin rein. Ich versuche dann immer, so wenig Platformabhängigen Code wie möglich zu haben, und schaue, dass der generische Code nicht von einer bestimmten Platform abhängig wird. In der regel mach ich das so, dass ich in Headern Interfaces definiere, und jede Platform diese dann implementiert. Beim compilieren lass ich dann die Dateien für andere Plattformen, als ich grad baue, einfach weg. Doxygen kann man die dann trotzdem alle vorwerfen, aber dort muss ich in der regel nicht viel Dokumentieren, weil das Interface schon zentral einmal dokumentiert ist und Programmunabhängig ist.
Ich bin mir nicht sicher, ob ich die Kernaussage richtig verstehe. Lautet sie "der Plattformabhängige Code ist so kurz, daß er nicht in die Doku braucht" ?
Walter T. schrieb: > #ifdef( TARGET1 ) > ... > #endif > #ifdef( TARGET2 ) > ... > #endif oder
1 | #if defined(TARGET1) || defined(DOXYGEN)
|
2 | ...
|
3 | #endif
|
4 | #if defined(TARGET2) || defined(DOXYGEN)
|
5 | ...
|
6 | #endif
|
Alternativ einfach nur die Definitionen der Funktionen in #ifdef packen - dann sind die Deklarationen immer da, und wenn man eine unpassende Funktion benutzt gibt's einen "undefined reference" Linker Fehler. Oder die Dinge für Target 1 in eine Datei, die für Target 2 in eine andere usw. Man muss dann die jeweils richtige Datei inkludieren, aber Doxygen sieht sie alle. Oder die unpassenden Funktionen per SFINAE statt per Makros ausblenden, dann sieht Doxygen sie auch. Oder verschiedene Klassen für die verschiedenen Targets definieren, und man muss dann je nach Target die richtige Klasse instanziieren. Doxygen sieht dann auch alles.
Nunja, die Funktionalität meiner Programme ist in der regel bei den meisten Targets grösstenteils gleich oder ähnlich. Sagen wir, ich deklariere in einem Header die Platformabhängige Funktion "void setBlaMotorSpeed(int speed);", dann Dokumentiere ich dort z.B. "Setzt die Drehgeschwindigkeit von Motor bla. \param speed Geschwindigkeit in RPM im Uhrzeigersinn, negative Werte gegen den Urzeigersinn.". Wenn ich dann für verschiedene Plattformen andere Implementationen davon habe, dann schreib ich das dort in der Regel nicht nochmal hin. Wo der Motor angeschlossen ist steht wo anders, und interessiert nicht, wenn man nur wissen will, was die Funktion tut. Höchstens Wenn es noch was spezielles zu beachten gibt, schreib ich das hin.
Exakt jene Frage hab ich vor 5 Monaten ebenfalls auf stackoverflow gestellt: https://stackoverflow.com/questions/55242882/doxygen-parse-everything-regardless-of-preprocessor-directive# Fazit: Ich entferne die Direktiven via Python-Script und parse die temporäre Datei...
Dr. Sommer schrieb: > #if defined(TARGET1) || defined(DOXYGEN) > ... > #endif > #if defined(TARGET2) || defined(DOXYGEN) > ... > #endif Gute Lösung! Das 'DOXYGEN' lässt sich in Doxygen selbst definieren. So muss man nur einmal zusätzlich rumfummeln. In der Konfiguration von Doxygen ist das dann nur ein: PREDEFINED = _DOXYGEN_ Ja, ich hab das mit zwei underlines gemacht. Und ja, die sind eigentlich für den Compiler (?) reserviert. Interessanterweise wirft Doxygen alternative defines dann raus:
1 | #if defined(DEBUG) || defined(__DOXYGEN__) |
2 | /** |
3 | \brief Debug something. Needs 'DEBUG' to be defined! |
4 | */ |
5 | void DebugSomething(); |
6 | #else |
7 | /// See function DebugSomething |
8 | #define DebugSomething() |
9 | #endif |
Hier wird nur die Doku für die Funktion und nicht das Makro erstellt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.