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"
UmNyobe
  • 22,539
  • 9
  • 61
  • 90
Pencheff
  • 190
  • 1
  • 7

4 Answers4

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()
Pencheff
  • 190
  • 1
  • 7
  • 1
    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/MacOS – Tim Meyer Mar 04 '15 at 06:02
  • 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? – codeling Jan 15 '16 at 09:26
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.

sakra
  • 62,199
  • 16
  • 168
  • 151
  • But I need to affect `project_automoc.cpp` :(. because project count not compile this file without precompiled headers. – Dmitry Sazonov Mar 19 '14 at 17:04
  • 2
    Looking at the CMake source code it seems that the generation of the `project_automoc.cpp` is hard coded and is not configurable. – sakra Mar 20 '14 at 08:31
  • 2
    @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()` – Pencheff Mar 20 '14 at 17:55
  • @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)? – Dmitry Sazonov Mar 21 '14 at 08:33
  • @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. – Pencheff Mar 22 '14 at 09:33
  • 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). – David Faure Sep 30 '16 at 11:13
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.

steveire
  • 10,694
  • 1
  • 37
  • 48
  • 1
    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 fine – Pencheff Feb 02 '14 at 09:56
  • Verify that the moc command line contains the appropriate -b and -f options when creating moc_file.cpp. – steveire Feb 02 '14 at 11:00
  • @steveire 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? – codeling Jan 15 '16 at 09:04
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.

Adversus
  • 2,166
  • 20
  • 23