12

Our project is using very strict set of warnings, but Qt5 generated moc files produce code that violates these warnings. We could obviously turn off the warnings globally, but I'd like to just suppress the warnings for the automoc files.

For example:

In file included from /Users/stebro/client/build/NotificationServer/Notification_automoc.cpp:2:
/Users/stebro/client/build/NotificationServer/moc_NotificationServer.cpp:100:18: error: dereference of type '_t *' (aka 'void (carbonite::NotificationServer::**)(const QByteArray &, const QString, const QVariant)') that was reinterpret_cast from type 'void **' has undefined behavior [-Werror,-Wundefined-reinterpret-cast]
            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&NotificationServer::notificationQueued)) {
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following doesn't work:

set_property(
  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  PROPERTY COMPILE_DEFINITIONS -Wundefined-reinterpret-cast
  )

cmake complains:

  set_property DIRECTORY scope provided but requested directory was not
  found.  This could be because the directory argument was invalid or, it is
  valid but has not been processed yet.

I can't use set_property(FILE ...) because I don't have a comprehensive list of files that are automoc'd at the time the makefile is build (so presumably GLOBing won't work either). I don't want to hand-maintain a list of all moc files that will get generated by the build.

RAM
  • 2,257
  • 2
  • 19
  • 41
Steve Broberg
  • 4,255
  • 3
  • 28
  • 40
  • Did you find a way around that since you asked this question? I'm currently stuck with the same issue. – Corristo Jun 25 '17 at 13:27
  • @Corristo: We have since moved on to Qt 5.7 and we're not getting this problem anymore (maybe Qt's automoc cleaned up their act). If you're running in a clang/OSX environment, I know you can get warnings to be suppressed for "system" headers, by using -isystem instead of -I in your compilation line. It may be possible to specify ${CMAKE_CURRENT_BINARY_DIR} as something included as a system path. – Steve Broberg Jun 28 '17 at 20:01
  • @Corristo: Actually, I misspoke (I checked the date of my original submission - this comment was for my current project, not my previous). I unfortunately got around the problem by just putting global suppressions for all my code to cover Qt's bad behavior. See my answer below. – Steve Broberg Jun 28 '17 at 20:06

2 Answers2

6

A bit late but I found a solution that works (CMake 3.16).

First off, Automoc cannot generate warnings. It is a preprocessor that takes a cpp file and generate a moc file. This operation will not generate compilation warnings.

In CMake, when you set the AUTOMOC property to true, CMake does (at least) two things:

  1. It gives all your sources to MOC to generate the moc files (these MOC files are not added to your target and we do not care about them)
  2. It creates a mocs_compilation.cpp file that includes all the necessary moc files, adds this file to your target then compile it.

Only this second operation can generate warnings. It's that compilation step that you want to silence.


In my case (CMake 3.16), the mocs_compilation file is generated in the following path:

${<target_name>_BINARY_DIR}/<target_name>_autogen/mocs_compilation.cpp

Once you know that path, you can silence some warnings by passing compilation flags only to this file in particular:

set_source_files_properties("<target_name>_autogen/mocs_compilation.cpp"
    PROPERTIES
        COMPILE_FLAGS "-Wno-undefined-reinterpret-cast"
)

In CMake 3.18 or later, one of DIRECTORY or TARGET_DIRECTORY must also be used if the source files were added in a different CMakeLists.txt file (e.g. if you are trying to set COMPILE_FLAGS from the root CMakeLists.txt, but the target was created in foo/CMakeLists.txt):

set_source_files_properties("<target_name>_autogen/mocs_compilation.cpp"
    TARGET_DIRECTORY <target_name>
    PROPERTIES
        COMPILE_FLAGS "-Wno-undefined-reinterpret-cast"
)

Even if paths change in the future, CMake always had a "general" cpp file that includes all the other MOC files. If you can find the path to this file, this solution will work.


In your case (older CMake version), this file is Notification_automoc.cpp, so the following line should work:

set_source_files_properties("Notification_automoc.cpp" PROPERTIES COMPILE_FLAGS "-Wno-undefined-reinterpret-cast")

C Snover
  • 17,908
  • 5
  • 29
  • 39
Ebatsin
  • 552
  • 5
  • 17
  • 1
    This will indeed add the flags to the compiler command line for building mocs_compilation.cpp, but it does not have any effect on the warnings the compiler will output (at least for Visual C++). The warnings are still reported for the individual moc_...cpp files. Is there a possibility to add the compiler flags to those files directly? – mgr Nov 13 '20 at 07:31
  • @mgr that's weird. The way mocs_compilation.cpp works is by including directly all the other .cpp files. They are always compiled through mocs_compilation.cpp. Never directly. Are you sure you silenced the correct file ? (it should be a list of `#include "XXXXXXX/moc_xxx.cpp` – Ebatsin Jan 06 '21 at 13:43
  • 1
    the compile flags are added to the correct generated file mocs_compilation.cpp, with verbose option to ninja I can see the flags added to the command line for this file. I even tried adding an invalid compile flag and got the expected warning (cl : Command line warning D9002 : ignoring unknown option...). And if I change /wd... to /we... it triggers the compilation error, so the compile flags are definitely applied. – mgr Jan 12 '21 at 08:04
0

You can disable all AUTOMOC warnings by passing the 'no warning' option on the moc command line. CMAKE_AUTOMOC_MOC_OPTIONS initializes the AUTOMOC_MOC_OPTIONS whose documentation is linked below.

SET(CMAKE_AUTOMOC   ON)
SET(CMAKE_AUTOMOC_MOC_OPTIONS "-nw")
Nicolas Holthaus
  • 7,763
  • 4
  • 42
  • 97
  • 1
    Adding this line didn't suppress the compiler warnings. I don't think the -nw flag controls compiler warnings. From looking the Qt link above, it seems like -nw suppresses the warnings in the generation the moc file, not the warnings generated when the file is compiled. – Steve Broberg Mar 31 '16 at 19:43
  • @SteveBroberg the fundamental problem is you are compiling and linking files that have warnings that you want to be warned about. For that, I'm not sure I see a way around it other than unsetting the warning on the project that compiles the automoc.cpp, or using a Qt version that doesn't generate the warnings. Maybe you could write a script to generate pragmas in the files after they're moc'd, but it seems like a lot of effort. – Nicolas Holthaus Mar 31 '16 at 19:53
  • Given the nature of the warning above, it seems unlikely that any version of Qt would not have this warning, as it's downcasting a pointer to a void* to a function pointer, which is how Qt manages to invoke callbacks. Short of refactoring their whole signal/slot mechanism, I don't see how they could avoid this other than putting compiler-specific pragmas in the code to ignore them. The Qt headers in general are full of warnings that trigger for -Weverything - I had to suppress 8 of them, but that's manageable via header wrappers - not so here. – Steve Broberg Mar 31 '16 at 20:02