Steve Broberg
Steve Broberg

Reputation: 4394

How do you get cmake to add compiler definitions only for automoc files

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.

Upvotes: 12

Views: 2487

Answers (2)

Ebatsin
Ebatsin

Reputation: 581

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")

Upvotes: 7

Nicolas Holthaus
Nicolas Holthaus

Reputation: 8273

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")

Upvotes: 0

Related Questions