Qt5, CMake, AUTOMOC и предварительно скомпилированные заголовки

Как указать предварительно скомпилированный заголовок для вывода CMake (2.8.12.1) AUTOMOC?

До сих пор в CMakeLists.txt я пробовал эти два по отдельности:

 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"

person Pencheff    schedule 30.01.2014    source источник


Ответы (4)


Правильная переменная для установки называется CMAKE_AUTOMOC_MOC_OPTIONS. Он используется для инициализации свойства AUTOMOC_MOC_OPTIONS цели, т.е.:

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

Также обратите внимание, что это только заставит компилятор Qt MOC добавлять данные включения в каждый сгенерированный файл moc_xxx.cpp. Общий project_automoc.cpp не пострадает.

person sakra    schedule 19.03.2014
comment
Но мне нужно повлиять на project_automoc.cpp :(. потому что количество проектов не компилирует этот файл без предварительно скомпилированных заголовков. - person Dmitry Sazonov; 19.03.2014
comment
Глядя на исходный код CMake, кажется, что генерация project_automoc.cpp жестко закодирована и не настраивается. - person sakra; 20.03.2014
comment
@DMitry, мой текущий обходной путь — просто отключить automoc для проектов, которые используют предварительно скомпилированные заголовки, в CMAKE-set_target_properties(${TARGET_NAME} PROPERTIES AUTOMOC FALSE) и moc файлы с использованием QT5_WRAP_CPP(MOC_SOURCES ${MOC_FILES}). Затем для каждого файла moc в MOC_SOURCES foreach(src_file ${moc_SRCS}) set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YuStableHeaders.h /FIStableHeaders.h") endforeach() - person Pencheff; 20.03.2014
comment
@Pencheff, вы можете опубликовать это как ответ. Еще один вопрос (сейчас я не могу проверить сам): безопасно ли передавать заголовки, отличные от qt, в QT5_WRAP_CPP? Или предпочтительнее проверять каждый файл на макрос Q_OBJECT (кажется медленно)? - person Dmitry Sazonov; 21.03.2014
comment
@Dmitry, да, безопасно передавать любые (заголовочные) файлы в QT5_WRAP_CPP, даже несуществующие файлы, и ничего не выйдет из строя, проект по-прежнему компилируется и работает нормально. - person Pencheff; 22.03.2014
comment
Вам не нужно передавать как -b, так и -f, это приводит к двум операторам #include. Достаточно одного -bstdafx.h (проверено с Qt 5.6 и 5.8). - person David Faure; 30.09.2016

Немного покопавшись, я решил просто отключить функцию 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()
person Pencheff    schedule 22.03.2014
comment
При отключении automoc обратите внимание, что в Windows вы можете легко получить список всех файлов заголовков с помощью макроса Q_OBJECT, выполнив findstr /m /s "Q_OBJECT" "*.h" в исходной папке из командной строки. Наверняка есть аналогичная команда для Linux/MacOS. - person Tim Meyer; 04.03.2015
comment
есть ли какое-либо другое решение для этого в то же время? в идеале cmake предоставил бы возможность добавить включаемый файл в сгенерированный файл _automoc, верно? - person codeling; 15.01.2016

AUTOMOC_MOC_OPTIONS не влияет на файл project_automoc.cpp. Он содержит параметры, переданные moc для создания «moc_widget_fps.cpp» и «moc_widget_sysevents.cpp». Они должны содержать ваш компьютер.

person steveire    schedule 31.01.2014
comment
Что я вижу в своем проекте, когда я включаю AUTOMOC ON, так это то, что для каждого файла file.h, в котором есть класс с Q_OBJECT, я получаю соответствующий moc_file.cpp в каталоге сборки. Эти файлы не добавляются в мой проект (визуальная студия), вместо этого я получаю один файл project_automoc.cpp, который включает в себя все файлы moc'ed cpp. Поскольку в моем проекте используются предварительно скомпилированные заголовки, этот файл должен включать stdafx.h. Если я вручную добавлю /FIstdafx.h в этот файл в VS, он отлично скомпилируется - person Pencheff; 02.02.2014
comment
Убедитесь, что командная строка moc содержит соответствующие параметры -b и -f при создании moc_file.cpp. - person steveire; 02.02.2014
comment
@steveire не уверен, как это поможет добавить параметр -b/-f, если это ничего не добавляет в файл _automoc, а компилятор жалуется только на этот файл, а не на файлы moc_? - person codeling; 15.01.2016

Возможно, более элегантный способ — отключить предварительно скомпилированные заголовки для файла 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 должно помочь.

person Adversus    schedule 19.02.2020