Я столкнулся с той же проблемой (я новичок в qt, но у меня это сработало). Для других людей, ищущих решение, я нашел это:
Что происходит
Проблема в том, что из-за макроса Q_PRIVATE_SLOT
сгенерированный moc_XXX.cxx
нуждается в полном объявлении класса XXXPrivate
для вызова функции закрытого слота. Так как открытый заголовок только пересылает его, форвард cxx не может быть скомпилирован сам по себе. Парни QtPropertyBrowser обошли эту проблему, включив сгенерированный moc_XXX.cpp
(обратите внимание на 'pp', cmake генерирует 'xx')) в свой исходный файл (уродливо, но работает). Я также не знаю другого способа сказать moc включить (в данном случае даже не присутствовать) private XXX_p.hpp
. Так что давайте придерживаться этого пути.
Затем я удалил сгенерированные файлы moc_XXX.cxx
из исполняемого файла, но это привело к тому, что moc никогда не вызывалось. Это случилось, хотя я использовал QT4_WRAP_CPP
. Так что после дальнейших поисков я обнаружил ...
Одно дополнение к этому особому случаю: декларация QtProperty
отсутствует. Либо добавьте следующую предварительную декларацию или соответствующий файл включения:
#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif
class QtProperty;
#if QT_VERSION >= 0x040400
QT_END_NAMESPACE
#endif
Решение
Полный кредит предоставляется fullmetalcoder , который представил эту функцию cmake:
function(qt4_wrap_hdrs _moc_srcs)
qt4_get_moc_flags(_moc_incs)
set(_mocs)
foreach(_current_file ${ARGN})
get_filename_component(_abs_file ${_current_file} ABSOLUTE)
if(EXISTS ${_abs_file})
file(READ ${_abs_file} _contents)
get_filename_component(_basename ${_abs_file} NAME_WE)
string(REGEX MATCH "Q_OBJECT" _match "${_contents}")
if(_match)
set(_moc "${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp")
qt4_create_moc_command(${_abs_file} ${_moc} "${_moc_incs}" "")
macro_add_file_dependencies(${_abs_file} ${_moc})
list(APPEND _mocs ${_moc})
endif(_match)
endif(EXISTS ${_abs_file})
endforeach (_current_file)
set(${_moc_srcs} ${_mocs} PARENT_SCOPE)
endfunction(qt4_wrap_hdrs)
(из http://www.qtcentre.org/threads/37428-using-QT-unit-testing-with-CMake)
Вы можете использовать эту функцию в качестве замены для QT4_WRAP_CPP
. Теперь вам нужно только добавить следующую строку в ваш CMakeLists.txt, чтобы компилятор нашел сгенерированные файлы moc_XXX.cpp
(новая функция создала файл 'pp' ...):
include_directories(${CMAKE_BINARY_DIR})
Эта функция постоянно вызывает moc и ведет себя больше как в случае qmake . За исключением, конечно, что вы можете легко сделать из исходных сборок.
Но есть одно предупреждение: все moc_XXX.cpp
файлы генерируются в CMAKE_BINARY_DIR
. Так что если у вас есть два файла include1/foo.hpp
и include2/foo.hpp
, один будет перезаписан!