martes, 19 de noviembre de 2013

Creación de complementos. Paso 0: configurar un proyecto

Alguien en el foro preguntó cómo hacer para utilizar OpenCV (una biblioteca con todo tipo de utilidades para cuestiones relacionadas a la visión computacional y bastante popular por estos días) en ZinjaI y en Windows. Alguna vez ya escribí de forma genérica acerca de cómo configurar un proyecto en ZinjaI para utilizar una biblioteca. Eso sigue siendo bastante cierto, pero el detalle del cambio de ABI del compilador que comenté en este otro post complicó las cosas. Y aún sin ese problema, las instrucciones aquellas son solo para compilar, pero nos vendría bien también armar una plantilla de proyecto, tener un índice de autocompletado, tal vez acceso a la referencia, etc. Entonces hoy voy a tomar el caso de OpenCV como ejemplo y contar paso a paso cómo armar todo eso y empaquetarlo en un complemento para instalar en ZinjaI en dos pasos. Espero que con este ejemplo los usuarios más interesados se animen a amar sus propios templates, autocompletados, o hasta complementos para compartir con los demás usuarios de ZinjaI.

En este primer post nos contentaremos con probar si sirven los archivos que bajamos del sitio oficial de la biblioteca y recompilarla en caso contrario. Al final, solo tendremos un proyecto andando, pero no una plantilla adecuada ni un complemento. Estos primeros pasos varían muchísimo según cada biblioteca, así que lo más general para armar complementos vendrá en los dos posts siguientes. Pero son estos problemas del principio generalmente los que más justifican la tarea de armar un complemento.

Lo primero que necesitamos es tener un proyecto andando, para tomar de base para la plantilla. Para que el proyecto ande, necesitamos los headers y los binarios de la biblioteca. Esto se puede buscar en el sitio de la biblioteca, pero no siempre sirve. A veces no tenemos los binarios necesarios para el compilador que queremos utilizar. En el caso de OpenCV se encuentran en su sitio binarios para MinGW, aunque no aclara para cual versión. Empecemos a armar el proyecto entonces para probarlos. Los pasos por ahora son:
  1. Descargar OpenCV ya compilada para Windows. Desde el sitio de OpenCV el link está bastante a mano, y nos descarga un ejecutable autoextraible. Es decir, que al ejecutar el archivo descargado nos pide un lugar para descomprimir todos los archivos de la biblioteca.
  2. Buscar entre esos archivos si tenemos lo necesario. Supongamos que lo descomprimimos en "C:\OpenCV". En este caso, podemos encontrar en "C:\OpenCV\build\include" los headers, y en "C:\OpenCV\build\x86\mingw" los binarios (ahí dentro están las carpetas "lib" con los binarios necesarios para el enlazado, y la carpeta "bin" con los dlls necesarios para poder ejecutar).
  3. Teniendo eso a mano, probemos crear el proyecto nuevo y configurarlo. Para configurarlo, si utilizamos la plantilla básica ("<incluir archivo y función main>") podemos reemplazar el main con algún código de ejemplo de algún tutorial o que encontremos en algún foro (como este), y luego configurar la compilación. Para eso vamos al menú Ejecución, seleccionamos "Opciones..." y ponemos:
    • el directorio de los headers ("C:\OpenCV\build\include") en el campo "Directorios adicionales para buscar cabeceras" (pestaña Compilación), 
    • el directorio lib ("C:\OpenCV\build\x86\mingw\lib") en el campo "Directorios adicionales para buscar bibliotecas" (pestaña Enlazado), 
    • y la lista de bibliotecas ("opencv_core246 opencg_highgui246 ...") en el campo "Bibliotecas a enlazar" (pestaña Enlazado). Aquí van minimamente los archivos de la carpeta lib (sin el prefijo lib ni la extensión) y tal vez algunas dependencias (normalmente bibliotecas Windows). Es importante el orden de estos archivos, y no olvidarse ninguno (sino tendremos errores del tipo "undefined reference to...". Nuevamente, google les ayudará a encontrar la lista correcta (si encuentran el comando para compilar un ejemplo con mingw, busquen los argumentos que empiezan con "-l" y copienlos sin el "-l").
    • Si en las opciones de compilación ven algún -DALGO agreguen ese ALGO a la lista de "Macros a Definir" en la pestaña Compilación.
  4. Probar compilar. Si aparecen problemas o errores, revisar el paso 3 (aquí hay tips de dónde buscar cada tipo de error). Si compila bien, pero no ejecuta porque faltan DLLs (este será el caso), copiarlas a la carpeta del proyecto (desde el directorio bin que encontramos antes, "C:\OpenCV\build\x86\mingw\bin").

Si todo fuera bien, ya tendríamos el proyecto andando, pero con OpenCV tenemos este problema de que está compilado con una versión de MinGW diferente a la de ZinjaI y entonces el programa revienta. En mi caso, vi un mensaje de error algo raro y poco descriptivo, y luego de buscar en Google al respecto, concluí que esa diferencia era la causa. Si no tuvieramos ese error, podríamos pasar directamente al siguiente post, donde explico cómo convertir el proyecto en plantilla y otras buenas cosas. Pero en este caso lo tenemos, y la única solución segura es compilar nuevamente la biblioteca. No siempre es fácil, pero allá vamos:

  1. Cada biblioteca usa algún mecanismo de generación de los pasos para compilarla más o menos conocido. En el caso de OpenCV usa CMake (nos damos cuenta por el archivo "CMakeLists.txt"). CMake es una herramienta que genera los Makefiles (archivos con reglas más específicas para finalmente compilar). Entonces el primer paso es descargar e instalar CMake. Si no usara CMake, tal vez sería un script configure para ejecutar desde msys, o alguna otra variante. Tendrían que leer un poco, ya no hay aquí receta universal.
  2. CMake tiene una interfaz gráfica para hacer las cosas más fácil, pero si lanzamos esa interfaz desde el menú inicio no va a encontrar el compilador que trae ZinjaI, ya que para que lo encuentre habría que modificar la variable de entorno PATH. Pero si lanzamos una consola desde (el menú Herramientas de) ZinjaI, dentro de esa consola las variables sí están modificadas. Desde la misma, podemos lanzar la gui de cmake llendo a su carpeta de instalación con "cd .." y "cd "cmake 2.8"", y ejecutar allí "cmake-gui".
  3. En la interfaz de cmake tenemos que completar los dos primeros campos de texto, para decirle donde estan los fuentes (es decir, la carpeta donde descomprimimos opencv) y donde queremos que ponga las cosas que compile. En el ejemplo sería "c:\opencv\sources" y "c:\opencv\booga". En lugar de "booga" pueden poner cualquier nombre de carpeta que no exista (usualmente pongo "build", pero en este caso ya existe).
  4. Luego, le damos al botón "Configure", y cuando nos pregunta qué "generator" utilizar elegimos "MinGW Makefiles". Cuando cmake termine de trabajar, tendremos todo listo para efectivamente compilar la biblioteca.
  5. Ahora, desde la consola vamos a la carpeta "booga" ( con "cd c:\opencv\booga") y ejecutamos allí "mingw32-make". Después de un buen rato, abrá terminado y tendremos por ahí los nuevos binarios de la biblioteca.

Ahora resta reconfigurar el proyecto para que busque estos nuevos archivos. Vamos a ZinjaI, menú Ejecución, Opciones, pestaña Bibliotecas, y en "Directorios adicionales..." colocamos "C:\opencv\booga\lib". Con eso ya compila. En los proyectos que utilicen DLLs (como este), también hay que actualizarlas. Es decir, copiar los archivos .DLL de "C:\opencv\booga\bin" a la carpeta del proyecto. Si siguieron correctamente estos pasos, el ejemplo tendría que estar funcionando sin problemas.

Y hasta aquí llego por hoy, habiendo explicado casi nada directamente relacionado a la construcción de complementos, pero sí habiendo dejado un ejemplo de lo primero que se necesita antes de empezar, que es normalmente lo más complicado. Voy a tomarlo como base para los ejemplos de la segunda parte. Si lo intentan reproducir ustedes y encuentran problemas que no hayan quedado bien explicados, consulten en los comentarios.

Este tema continúa en Creación de complementos. Paso 1: relatividad

No hay comentarios:

Publicar un comentario