I added code to generate a file using the MOC executable from QT. When I try to build it, the file is generated, but it doesn't get compiled.
find_program (QT_UIC uic)
find_program (QT_MOC moc)
set(TARGET_LIBRARY support_qt_${UNICODE_FLAG}${STATIC_FLAG}${BUILD_TYPE_FLAG})
# Enable the build directory as an include path as well, required for
# qt moc generated files.
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
include_directories(${Qt5Widgets_INCLUDES})
include_directories("..")
set(SUPPORT_SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/support_qt_dll_api.h
${CMAKE_CURRENT_SOURCE_DIR}/supportlib_qt_namespace.h
${CMAKE_CURRENT_SOURCE_DIR}/dll_main.cpp
)
if (STATIC_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBUILD_SUPPORT_QT_STATIC")
else (NOT STATIC_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBUILD_SUPPORT_QT_DLL")
endif()
if (UNICODE_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
add_subdirectory (logging)
add_subdirectory (models)
add_subdirectory (window)
#QT5_WRAP_UI(QT_UI_HEADERS ${QT_UI_SOURCES} )
# Process each .ui file and create a dependency to the
# the corresponding .h file.
set(GENERATED_SOURCES "")
foreach(ui_file ${SUPPORT_SOURCE})
get_filename_component(ui_ext ${ui_file} EXT)
string(TOLOWER ${ui_ext} ui_ext)
set(ui_dependency "")
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" ui_gen_file ${ui_file})
if( ${ui_ext} STREQUAL ".ui" )
string(REGEX REPLACE ".ui$" ".h" ui_gen_file "${ui_gen_file}")
add_custom_command(
#PRE_BUILD
OUTPUT "${ui_gen_file}"
COMMAND ${QT_UIC} -g cpp -o "${ui_gen_file}" "${ui_file}"
MAIN_DEPENDENCY "${ui_file}"
COMMENT "Generating UI: ${ui_gen_file}"
)
# A .ui File always has a .moc file with it.
string(REGEX REPLACE ".h$" ".moc" ui_gen_file "${ui_gen_file}")
set(ui_ext ".moc")
endif()
if( ${ui_ext} STREQUAL ".moc" )
string(REGEX REPLACE ".moc$" ".cpp" ui_gen_file "${ui_gen_file}")
set(GENERATED_SOURCES "${GENERATED_SOURCES} ${ui_gen_file}")
add_custom_command(
#PRE_BUILD
OUTPUT "${ui_gen_file}"
COMMAND ${QT_MOC} -o "${ui_gen_file}" -f "${ui_file}" "${ui_file}"
MAIN_DEPENDENCY "${ui_file}"
COMMENT "Generating MOC: ${ui_gen_file}"
)
set(GENERATED_SOURCE "${GENERATED_SOURCE} ${ui_gen_file}")
#message("Generated: ${ui_gen_file}")
endif()
endforeach()
set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
add_library(${TARGET_LIBRARY} ${BUILD_TYPE} ${SUPPORT_SOURCE} ${GENERATED_SOURCES})
target_link_libraries(${TARGET_LIBRARY} Qt5::Widgets)
set_target_properties(${TARGET_LIBRARY} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
)
When I remove the ${GENERATED_SOURCES}
from the append_library
I get this error:
CMake Error at support_qt/CMakeLists.txt:109 (add_library):
Cannot find source file:
D:/src/c/support_lib/build/support_qt/logging/logging_dialog_box_gui.cpp D:/src/c/support_lib/b
uild/support_qt/logging/logging_dialog_box_gui.cpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: support_qt_ad
CMake Error: Cannot determine link language for target "support_qt_ad".
I have seen other postings where similar scripts were shown using add_custom_command
but when I do it like this, I get:
mingw32-make[2]: *** No rule to make target 'support_qt/ D:/src/c/support_lib/build/support_qt/loggi
ng/logging_dialog_box_gui.cpp D:/src/c/support_lib/build/support_qt/logging/logging_dialog_box_gui.c
pp', needed by 'support_qt/CMakeFiles/support_qt_ad.dir/_D_/src/c/support_lib/build/support_qt/loggi
ng/logging_dialog_box_gui.cpp_D_/src/c/support_lib/build/support_qt/logging/logging_dialog_box_gui.c
pp.obj'. Stop.
CMakeFiles\Makefile2:236: recipe for target 'support_qt/CMakeFiles/support_qt_ad.dir/all' failed
mingw32-make[1]: *** [support_qt/CMakeFiles/support_qt_ad.dir/all] Error 2
makefile:74: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
and the file is not compiled only generated.
Update:
I also tried set(CMAKE_AUTOMOC ON)
and the generated cpp gets compiled, but only once. When the moc
is modified, or the included ui
file, it doesn't update it. It would be helpfull to see a fully working example. When I google I only find snippets. :(
It should be enough to set:
SET(CMAKE_AUTOMOC ON)
to instruct CMake to run moc automatically when needed (requires CMake 2.8.6+). Don't forget to remove the${GENERATED_SOURCES}
from theappend_library
.Also add QT5_WRAP_UI macro, for example:
EDIT: Fully working example. For simplicity some irrelevant to Qt stuff omitted.