2010-09-06 7 views
5

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

+0

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? –

+1

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. –

+0

@ 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). –

Respuesta

1

En referencia a la documentación "Utilización del MOC" (http://doc.qt.nokia.com/4.1/moc.html), sólo había necesidad de importar "foo. moc "al final de su archivo de implementación. Como no puede modificar las reglas de compilación de forma correspondiente, intente exportar un archivo .pro y aplique la regla de compilación como lo sugiere el documento de nokia.

2

Las versiones recientes de CMake tienen "automoc", que funcionó como un encanto para mí: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc

sólo tiene que añadir en el CMakeLists.txt:

set(CMAKE_AUTOMOC TRUE) 

y luego en el CPP (por ejemplo, ejemplo. cpp) file:

#include "example.moc" 

(el * .moc debe coincidir con el nombre del archivo cpp).

Cuestiones relacionadas