[CMake] Qt4 moc and uic macros
Patrick Noffke
Patrick.Noffke at adpro.com.au
Thu Jun 8 05:52:58 EDT 2006
All,
I've written the following macros (the first one based on the existing QT4_AUTOMOC macro) to improve the handling of moc and uic generated files with Qt4. The "qmake way" is to generate moc_xxx.cpp files for headers that contain Q_OBJECT, and automatically include them as part of the build. The QT4_AUTOMOC2 macro below does this. An example usage of the macro would be as follows:
SET(foo_SRCS
Class1.cpp
Class2.cpp
some_dir/Class3.cpp
)
SET(foo_MOC_HDRS
Class1.h
Class2.h
some_dir/Class3.h
)
# Returns the moc_xxx.cpp files in the foo_MOC_SRCS variable
QT4_AUTOMOC2(foo_MOC_SRCS ${axiom_setup_MOC_HDRS})
ADD_EXECUTABLE(foo ${foo_SRCS} ${foo_MOC_SRCS})
The QT4_AUTOUIC macro allows you to automatically run uic on .ui files and creates a dependency of the ui_xxxx.h by xxxx.cpp (since this is the file that #include's ui_xxxx.h). An example usage would be as follows:
SET(foo_UI
Widget1.ui
Widget2.ui
)
QT4_AUTOUIC(${foo_UI})
These two macros solve the problems I've been having with moc'able files existing outside the source dir, and also allows me to define a build_dir outside the source tree. Please review them and if acceptable could a cmake maintainer please incorporate them into the cmake source tree?
Regards,
Patrick
MACRO(QT4_AUTOMOC2 moc_SRCS)
QT4_GET_MOC_INC_DIRS(_moc_INCS)
SET(_matching_FILES )
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
# if "SKIP_AUTOMOC" is set to true, we will not handle this file here.
# here. this is required to make bouic work correctly:
# we need to add generated .cpp files to the sources (to compile them),
# but we cannot let automoc handle them, as the .cpp files don't exist yet when
# cmake is run for the very first time on them -> however the .cpp files might
# exist at a later run. at that time we need to skip them, so that we don't add two
# different rules for the same moc file
GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC)
IF ( NOT _skip AND EXISTS ${_abs_FILE} )
FILE(READ ${_abs_FILE} _contents)
GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
STRING(REGEX MATCHALL "Q_OBJECT" _match "${_contents}")
IF(_match)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_header ${_abs_PATH}/${_basename}.h)
SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp)
ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${_moc_INCS} ${_header} -o ${_moc}
DEPENDS ${_header}
)
ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc})
SET(${moc_SRCS} ${${moc_SRCS}} ${_moc})
ENDIF(_match)
ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} )
ENDFOREACH (_current_FILE)
ENDMACRO(QT4_AUTOMOC2)
MACRO(QT4_AUTOUIC)
SET(_matching_FILES )
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
IF ( EXISTS ${_abs_FILE} )
FILE(READ ${_abs_FILE} _contents)
GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_outfile ${CMAKE_CURRENT_SOURCE_DIR}/ui_${_basename}.h)
SET(_header ${_basename}.h)
SET(_source ${_basename}.cpp)
ADD_CUSTOM_COMMAND(OUTPUT ${_outfile}
COMMAND ${QT_UIC_EXECUTABLE}
ARGS -o ${_outfile} ${_abs_FILE}
MAIN_DEPENDENCY ${_abs_FILE})
ADD_FILE_DEPENDENCIES(${_source} ${_outfile})
ENDIF ( EXISTS ${_abs_FILE} )
ENDFOREACH (_current_FILE)
ENDMACRO(QT4_AUTOUIC)
More information about the CMake
mailing list