Qt5, CMake, AUTOMOC and precompiled headers
Asked Answered
C

4

7

How to specify a precompiled header to the output of CMake (2.8.12.1) AUTOMOC ?

So far, in the CMakeLists.txt I've tried these two separately:

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

The generated AUTOMOC output when building the project (project_automoc.cpp) only contains the moc_xxx.cpp files:

/* This file is autogenerated, do not edit*/
/// <- stdafx.h should be here ?!?!
#include "moc_widget_fps.cpp"
#include "moc_widget_sysevents.cpp"
Circumcise answered 30/1, 2014 at 18:32 Comment(0)
C
3

After some digging I decided to just turn the AUTOMOC feature off for projects that use precompiled headers:

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()
Circumcise answered 22/3, 2014 at 9:44 Comment(2)
When turning automoc off, note that on Windows you can get the list of all header files with the Q_OBJECT macro easily by executing findstr /m /s "Q_OBJECT" "*.h" on the source folder from the command line. There surely is a similar command for Linux/MacOSMailand
is there any other solution to this in the meantime? ideally cmake would provide an option to add an include file to the generated _automoc file, right?Langevin
D
2

The correct variable to set is called CMAKE_AUTOMOC_MOC_OPTIONS. It is used to initialize the AUTOMOC_MOC_OPTIONS property of a target, i.e.:

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

Also note that this will only make the Qt MOC compiler add the given includes to each generated moc_xxx.cpp file. The overall project_automoc.cpp will not be affected.

Ducharme answered 19/3, 2014 at 16:52 Comment(6)
But I need to affect project_automoc.cpp :(. because project count not compile this file without precompiled headers.Skylab
Looking at the CMake source code it seems that the generation of the project_automoc.cpp is hard coded and is not configurable.Ducharme
@DMitry, my current workaround is to just disable automoc for projects that use precompiled headers, in CMAKE- set_target_properties(${TARGET_NAME} PROPERTIES AUTOMOC FALSE) and moc the files using QT5_WRAP_CPP(MOC_SOURCES ${MOC_FILES}). Then for every moc file in MOC_SOURCES foreach(src_file ${moc_SRCS}) set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YuStableHeaders.h /FIStableHeaders.h") endforeach()Circumcise
@Pencheff, you may post it as an answer. Just one more question (I cannot check it by myself now): is it safe to pass non-qt headers to QT5_WRAP_CPP? Or it is prefferable to check each file for Q_OBJECT macro (seems slow)?Skylab
@Dmitry, yes its safe to pass any (header) files to QT5_WRAP_CPP, even non-existing files, and nothing will fail, project still compiles and runs fine.Circumcise
You don't need to pass both -b and -f, this leads to two #include statements. A single -bstdafx.h is enough (tested with Qt 5.6 and 5.8).Poem
T
0

AUTOMOC_MOC_OPTIONS doesn't affect the project_automoc.cpp file. It contains options passed to moc to create "moc_widget_fps.cpp" and "moc_widget_sysevents.cpp". Those should contain your pch includes.

Training answered 31/1, 2014 at 17:36 Comment(3)
What I see in my project when I turn on the AUTOMOC ON is, for every file.h that has a class with Q_OBJECT in, I get a corresponding moc_file.cpp in the build directory. These files are not added to my (visual studio) project, instead I get a single project_automoc.cpp file that includes all the moc'ed cpp files in it. Since my project uses precompiled headers, this file should include stdafx.h. If I manually add /FIstdafx.h to that file in VS, it compiles fineCircumcise
Verify that the moc command line contains the appropriate -b and -f options when creating moc_file.cpp.Training
@Training not sure how will it help to add the -b/-f option if that doesn't add anything to the _automoc file, and compiler complains about this file only, not about moc_ files?Langevin
C
0

A perhaps more elegant way is to disable precompiled headers for the mocs_... file. This allows you to keep AUTOMOC:

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

Alternatively if you can/are willing to change the name and contents of the precompiled header file, you can add this to it:

#ifdef HACK_FOR_TRICKING_MOC_INTO_INCLUDING_ME_IN_THE_MOCS_FILE_DO_NOT_DEFINE
Q_OBJECT
#endif

This will trick cmake into including it in the mocs_... file. You then need it to be at the top which requires a name change, files are sorted numbers first, then uppercase, then lowercase, so e.g. 1_precompiled.h should do the trick.

Commutative answered 19/2, 2020 at 19:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.