cerrar-sesion editar-perfil marker video calendario monitor periodico fax rss twitter facebook google-plus linkedin alarma circulo-derecha abajo derecha izquierda mover-vertical candado usuario email lupa exito mapa email2 telefono etiqueta

400390106. Allanando el camino a la portabilidad

Escrito por Redacción en Secciones
no hay comentarios Haz tu comentario
Imagen de logotipo de facebook Imagen de logotipo de Twitter Imagen de Logotipo de Google+ Imagen de logotipo de Linkedin

Open C es un conjunto de bibliotecas C diseñadas para facilitar y fomentar el porteado de aplicaciones open-source de un sobremesa a la plataforma de teléfono móvil S60 de Nokia, (acomoda también la escritura de software para plataformas cruzadas). Open C ayuda a los desarrolladores de aplicaciones móviles de dos formas:

– Como las bibliotecas Open C se compilan en POSIX y otros proyectos open-source, el código portátil sobre Open C es más fácil de escribir. Eso ayuda a los desarrolladores a diseñar e implementar grandes bases de aplicaciones que tienen que ejecutarse en varios sistemas operativos.
– Open C abre las puertas a los programadores de C/C++ que no tienen experiencia con Symbian, pero que necesitan desarrollar aplicaciones para dispositivos móviles.

En el presente artículo, vamos a presentar open C (forum.nokia.com/openc) y mostrar cómo podemos portar con eficacia el código del que disponemos a la plataforma smartphone 260. Para ilustrarlo, vamos a portar SQLite (www.sqlite.org), una pequeña biblioteca C open-source que implementa un motor de base de datos SQL, auto-contenido, insertable y de configuración cero, desde un sobremesa al S60 (www.s60.com).

Detalles sobre Open C

Una vez más, Open C es una colección de bibliotecas basadas en POSIX y otros proyectos open-source. En su primer lanzamiento, Open C incluye más del 70 por ciento de la funcionalidad contenida en las siguientes bibliotecas:
– Libc. Bibliotecas C estándar, que incluyen rutinas de input/output estándar, rutinas de bases de datos, operadores de bits, operadores de cadenas, comprobaciones de carácter y operadores de carácter, rutinas de encriptado DES, asignación de almacenado, funciones de tiempo, sockets y comunicación de interproceso.
– Libm. Funciones aritméticas y matemáticas.
– Libpthread. La API de Pthreads ofrece una interfaz estándar IEEE Std1003.1c (POSIX) que implementa múltiples hilos de ejecución dentro de procesos de usuario tradicionales. Esta implementación está sólo como espacio de usuario. Pthreads proporciona funciones para la creación y destrucción de hilos, una interfaz al programador de hilos para establecer los parámetros para la programación de hilos, y mutex y variables de condición para ofrecernos mecanismos que nos permitan sincronizar el acceso a los recursos de procesos compartidos.
– Libz. La biblioteca de compresión Zlib ofrece funciones de compresión y descompresión dentro de la memoria, incluidas las comprobaciones de integridad de los datos no comprimidos.
– Libdl. Proporciona a los usuarios la funcionalidad de cargar DLL de forma dinámica.
– Libcrypto. La biblioteca crypto OpenSSL implementa una amplia gama de algoritmos criptográficos. Los servicios ofrecidos por esta biblioteca son utilizados por las implementaciones OpenSSL de SSL, TLS, y S/MIME, y se han usado también para implementar SSH, OpenPGP, y otros estándares criptográficos.
– Libssl. La biblioteca ssl OpenSSL implementa los protocolos Secure Sockets Layer (SSL v2/v3) y Transport Layer Security (TLS v1).
– Libcrypt. Bibliotecas de criptografía que contienen funciones para encriptar bloques de datos y mensajes y hashing de contraseñas.
– Libglib. Una biblioteca de utilidades de carácter general, que ofrece tipos de datos, macros, conversiones de tipo, utilidades de cadena, utilidades de ficheros, una abstracción de bucle principal, etc. Libssl funciona en muchas plataformas tipo UNIX, además de Windows, OS/2, y BeOS.

Open C se compila sobre P.I.P.S de Symbian. (abreviatura de «POSIX on Symbian»), que salió al mercado a principios de este año. Al igual que Open C, P.I.P.S. reduce el esfuerzo que se necesita para migrar los componentes/aplicaciones actuales de sobremesa y servidor desde otras plataformas al SO de Symbian. Las bibliotecas P.I.P.S. —libc, libm, libdl, y libpthread—fueron desarrolladas conjuntamente por Nokia y Symbian para garantizar que el código escrito sobre Open C hace llegar las prestaciones que se esperan de un entorno nativo. Open C añade a P.I.P.S. bibliotecas que proceden de OpenSSL, libz, y Glib (del proyecto GNOME).

Limitaciones de Open C

El primer lanzamiento de Open C no ofrece una funcionalidad completa. Por ejemplo:

– No se da soporte para señal, bifurcación (fork), ni exec. Si el software que queremos portar contiene estas invocaciones al sistema, deberemos analizar con cuidado cuanta modificación tenemos que hacer al software portado.

– dlsym. La búsqueda de direcciones mediante los nombres de símbolos no tiene soporte y tenemos que usar números ordinales en vez de nombres de símbolos. Se pueden obtener los números ordinales de las funciones exportadas del fichero de definición de módulos (.def) del DLL asociado, como en el listado número 1. Esta misma limitación se aplica para la función g_module_symbol. El primer lanzamiento del plug-in de la SDK de Open C nos permite compilar módulos y desplegarlos en los dispositivos móviles de los que disponemos, compilados en la 3ª edición de S60 y el Paquete 1 de Características de la 3ª edición de S60. La búsqueda de símbolos por nombre tendrá soporte con el Paquete 2 de Características de la 3ª edición de S50, cuando se usen los nuevos tipos de objetivos.


// This code is part of the libsliteU.DEF file //

EXPORTS

sqlite3AbortOtherActiveVdbes @ 1 NONAME

sqlite3AddCheckConstraint @ 2 NONAME

...

Listado número 1

– Open C no suministra API para el desarrollo de IU. Las IU se pueden escribir usando las API S60 existentes, y desarrolladas dentro de las ediciones Carbide.c++ Developer o Profesional. Las IU pueden ser también compiladas usando S60 Python (www.forum.nokia.com/python) con los vínculos Python para la funcionalidad exportada.

– Open C no ofrece vínculos de C nativos a servicios de plataforma Symbian/S60 como telefonía, mensajería, Bluetooth, servicios de localización, y cosas por el estilo. En esos casos, tenemos que usar las interfaces C++ que se incluyen. Desde la perspectiva de la portabilidad, no obstante, recomendamos aislar el código fuente específico para plataforma en distintos ficheros fuente:


/* The below won't work in */

/* Open C SDK plug-in */

ret = g_module_symbol(module,

"sqlite3AbortOtherActiveVdbes"

,&ptr);

/* And it has to be like below. */

/* 1 is the ordinal of the */

/* exported function */

ret = g_module_symbol(module,

"1", &ptr);

Las SDK de Open C

En Forum Nokia (www.forum.nokia.com/tools) hay disponible un plug-in de la caja de herramientas SDK de Open C para los dispositivos de la 3ª edición de S60 de Open C y el Paquete 1 de Características de la 3ª Edición de S60. Con el plug-in de la SDK de Open C, recomendamos usar la SDK S60 3ª Edición de C++ porque podemos así establecer como objetivo un conjunto amplio de dispositivos disponibles. El plug-in de la SDK de Open C contiene bibliotecas para compilar, runtimes para el emulador/objetivo, documentación y aplicaciones muestra. Los paquetes de runtime Open C firmados pueden ser enviados juntos con la aplicación, lo que resulta conveniente para que los usuarios finales lo puedan instalar.

Por su parte, Symbian va a lanzar el plug-in P.I.P.S. correspondiente, que contiene las cuatro bibliotecas desarrolladas conjuntamente con Nokia. Para garantizar la compatibilidad de fuentes y la binaria, los dos plug-ins contendrán exactamente la misma versión de las bibliotecas especificadas y los mismos binarios para las bibliotecas compartidas.

Open C será parte de la plataforma S60 empezando con el Paquete 2 de Características de la 3ª Edición de S60. El lanzamiento del Paquete 2 de Características incluirá las mismas API que en el actual plug-in de la SDK Open C, pero introducirá nuevos tipos de objetivos —STDEXE, STDDLL, y STDLIB—que facilitan el desarrollo permitiendo:

– Soporte para la búsqueda de direcciones por nombre cuando se usan nuevos tipos de objetivos. Las funciones dlsym y g_module_symbol funcionarán según se especifica y no tendremos ya que usar ordinales con esas funciones.

– No habrá necesidad de anotar fuentes con IMPORT_C y EXPORT_C cuando se use nuevos tipos de objetivos. Ello hace más fácil el portado cuando se portan bibliotecas exponiendo muchas API.

Estudio de un caso con Open C, Portado de SQLite para S60

Para ilustrar cómo usar Open C, vamos a portar SQLite (www.sqlite.org), una pequeña biblioteca C que implementa un motor de base de datos SQL, auto-contenido, insertable y de configuración cero, desde un sobremesa a la plataforma S60.

Pero antes de empezar a portar, tenemos que hacer algunos toques en la seguridad de la plataforma que está implicada en el portado. La seguridad de la plataforma protege la integridad de los dispositivos, ofrece confidencialidad para los datos sensibles, y controla los accesos a operaciones sensibles. En el desarrollo de la aplicación, la seguridad de la plataforma conlleva la adquisición de certificados y el establecimiento de capacidades para las aplicaciones. Los dos aspectos principales en la seguridad de la plataforma son:

– Encapsulado de datos. Las aplicaciones y los usuarios tienen acceso sólo a ciertas áreas del sistema de ficheros. En la práctica, las aplicaciones pueden acceder a sus propios directorios privados y a los directorios marcados como abiertos. Eso quiere decir que una aplicación no puede acceder al directorio privado y los datos de otra aplicación, ni puede acceder al directorio en el que se almacenan los ejecutables.

– Capacidades. Se usan para especificar qué funcionalidad y aplicación es fiable para su uso; las capacidades se asignan a la aplicación en el momento de la compilación y se vigilan durante el tiempo de ejecución. Una vez se han asignado las capacidades a las aplicaciones, no se pueden cambiar. Así, las aplicaciones tienen un conjunto de capacidades inalterables que describen qué acceso tiene la aplicación a las API. Las capacidades se especifican en el fichero MMP.

La 3ª edición de S60 requiere el firmado de ficheros .sis, lo que significa que todos los ficheros .sis han de ser firmados mediante las utilidades SignSIS o CreateSIS (que se incluyen en la SDK) antes de instalarlas en los dispositivos. El paquete de instalación puede firmarse con una clave auto-creada y se puede generar el certificado con la SDK. El firmado de .sis dificulta manipular o cambiar el paquete de instalación original.

Además, las aplicaciones pueden ser certificadas por Symbian Signed. Una aplicación Symbian Signed ha pasado una serie de pruebas y la identidad del originador ha sido verificada. El objetivo que hay tras estas medidas es evitar el software malicioso, dándole a la aplicación una firma digital a prueba de manipulaciones. Para más detalles sobre seguridad y firmado de plataformas, véase «The SymbianOS Security Model,» de Regan Coleman (www.ddj.com/dept/architect/193100464).

Ahora estamos listos para empezar el portado, que consiste en ocho pasos.

1. Análisis inicial. Una vez más, Open C es un subconjunto de funcionalidades de bibliotecas seleccionadas, no la implementación completa que encontramos en la mayoría de los sistemas UNIX. Por tanto, iniciamos nuestro portado de SQLite configurando (./configure) y compilando (make) SQLite en una caja de Linux. En este punto, merece la pena observar que tenemos que capturar el registro de compilación; lo necesitaremos más adelante para identificar qué ficheros fuentes son para qué bibliotecas. Una vez hemos compilado con éxito el código fuente en la caja de Linux, usamos herramientas estándar (como ldd y nm) para ver qué bibliotecas y funciones está utilizando. Al hacerlo, observamos que SQLite es dependiente prácticamente nada más que de libc.

2. Traslado de la fuente al Entorno S60. Copiemos ahora el entorno que teníamos en la caja de Linux al entorno de desarrollo S60. Normalmente conviene que hagamos esto, porque a menudo los scripts (./configure) crean ficheros de configuración ( como config.h) que definen la funcionalidad de nuestro entorno, y nos irá mejor con algunos valores iniciales. Como la compilación del entorno para Symbian es distinta a la del mundo de UNIX, necesitamos compilar algunos makefiles intermedios. Conforme a las convenciones de codificado de S60 y a las estructuras del directorio, hacemos una carpeta de grupos para nuestro proyecto en el entorno S60: \SQLite\group.

3. Definición del entorno y los makefiles. Esta carpeta del grupo en el entorno de desarrollo Symbian/S60 define los entornos objetivos, los ficheros de encabezamiento exportables, los makefiles de Symbian (denominados «MMP-files» en el desarrollo Symbian), y algunos otros ficheros de recursos para proyectos. Empezamos creando un fichero de configuración para proyectos denominado bld.inf (véase el listado número 2).


-- begin file bld.inf --

// Project configuration file for SQLite3

// Project platforms

PRJ_PLATFORMS

WINSCW ARMV5 GCCE

// Project exports

PRJ_EXPORTS

// MMP files for project components

PRJ_MMPFILES

libsqlite.mmp

sqlite3.mmp

end file bld.inf –

Listado número 2

La cuarta línea del Listado número 2 define las plataformas objetivo. En este caso, es el emulador WINSCW (para «Windows CodeWarrior,» un IDE para desarrolladores de Windows) y ARMV5 (el compilador objetivo), y GCCE (para el compilador objetivo que usa gcc). PRJ_EXPORTS establece que estamos a punto de exportar un fichero de encabezado (sqlite3.h, en este caso) e identifica la localización a la que lo exportamos. PRJ_MMPFILES define los makefiles Symbian para ambos objetivos —uno para la biblioteca SQLite, el otro para el ejecutable para que podamos usar la biblioteca.

4. Creación de makefiles MMP para el proyecto A continuación, tenemos que establecer los ficheros MMP que aparecen en el listado de bld.inf. En este punto conviene tener a mano el registro de compilación para ver qué ficheros se necesitan para compilar la biblioteca SQLite además de la apliación SQLite. El listado número 3 presenta el fichero MMP.


-- begin file libsqlite.mmp --

// General properties

TARGET libsqlite.dll

TARGETTYPE dll

CAPABILITY NONE

UID 0x1000008d 0x00000001

//EPOCHEAPSIZE 4 4194304 // min. 4KB and max 4MB

// Allow global writeable static data

EPOCALLOWDLLDATA

// Source files

SOURCEPATH ..\src

SOURCE alter.c analyze.c attach.c auth.c btree.c build.c callback.c complete.c

SOURCE date.c delete.c expr.c func.c hash.c insert.c loadext.c main.c os.c

SOURCE os_unix.c os_win.c os_os2.c pager.c pragma.c prepare.c printf.c

SOURCE random.c select.c table.c tokenize.c trigger.c update.c util.c vacuum.c

SOURCE vdbe.c vdbeapi.c vdbeaux.c vdbefifo.c vdbemem.c where.c utf.c

SOURCE legacy.c vtab.c

USERINCLUDE ..\src

USERINCLUDE ..

// System include paths

SYSTEMINCLUDE \Epoc32\include

SYSTEMINCLUDE \Epoc32\include\stdapis

// Library dependencies

LIBRARY libc.lib

end file –

Listado número 3

En los makefiles MMP de Symbian, definimos el objetivo, el tipo de objetivo, las capacidades y las necesidades ejecutables, y las fuentes de nuestro binario. Todos los proyectos en los que se usa Open C han de especificar que el sistema incluye ruta para los encabezados Open C. Los encabezados Open C están situados en la carpeta \epoc32\include\stdapis.

Al final del fichero, definimos las bibliotecas necesarias para compilar SQLite; véase el listado número 4 para el fichero MMP específico.


-- begin file sqlite3.mmp

// SQLite3 executable component properties

// General properties

TARGET sqlite3.exe

TARGETTYPE exe

CAPABILITY NONE

UID 0x100039CE 0xA000029F

VENDORID 0

START RESOURCE sqlite_reg.rss

#ifdef WINSCW

TARGETPATH \private\10003a3f\apps

#else

TARGETPATH \private\10003a3f\import\apps

#endif

END //RESOURCE

// Allow global writeable static data

EPOCALLOWDLLDATA

// Source files

SOURCEPATH .

SOURCEPATH ..\src

SOURCE shell.c

USERINCLUDE ..\src

// System include paths

SYSTEMINCLUDE \epoc32\include

SYSTEMINCLUDE \epoc32\include\stdapis

// Library dependencies

STATICLIBRARY libcrt0.lib

LIBRARY libc.lib

LIBRARY euser.lib

LIBRARY libsqlite.lib

-- end file sqlite3.mmp --

Listado número 4

El ejecutable (sqlite.exe) tiene un fichero MMP de aspecto diferente. Aquí establecemos que el tipo de objetivo es un EXE. Hay también un fichero de registro de aplicación para sqlite.exe, importante para que aparezca un icono en nuestro teléfono S60. Vinculamos además una biblioteca estática libcrt0.lib a nuestro binario, de manera que podamos codificar la función main() al punto de entrada para este ejecutable.

Hay que especificar siempre libcrt0.lib como la primera biblioteca y contiene el punto de entrada E32Main necesario para las aplicaciones Symbian. No debe sorprendernos que haya bibliotecas adicionales, por lo que necesitamos tener también la biblioteca base de Symbian denominada euser.lib, la libc, además de nuestra flamante biblioteca sqlite. Libc es la única biblioteca obligatoria con la que tenemos que vincular al utilizar Open C. Dependiendo de las API, puede que tengamos que especificar además otras bibliotecas.

5. Mostrar a la aplicación SQLite la Red de Software S60. El fichero de registro de la aplicación (denominado sqlite_reg.rss) tiene el siguiente aspecto:


#include

UID2 KUidAppRegistrationResourceFile

UID3 0xA000029F

RESOURCE APP_REGISTRATION_INFO

app_file="SQLite3";

embeddability=KAppNotEmbeddable;


6. Modificaciones necesarias en el código fuente Ahora que ya hemos realizado el trabajo básico, necesitamos empezar a modificar el código fuente. Recordemos que hemos mencionado que aunque el código fuente es C, no exportamos ninguna función sin anotarlo de manera explícita. Ello es así porque estamos compilando el código fuente como si fuera código C++.

Para que la biblioteca exporte funciones o para que una aplicación importe una función de la biblioteca, necesitamos usar las macros EXPORT_C e IMPORT_C, respectivamente. En un DLL cargado estáticamente, se necesita una biblioteca de importación para resolver la referencia al tiempo de enlace. Por tanto, al exportar una función concreta de una biblioteca, añadimos EXPORT_C delante de la función como ejemplo. Aquí tenemos algunos:


/* src/main.c */—

/* The version of the library */

EXPORT_C const char

sqlite3_version() =

SQLITE_VERSION;

EXPORT_C const char

*sqlite3_libversion(void)

return sqlite3_version;

EXPORT_C int

sqlite3_libversion_number(void)

return SQLITE_VERSION_NUMBER;

/* sqlite3.h */—

IMPORT_C int sqlite3_open(

const char *filename,

/* Database filename (UTF-8) */

sqlite3 **ppDb

/* OUT: SQLite db handle */

);

IMPORT_C int sqlite3_open16(

const void *filename,

/* Database filename (UTF-16) */

sqlite3 **ppDb

/* OUT: SQLite db handle */

);

En el Paquete 2 de Características de la 3ª edición de S60, no tenemos que usar IMPORT_C/EXPORT_C con los nuevos tipos de objetivo. Esto facilita el portado.

Una modificación en el fichero shell.c del ejecutable sqlite.exe es comentar el fichero signal.h, porque Open C no soporta señales. La única señal que utilizó este ejecutable es SIGINT, que fue utilizada para abortar la ejecución del proceso.

Como sqlite3.exe es un ejecutable con el punto de entrada main(), estas sentencias han de añadirse a shell.c para superar una cuestión con la cadena de herramientas GCCE (esto es aplicable sólo al plug-in de la SDK de Open C):


#ifdef __SYMBIAN32__

/* GCCE specific header file for */

/* GCCE toolchain problem that */

/* must be included when using */ /* main() entry point.*/

#include

#endif

Si todo ha ido bien, tendremos ahora que hacer lo siguiente para compilar y elaborar todas las bibliotecas.

7. Compilar y finalizar todo desde la línea de comandos Una vez se han compilado los componentes, necesitamos fabricar un instalable para el teléfono S60. Para fabricar un instalable, haremos un fichero de texto para paquetes de instalación (denominado «pkg file») que contenga instrucciones sobre cómo compilar los paquetes de instalación del software (denominados «sis files»):

;Header

#"sqlite3",(0xA000029F),1,0,0

;Supports S60 3.0

(0x101F7961), 0, 0, 0,

"S60ProductID"

;Localized Vendor name

%"sqlite3"

;Unique Vendor name

:"Vendor"

;Files to install

;sqlite3.exe

"\epoc32\release\ARMV5\UDEB\sqlite3.

exe"-"!:\sys\bin\sqlite3.exe"

"\epoc32\release\ARMV5\UDEB\libsqlite.

dll"-"!:\sys\bin\libsqlite.dll"

"\epoc32\data\z\private\10003a3f\

import\apps\sqlite_reg.rsc"

-"!:\private\10003a3f\import\apps\

sqlite_reg.rsc"

Para compilar el fichero SIS, usaremos las herramientas Makesis (que compila el paquete SIS) y Signsis (que firma el paquete). Debido a las avanzadas características de seguridad para la plataforma en el SO 9.1 y posterior de Symbian, todos los ficheros SIS tienen que estar firmados antes de la instalación. En este punto, podemos firmar el paquete:

makesis sqlite.pkg sqlite_unsig.sis

signsis -s sqlite_unsig.sis

sqlite.sis yourcert.

cer yourcert-key.pem

U obtener certificados para el desarrollador de Symbian (https://www.symbiansigned.com).

Conclusión

Así pues, ¿qué es lo que tenemos? Tenemos un SQLite ejecutándose en un smartphone S60. La contabilización de líneas de código fuente con find . -name "*.(c,h)" -exec cat \; | wc -l muestra 84.064 líneas de código. ¿Y cuanto tiempo se tardó? Aproximadamente tres horas. La portabilidad compensa.

Etiquetas

Noticias relacionadas

Comentarios

No hay comentarios.

Deja un comentario

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

Debes haber iniciado sesión para comentar una noticia.