Qt5,CMake,AUTOMOC和预编译头

7

如何在CMake (2.8.12.1) AUTOMOC的输出中指定预编译头文件?

到目前为止,我已经分别尝试了以下两个方法:

 set(AUTOMOC_MOC_OPTIONS "-bstdafx.h")
 set(AUTOMOC_MOC_OPTIONS "-fstdafx.h")

在构建项目时生成的 AUTOMOC 输出(project_automoc.cpp)仅包含 moc_xxx.cpp 文件:

/* This file is autogenerated, do not edit*/
/// <- stdafx.h should be here ?!?!
#include "moc_widget_fps.cpp"
#include "moc_widget_sysevents.cpp"
4个回答

3

经过一番搜索,我决定为使用预编译头文件的项目关闭AUTOMOC功能:

set_target_properties (ProjectName PROPERTIES AUTOMOC FALSE)

# Set the headers that need moc'ing
file (GLOB MOC_FILES widget_filetransfer.h widget_main_menu.h widget_main_toolbar.h)
QT5_WRAP_CPP (MOC_SOURCES ${MOC_FILES})

...
# Force PCH for the generated MOC files
foreach (src_file ${MOC_SOURCES})
    set_source_files_properties (${src_file} 
  PROPERTIES COMPILE_FLAGS "/Yustdafx.h /FIstdafx.h"
)
endforeach()

1
当关闭automoc时,请注意在Windows上可以通过在命令行中从源文件夹执行findstr /m /s "Q_OBJECT" "*.h"来轻松获取所有带有Q_OBJECT宏的头文件列表。对于Linux/MacOS肯定也有类似的命令。 - Tim Meyer
在此期间是否有其他解决方案?理想情况下,CMake会提供一种选项,以将包含文件添加到生成的_automoc文件中,对吧? - codeling

2
正确的变量名是CMAKE_AUTOMOC_MOC_OPTIONS。它用于初始化目标的AUTOMOC_MOC_OPTIONS属性,例如:
set (CMAKE_AUTOMOC_MOC_OPTIONS "-bstdafx.h" "-fstdafx.h")

请注意,这将只使Qt MOC编译器将给定的包含文件添加到每个生成的文件中。整个不会受到影响。

但是我需要影响project_automoc.cpp :( 因为项目无法在没有预编译头文件的情况下编译此文件。 - Dmitry Sazonov
2
从CMake源代码来看,生成project_automoc.cpp的过程是硬编码的,不可配置。 - sakra
2
@DMitry,我的当前解决方法是对于使用预编译头文件的项目,禁用automoc,在CMAKE中使用set_target_properties(${TARGET_NAME} PROPERTIES AUTOMOC FALSE)并使用QT5_WRAP_CPP(MOC_SOURCES ${MOC_FILES})来moc文件。然后对于MOC_SOURCES中的每个moc文件,使用foreach(src_file ${moc_SRCS}) set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YuStableHeaders.h /FIStableHeaders.h") endforeach() - Pencheff
@Pencheff,您可以将其发布为答案。只有一个问题(我现在无法检查):将非Qt头文件传递给QT5_WRAP_CPP是否安全?还是最好检查每个文件的Q_OBJECT宏(似乎很慢)? - Dmitry Sazonov
@Dmitry,是的,将任何(头)文件传递给QT5_WRAP_CPP都是安全的,即使是不存在的文件,也不会出现任何问题,项目仍然可以编译和运行良好。 - Pencheff
不需要同时传递-b和-f,这会导致两个#include语句。一个单独的-bstdafx.h就足够了(在Qt 5.6和5.8中测试过)。 - David Faure

0

AUTOMOC_MOC_OPTIONS 不会影响 project_automoc.cpp 文件。它包含传递给 moc 的选项,用于创建 "moc_widget_fps.cpp" 和 "moc_widget_sysevents.cpp"。这些文件应该包含您的 pch 包含文件。


1
当我打开AUTOMOC时,在我的项目中看到的是,对于每个具有Q_OBJECT类的file.h文件,我都会在构建目录中得到一个相应的moc_file.cpp文件。这些文件没有添加到我的(Visual Studio)项目中,而是我得到了一个包含所有moc'ed cpp文件的单个project_automoc.cpp文件。由于我的项目使用预编译头文件,因此该文件应包括stdafx.h。如果我在VS中手动将/FIstdafx.h添加到该文件中,则可以成功编译。 - Pencheff
在创建moc_file.cpp时,请验证moc命令行是否包含适当的-b和-f选项。 - steveire
@steveire 不确定添加-b/-f选项如何有助于自动创建的文件,编译器只会抱怨_automoc文件,而不是moc_文件,这样做有什么意义呢? - codeling

0

可能更加优雅的方法是禁用mocs_...文件的预编译头文件。 这样可以保留AUTOMOC

append_to_source_file_property(
  ${CMAKE_CURRENT_BINARY_DIR}/<PROJECT_NAME_HERE>_autogen/mocs_compilation.cpp
  COMPILE_FLAGS " /Y- ")

如果你能/愿意改变预编译头文件的名称和内容,也可以将以下内容添加到其中:

#ifdef HACK_FOR_TRICKING_MOC_INTO_INCLUDING_ME_IN_THE_MOCS_FILE_DO_NOT_DEFINE
Q_OBJECT
#endif

这将欺骗cmake将其包含在mocs_...文件中。然后您需要将其置于顶部,这需要更改名称,文件按数字排序,然后是大写字母,然后是小写字母,因此例如1_precompiled.h应该可以解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接