如何使cmake仅为automoc文件添加编译器定义

Ste*_*erg 5 qt cmake automoc

我们的项目使用了非常严格的警告集,但是Qt5生成的moc文件所生成的代码违反了这些警告。显然,我们可以全局关闭警告,但是我只想禁止对automoc文件的警告。

例如:

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)) {
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

以下内容不起作用:

set_property(
  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  PROPERTY COMPILE_DEFINITIONS -Wundefined-reinterpret-cast
  )
Run Code Online (Sandbox Code Playgroud)

cmake抱怨:

  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.
Run Code Online (Sandbox Code Playgroud)

我不能使用set_property(FILE ...),因为我没有生成makefile时会自动执行的文件的完整列表(因此GLOBing也不起作用)。我不想手工维护将由构建生成的所有moc文件的列表。

Eba*_*sin 7

有点晚了,但我找到了一个可行的解决方案(CMake 3.16)。

首先,Automoc 无法生成警告。它是一个预处理器,接受 cpp 文件并生成 moc 文件。此操作不会生成编译警告。

在 CMake 中,当您将 AUTOMOC 属性设置为 时true,CMake 会(至少)执行两件事:

  1. 它将您的所有源提供给 MOC 以生成 moc 文件(这些 MOC 文件不会添加到您的目标中,我们不关心它们)
  2. 它创建一个mocs_compilation.cpp包含所有必需的 moc 文件的文件,将该文件添加到您的目标中,然后对其进行编译。

只有第二个操作才能生成警告。这就是您想要静音的编译步骤。


就我而言(CMake 3.16),mocs_compilation 文件是在以下路径中生成的:

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

一旦知道该路径,您可以通过仅将编译标志传递给该文件来消除一些警告:

set_source_files_properties("<target_name>_autogen/mocs_compilation.cpp"
    PROPERTIES
        COMPILE_FLAGS "-Wno-undefined-reinterpret-cast"
)
Run Code Online (Sandbox Code Playgroud)

在 CMake 3.18 或更高版本中,如果源文件添加到不同的文件中,则还必须使用DIRECTORY或之一(例如,如果您尝试从 root设置,但目标是在 中创建的):TARGET_DIRECTORYCMakeLists.txtCOMPILE_FLAGSCMakeLists.txtfoo/CMakeLists.txt

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

即使将来路径发生变化,CMake 始终有一个包含所有其他 MOC 文件的“通用”cpp 文件。如果您可以找到该文件的路径,则该解决方案将起作用。


在您的情况(较旧的 CMake 版本)中,该文件是Notification_automoc.cpp,因此以下行应该有效:

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