wxWidgets con Visual Studio 2005

Buscando por ahí frameworks alternativos a .NET y MFC, he encontrado por ahí dos candidatos muy interesantes (bueno, realmente no ha sido así, sino que ya sabía de ellos, pero queda más bonito decirlo de la otra forma). Es muy posible que el lector ya los conozca, y quizás los esté usando.


La diferencia más importante respeco a .NET consiste en que estos sí que son multiplataforma de verdad, es decir, sus aplicaciones se pueden ejecutar con una simple recompilación tanto en Windows, MAC o Linux, y a veces en otras plataformas más. Ya sé que el .NET no necesita recompilación, pero a la experiencia me remito: las compilaciones «AnyCPU» del .NET son erráticas, presentan un comportamiento diferente y en general terminan haciendo explotar la máquina virtual .NET en cuanto les das algo de caña.


Una de las alternativas es, ya lo habrán adivinado, las QT de Trolltech (qué curioso que una empresa se llame El troll tecnológico, por algo será). Esta biblioteca tiene, desde mi punto de vista, dos contrapartidas: es muy cara (unos 3.000 euros/año) y, al igual que el C++ para .NET, no es un C++ puro. En este caso es necesario un metacompilador que nos generará las clases a partir de lo realizado con los generadores visuales. Desde mi punto de vista adolece del mismo problema que el C++/CLI.


Evidentemente, existe la versión Open Source, pero con ella no se pueden realizar proyectos propietarios lo que, sumado al hecho de no ser un C++ puro, me retrae a probarla.


La otra que nos queda es, ya lo habrán adivinado, wxWidgets, antes wxWindows, nombre que Microsoft consiguó cambiar a golpe de talonario. Esta biblioteca no integra RTTI ni excepciones, cosa que no creo que tenga mucha importancia. Con ella se han construido muchos programas de éxito y, por tener, hasta tiene un IDE creado con ella misma. Este IDE se llama Code::Blocks, y tiene una pinta inmejorable, sobre todo las nighty builds. Pero como la mayoría de las cosas Open Source, está a medio hacer y tiene más problemas que cosas funcionan o, más bien, todo funciona pero no lo hace del todo bien.


Por ello, tras descartarlo, me decidí a integrar wzWidgets en el Visual Studio 2005. Integrar es un decir, porque lo único que he hecho es hacer que el VS2005 compile y trabaje con dicha biblioteca. Existen soluciones de integración comerciales, pero no creo que sean muy necesarias, ya que el IntelliSense con código nativo funciona correctamente en el VS2005 y el archivo de ayuda se puede abrir a mano.


PRIMER PASO: Obtener y compilar wxWidgets
El primer paso consiste en acercarnos a http://www.wxwidgets.org y bajarnos el código fuente de la biblioteca. Necesitaremos la versión completa o la MSW. Debemos descomprimirla sobre una ruta sin espacios en blanco. Una vez hecho esto, nos vamos a la carpeta



<ruta_wx>build/msw


mediante la consola de compilación que el Visual Studio nos proporciona (Ya saben: Inicio -> Visual Studio 2005 -> Tools -> Command Prompt).


Ahora debemos detenernos a considerar una serie de cosas. Existe una solución para generar la biblioteca completa, tan completa, que genera todas las combinaciones posibles, llenándonos el disco duro con casi doce gigas de código, por lo que no la vamos a utilizar. Lo normal es tener dos o cuatro versiones como mucho, y en casos extraordinarios hasta ocho. Podemos elegir entre:



  • Unicode y no Unicode

  • Estática y DLL

  • Modular y Monolítica

  • Debug y Release

El autor se ha construido la versión Unicode Estática Monolítica, tanto en Debug como Release. Para ello ha utilizado el fichero makefile.vc situado en la carpeta citada.


Para construir la versión de depuración ejecutamos:



nmake -f makefile.vc UNICODE=1 BUILD=debug MONOLITHIC=1


y para la Release:



nmake -f makefile.vc UNICODE=1 BUILD=release MONOLITHIC=1


Si queremos trabajar con DLLs (cosa que sólo recomiendo si se van a distribuir muchas aplicaciones en un mismo equipo), tan sólo debemos añadir «SHARED=1» a las dos líneas anteriores. Otro tipo de build que podemos hacer es enlazar con las bibliotecas de tiempo de ejecución estáticas del Visual C++, con lo que evitaremos el hecho de tener que distribuir las DLL del Visual Studio 2005. En ese caso debemos añadir «RUNTIME_LIBS=static» a los comandos anteriores. Quizás sea esta la mejor opción de todas, para evitar el error que suele aparecer casi siempre en el que la aplicación, en lugar de decirnos que le falta tal o cual DLL, nos dice que la reinstalemos. Si quitamos «MONOLITHIC=1», en lugar de generar una DLL o una LIB de proporciones considerables, se crearán varias, cada una con un subconjunto de toda la biblioteca.


En la carpeta «<ruta_wx>libvc_lib» podemos encontrar las bibliotecas compiladas y listas para integrar. Si queremos comprobar si todo ha ido bien, podríamos ir a la carpeta «samplesminimal» y ejecutar el mismo comando que para construir las bibliotecas. Deberíamos obtener un ejecutable que nos lanzará una aplicación Windows básica.


SEGUNDO PASO: Integrar en Visual Studio
Ahora viene la que quizás sea la parte más liosa de todas, y la que los tutoriales que he encontrado por ahí no terminan de explicar todo lo bien que sería necesario. Debemos abrir nuestra copia de Visual Studio, nos sirve incluso la Express con el Platform Builder instalado y las rutas correctamente establecidas para crear ejecutables nativos, cosa que sabremos que está bien si hemos podido compilar la biblioteca.


Creamos un proyecto vació, al que le añadiremos, copiándolo, el código que hay en el fichero «<ruta_wx>samplesminimalminimal.cpp» o asociando dicho archivo. Si intenamos compilar ahora veremos que el compilador no encuentra las rutas.


Nos vamos a las propiedades del proyecto, en la configuración Debug, y en la pestaña «C/C++ -> General», «Additiona Include directories», añadimos en primer lugar la ruta



<ruta_wx>libvc_libmswud


¿Por qué esta ruta, y por qué en primer lugar? Pues para que el compilador encuentre el archivo «wxsetup.h», que le indicará qué compilar y cómo. Dicho archivo depende de cada configuración, y por eso se sitúa en la carpeta de las bibliotecas. Si nos damos cuenta en el nombre de la ruta, «mswud», veremos que se trata de la versión Windows («msw»: MicroSoft Windows), Unicode («u») y Debug («d»).


La otra ruta a añadir es la típica de inclusión, «<ruta_wx>include».


Si hemos creado la biblioteca con la versión estática de las bibliotecas del Visual Studio (opción «RUNTIME_LIBS=static»), debemos ir a «C/C++ -> Code Generation» y cambiar el valor de «Runtime Library» de «Multi-threaded Debug DLL (/MDd)» a «Multi-threaded Debug (/MTd)», ya que si no lo hacemos obtendremos errores de símbolos duplicados durante el enlazado.


Ahora, en la pestaña «Linker -> General», en la opción «Additional Library Directories» tenemos que especificar la ruta a las nuevas bibliotecas,



<ruta_wxlibvc_lib»


Ya por último, en la pestaña «Linker -> Input» tenemos que añadir los ficheros de la biblioteca. Aquí es donde más errores cometen todos los tutoriales, pues no indican claramente qué ficheros incluir. Si hemos construido la versión monolítica, debemos añadir




  • wxexpatd.lib


  • wxjpegd.lib


  • wxmsw28ud.lib


  • wxpngd.lib


  • wxregexud.lib


  • wxtiffd.lib


  • wxzlibd.lib


  • comctl32.lib


  • rpcrt4.lib


  • winmm.lib


  • wsock32.lib

y si es la versión partida, debemos sustituir wxmsw28ud.lib por todas sus partes equivalentes. Observamos que los cuatro últimos ficheros no pertenecen a wxWdigets, si no al propio Visual Studio. Si no los incluímos, obtendremos errores por falta de símbolos.


Y ya está, ya podemos compilar nuestro proyecto.


También debemos repetir todos estos pasos para la compilación Release, pero cambiando la ruta de inclusión «<ruta_wx>libvc_libmswud» por «<ruta_wx>libvc_libmswu», y los nombres de los ficheros .lib por aquellos cuyo nombre no finalice en d.


TERCER PASO: Cabeceras Precompiladas
Las cabeceras precompiladas son el quebradero de cabeza de muchos, ya que el tema no está muy bien tratado por Microsoft. Otros compiladores que las soportan son más claros en detallar los pasos y el uso de las mismas. En nuestro caso, dado que no se trata de los ficheros de inclusión estándar de Microsoft, la gente de wxWidgets han solucionado el tema a su manera.


El uso de las cabeceras precompiladas requiere de dos pasos. El primero consiste en crearlas, el segundo en usarlas, ya que parece ser que los compiladores de Microsoft son incapaces de generarlas si no están y usarlas una vez generadas.


Lo primero nos vamos a las propiedades del proyecto y en la pestaña «C/C++ -> Precompiled Headers», en «Create/Use Precompiled Header» cambiamos la opción a «Use…», y en «Create/USE PCH Through File», tecleamos «wx/wxprec.h». Y por útlimo en «Precompiled Header File», colocamos el fichero



<ruta_wx>libvc_libwxprecd.pch.


Cerramos la ventan de las propiedades y construimos una vez nuestro proyecto, que nos creará el fichero «wxprecd.pch» en la carpeta de las bibliotecas de wxWidgets. De este modo ya no será necesario volver a generarlas si no cambiamos nada de la biblioteca. También podemos dejarlas en el directorio por defecto, pero en este caso tendremos que generarlas en cada proyecto.


Para usarlas, volvemos a las opciones del proyecto y cambiamos «Create…» por «Use…» en «Create/Use Precompiled Header». Para la pestaña de Release también repetiremos los pasos, pero en este caso el nombre será



<ruta_wx>libvc_libwxprecd.pch


o el que nos pone el entorno por defecto.


Para utilizarlas, en nuestros programas debemos colocar



#include «wx/wxprec.h»


en todos los ficheros de código fuente.

10 comentarios sobre “wxWidgets con Visual Studio 2005”

  1. Saludos y Gracias por la guía.

    He seguido la guía de principio a fin y me he encontrado con el siguiente problema.

    Cuando le doy a «generar solución», me aparecen los dos errores que expongo a continuación.

    c:documents and settingsjuanjoclausellmis documentosvisual studio 2005projectspruebawxpruebawxminimal.cpp(21) : error C2859: c:documents and settingsjuanjoclausellmis documentosvisual studio 2005projectspruebawxpruebawxdebugvc80.pdb no es el archivo pdb que se utilizó al crear este encabezado precompilado; vuelva a crear el encabezado precompilado.
    c:documents and settingsjuanjoclausellmis documentosvisual studio 2005projectspruebawxpruebawxminimal.cpp(21) : error C2859: c:documents and settingsjuanjoclausellmis documentosvisual studio 2005projectspruebawxpruebawxdebugvc80.idb no es el archivo idb que se utilizó al crear este encabezado precompilado; vuelva a crear el encabezado precompilado.

    Que es justo en la linea de código donde se encuentra #include «wx/wxprec.h»

    Como podeis ver utilizo el VS 2005 Pro.

    Alguien sabe que he hecho mal?

    Toda ayuda será bien recibida.

    Un saludo.

  2. Tienes problemas con el fichero de información de depuración, porque has cambiado la secuencia de las cabeceras precompiladas (que es un problema del Visual Studio, que no es capaz de detectar que ésta ha cambiado y volverlas a generar si no es una solución MFC).

    La solución pasa por volverlas a generar cada vez que cambies algo de la secuencia de los ficheros incluidos. Repite lo que comento en la entrada sobre las cabeceras precompiladas (para volver a generarlas).

  3. Gracias Rafael, por la guía y por contestar tan rápido.

    Sin embargo, tras repetir los pasos en la entrada sobre las cabeceras compiladas, y eso que no habia cambiado nada, me sigue dando exactamente el mismo error.

    Adjunto imagenes con la configuración, aunque creo que no se me ha pasado nada.

    http://img137.imageshack.us/img137/5923/adicionalincludescc0.jpg
    http://img401.imageshack.us/img401/7083/generacioncodigocs5.jpg
    http://img186.imageshack.us/img186/8070/linkergeneralpb1.jpg
    http://img78.imageshack.us/img78/7521/dependenciasadicionalesjy5.jpg
    http://img45.imageshack.us/img45/139/cabecerasprecompiladasoz0.jpg

    Gracias de nuevo.

    Un saludo.

  4. A ver, en tu última captura: «Crear o utilizar encabezado precompilado». ¿Lo cambias primero por «Crear…» y generas la solución antes de volver a cambiar a «Utilizar…»

  5. Exacto, primero lo dejo en «Crear …» pero ni asi me genera la solución, a ver si la próxima semana averiguo que tengo mal configurado.

    Un saludo y Gracias.

  6. T.T!, estoy tratando compilarlas con visual studio 2008 y a la hora de tratar de compilar, despues de haber generado el encabezado precompilado me tira errores al vincular =/..

    minimal.obj : error LNK2001: símbolo externo «public: virtual bool __thiscall wxApp::Initialize(int &,char * *)» (?Initialize@wxApp@@UAE_NAAHPAPAD@Z) sin resolver

    qué podría ser?
    ya verifique las libs incluidas, tengo:

    wxexpatd.lib
    wxjpegd.lib
    wxmsw28ud.lib
    wxpngd.lib
    wxregexud.lib
    wxtiffd.lib
    wxzlibd.lib
    comctl32.lib
    rpcrt4.lib
    winmm.lib
    wsock32.lib

    no se me ocurre que más pueda ser xD

  7. Hola, Tira. Pues no tengo ni idea, ya que las bibliotectas que has puesto son todas las que hay que poner…

    De todos modos, según el mensaje que pones, el enlazador no es capaz de encontrar el método Initialize de wxApp… Causas posibles: que se haya olvidado de compilar un fichero, que tu compilación provenga a medio compilar de otro compilador… porque supongo que si estás haciendo una aplicación de demo, hayas definido el método Initialize en tu clase heredada de wxApp, ¿no? Si es así debes tener también un error del compilador.

  8. hola buenos dias:

    intentando compilar esto, tal y como esta en el manual me da el siguiente error.

    1>—— Build started: Project: nuevo_proyecto, Configuration: Debug Win32 ——
    1>Linking…
    1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
    1>C:Documents and SettingsAdministradorMis documentosVisual Studio 2005Projectsnuevo_proyectoDebugnuevo_proyecto.exe : fatal error LNK1120: 1 unresolved externals
    1>Build log was saved at «file://c:Documents and SettingsAdministradorMis documentosVisual Studio 2005Projectsnuevo_proyectonuevo_proyectoDebugBuildLog.htm»
    1>nuevo_proyecto – 2 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Responder a rfog Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *