Estoy desarrollando un gran proyecto utilizando Qt 4.6, CMake 2.8 y Visual Studio 2008 para la plataforma Windows.Qt, CMake, Visual Studio y Q_OBJECT en archivos cpp
En lo que respecta al sistema de compilación, todo es estándar: estoy usando la macro QT4_WRAP_CPP
de CMake para generar archivos moc a partir de archivos de encabezado, que luego se vinculan al último ejecutable en el comando add_executable
. Todo está funcionando como se esperaba
La única restricción con esta configuración es que no puedo definir widgets o ayuda utilizando Q_OBJECT
en .cpp archivos. Esto sería muy conveniente para pequeñas clases de ayudantes específicas del contexto que deberían aparecer justo al lado de donde se usan.
Me trataron de pasar toda la lista de archivos fuente (tanto .h y .cpp) a QT4_WRAP_CPP
, en lugar de sólo los archivos de cabecera, pero eso no funciona (enlace falla debido a alguna relacionada con moc los símbolos no están definidos).
Creo que el problema es que, por un par de archivos foo.h y foo.cpp dado, el QT4_WRAP_CPP
macro generará el mismo archivo moc (moc_foo.cxx) en el mismo directorio, y obviamente eso significa que el primer archivo será sobrescrito por el segundo y, como resultado, faltarán símbolos en el tiempo del enlace.
¿Hay alguna manera de solucionar este problema o solucionarlo? Por ejemplo, he intentado añadir una regla específica para foo.cpp de la forma
QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc)
y luego añadir
#include "foo.moc"
al final de foo.cpp. Creo que esto debería funcionar, pero lamentablemente Visual Studio solo permite una regla de compilación por archivo, y .cpp los archivos ya tienen una regla de compilación (compilación a archivo de objeto), por lo que este enfoque no funciona, al menos con Visual Studio .
Otra idea que tenía era crear una nueva macro, QT4_WRAP_CPP_WITH_PREFIX
decir, basado en QT4_WRAP_CPP
(que se define en share/cmake-2.8/Módulos/Qt4Macros.cmake), que tendría un argumento prefijo adicional y agregaría este prefijo a los archivos moc generados. De esa manera, llamaría al QT4_WRAP_CPP_WITH_PREFIX
dos veces, una para los archivos .h y una para los archivos .cpp, con diferentes prefijos. Lo que no me gusta de este enfoque es que estaría jugando con las funciones internas del soporte de Qa de CMake, en lugar de usar la API pública.
¿Alguna idea mejor?
Cheerz, Franz
No estoy seguro de entender este bit: "La única restricción con esta configuración es que no puedo definir widgets o ayuda utilizando Q_OBJECT en archivos .cpp". ¿Nunca deberías necesitar ejecutar MOC en algo más que archivos de encabezado? –
Encuentro conveniente definir ocasionalmente una pequeña clase de ayuda en un archivo .cpp y no exponerlo fuera de este archivo .cpp. Para esto necesito poder ejecutar MOC en archivos .cpp. El enfoque macro 'QT4_WRAP_CPP_WITH_PREFIX' delineado en mi publicación funciona como un amuleto. –
@ FrançoisBeaune: ¿alguna vez se te ocurrió una solución para esto? Incluso para algo tan simple: # include # include # include clase MiClase: QObject pública { Q_OBJECT }; int main (int, char * []) { MyClass myClass; return 0; } No puedo encontrar la forma de MOC, ya que está en un archivo cpp (y obtengo los errores de Vtable cuando intento construirlo normalmente). –