moc is ignoring preprocessor directives #65

Open
opened 1 year ago by AlexKent · 4 comments
Collaborator

Basic information

  • TDE version: R14.0.13
  • Distribution: Ubuntu 22.04.1 LTS
  • Hardware: amd64

Description

tqmoc ignores preprocessor directives.

Directives such as #if, #else, and #endif in the input header file seem to be simply stripped out.

Note that the version of moc shipped with QT5 behaves as expected and respects the prepocessor directives (with TQ_OBJECT changed to Q_OBJECT).

Steps to reproduce

  1. Create a header file with some slots surrounded by #ifdefs (see listing below).
  2. Run tqmoc against the file.

The output should mention includedMethod but not excludedMethod. Currently tqmoc's output mentions both.

Listing

test.h

#include <tqwidget.h>

class OurWidget : public TQWidget
{
  TQ_OBJECT
  
public slots:
#ifdef SOME_UNDEFINED_CONDITION
  void excludedMethod();
#else
  void includedMethod();
#endif
};

Possible fixes

  1. Backport moc from QT5 to TQT
  2. Instead of opening the input directly open it using cpp and read that program's output. As suggested by denk on IRC:
[09:37:40] <denk> a big idea to you, modify moc to use an external CPP to preprocess the file
[09:40:38] <denk>         yyin = fopen( (const char *)g->fileName, "r" );
[09:40:50] <denk> replace by popen() with cpp
<!-- This is a comment. Please fill in the required fields below. The comments provide instructions on how to do so. Note: You do not need to remove comments. --> ## Basic information - TDE version: R14.0.13 <!-- such as R14.0.12 - see tde-config -v --> - Distribution: Ubuntu 22.04.1 LTS <!-- such as Debian Bullseye - see lsb_release -sd --> - Hardware: amd64 <!-- amd64 / i386 / ppc64el / armhf / ... --> <!-- Use SL/* labels to set the severity level. Please do not set a milestone. --> ## Description `tqmoc` ignores preprocessor directives. Directives such as `#if`, `#else`, and `#endif` in the input header file seem to be simply stripped out. Note that the version of `moc` shipped with QT5 behaves as expected and respects the prepocessor directives (with `TQ_OBJECT` changed to `Q_OBJECT`). ## Steps to reproduce 1. Create a header file with some slots surrounded by `#ifdef`s (see listing below). 2. Run tqmoc against the file. The output should mention `includedMethod` but not `excludedMethod`. Currently `tqmoc`'s output mentions both. ## Listing **test.h** ``` #include <tqwidget.h> class OurWidget : public TQWidget { TQ_OBJECT public slots: #ifdef SOME_UNDEFINED_CONDITION void excludedMethod(); #else void includedMethod(); #endif }; ``` ## Possible fixes 1. Backport `moc` from QT5 to TQT 2. Instead of opening the input directly open it using `cpp` and read that program's output. As suggested by denk on IRC: ``` [09:37:40] <denk> a big idea to you, modify moc to use an external CPP to preprocess the file [09:40:38] <denk> yyin = fopen( (const char *)g->fileName, "r" ); [09:40:50] <denk> replace by popen() with cpp ```
blu.256 commented 1 year ago
Collaborator

I remember encountering this bug before. Would be good to have that fixed.

Fix 2 seems easier to me but how will the preprocessor be guessed? The user might prefer to use a certain preprocessor, so just running cpp would not be totally correct.

Fix 1 looks hard but might not be (must look at the code to be sure). It could be a matter of backporting just one or several commits and might certainly be preferrable.

I remember encountering this bug before. Would be good to have that fixed. Fix 2 seems easier to me but how will the preprocessor be guessed? The user might prefer to use a certain preprocessor, so just running `cpp` would not be totally correct. Fix 1 looks hard but might not be (must look at the code to be sure). It could be a matter of backporting just one or several commits and might certainly be preferrable.
Poster
Collaborator

For the record, the workaround I'm using is to always declare the slots in the header file. In the .cpp file I'm defining the slot methods but using #ifdef statements in their bodies to make the methods stubs when appropriate.

For the record, the workaround I'm using is to always declare the slots in the header file. In the `.cpp` file I'm defining the slot methods but using `#ifdef` statements in their bodies to make the methods stubs when appropriate.
Poster
Collaborator

@blu.256 WRT fix 2, the CPP variable is set during builds (to cc -E on my system). tqmoc could check if the variable is set and run the fix (using its value as the command) if it is. If the variable is not set then the current behavior could be retained.

@blu.256 WRT fix 2, the `CPP` variable is set during builds (to `cc -E` on my system). `tqmoc` could check if the variable is set and run the fix (using its value as the command) if it is. If the variable is not set then the current behavior could be retained.
Owner

I remember running into this issue too.

Preprocessing file before using moc seems weird IMO, because you never know where things are defined. We would basically need to preprocess all the files as if we were starting a build, then moc the files and then do the real build, because defines could be in many different places. So it may work if the #define was in the same file or was passed from command line, but would it work if the define was in an header file somewhere else, maybe from a totally different header/library?

IMO a better solution would be to have the slot always defined and then use the define to enable/disable some part of its body.

I remember running into this issue too. Preprocessing file before using moc seems weird IMO, because you never know where things are defined. We would basically need to preprocess all the files as if we were starting a build, then moc the files and then do the real build, because defines could be in many different places. So it may work if the #define was in the same file or was passed from command line, but would it work if the define was in an header file somewhere else, maybe from a totally different header/library? IMO a better solution would be to have the slot always defined and then use the define to enable/disable some part of its body.
Sign in to join this conversation.
No Milestone
No Assignees
3 Participants
Notifications
Due Date

No due date set.

Dependencies

No dependencies set.

Reference: TDE/tqt3#65
Loading…
There is no content yet.