1. Fusión frente a archivos fuente individuales2. Compilación de la interfaz de línea de comandos 3. Compilación de la interfaz TCL 4. Construyendo la fusión 5. Construyendo una DLL de WindowsCómo compilar SQLite

Visión general

SQLite es código fuente ANSI-C. Debe compilarse en código de máquina antes de que sea útil. Este artículo es una guía de las diversas formas de compilar SQLite.

Este artículo no contiene una receta paso a paso para compilar SQLite. Eso sería difícil ya que cada situación de desarrollo es diferente. Más bien, este artículo describe e ilustra los principios detrás de la compilación de SQLite. Los comandos de compilación típicos se proporcionan como ejemplos con la expectativa de que los desarrolladores de aplicaciones puedan utilizar estos ejemplos como guía para desarrollar sus propios procedimientos de compilación personalizados. En otras palabras, este artículo proporciona ideas y conocimientos, no soluciones llave en mano.

SQLite se crea a partir de más de cien archivos de código C y scripts distribuidos en varios directorios. La implementación de SQLite es ANSI-C puro, pero muchos de los archivos de código fuente en lenguaje C son generados o transformados por programas auxiliares en C y scripts AWK, SED y TCL antes de ser incorporados a la biblioteca SQLite terminada. Construir los programas en C necesarios y transformar y / o crear el código fuente en lenguaje C para SQLite es un proceso complejo.

Para simplificar las cosas, SQLite también está disponible como un archivo de código fuente de fusión empaquetado previamente: sqlite3.c. La fusión es un solo archivo de código ANSI-C que implementa toda la biblioteca SQLite. La fusión es mucho más fácil de manejar. Todo está contenido en un solo archivo de código, por lo que es fácil colocarlo en el árbol de fuentes de un programa C o C ++ más grande. Todos los pasos de generación y transformación de código ya se han llevado a cabo, por lo que no hay programas C auxiliares para configurar y compilar ni scripts para ejecutar. Y, debido a que toda la biblioteca está contenida en una sola unidad de traducción, los compiladores pueden realizar optimizaciones más avanzadas que resultan en una mejora del rendimiento del 5% al ​​10%. Por estos motivos, el archivo fuente de fusión (“sqlite3.c“) se recomienda para todas las aplicaciones.

Se recomienda el uso de la amalgama para todas las aplicaciones.

Sin duda, es posible crear SQLite directamente a partir de archivos de código fuente individuales, pero no se recomienda. Para algunas aplicaciones especializadas, puede ser necesario modificar el proceso de compilación de formas que no se pueden hacer usando solo el archivo fuente de fusión prediseñado descargado del sitio web. Para esas situaciones, se recomienda que se cree una combinación personalizada (como se describe a continuación) y se utilice. En otras palabras, incluso si un proyecto requiere construir SQLite comenzando con archivos fuente individuales, se recomienda que se utilice un archivo fuente de fusión como paso intermedio.

Una compilación de la interfaz de línea de comandos requiere tres archivos fuente:

  • sqlite3.c: El archivo fuente de fusión de SQLite
  • sqlite3.h: Los archivos de encabezado que acompañan a sqlite3.cy definen las interfaces de lenguaje C para SQLite.
  • shell.c: El programa de la interfaz de línea de comandos en sí. Este es el archivo de código fuente C que contiene la definición del principal() rutina y el bucle que solicita la entrada del usuario y pasa esa entrada al motor de la base de datos SQLite para su procesamiento.

Los tres archivos fuente anteriores están contenidos en el tarball de amalgama disponible en el página de descarga.

Para construir la CLI, simplemente coloque estos tres archivos en el mismo directorio y compílelos juntos. Usando MSVC:

cl shell.c sqlite3.c -Fesqlite3.exe

En sistemas Unix (o en Windows usando cygwin o mingw + msys), el comando normalmente se ve así:

gcc shell.c sqlite3.c -lpthread -ldl -lm

La biblioteca pthreads es necesaria para que SQLite sea seguro para los subprocesos. Pero dado que la CLI es de un solo subproceso, podríamos indicarle a SQLite que compile en un modo no seguro para subprocesos y, por lo tanto, omitir la biblioteca pthreads:

gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl -lm

La biblioteca -ldl es necesaria para admitir la carga dinámica, la interfaz sqlite3_load_extension () y la función SQL load_extension (). Si estas características no son necesarias, pueden omitirse utilizando la opción de tiempo de compilación SQLITE_OMIT_LOAD_EXTENSION:

gcc -DSQLITE_THREADSAFE=0-DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c

Es posible que desee proporcionar otras opciones de tiempo de compilación como -DSQLITE_ENABLE_FTS4 o -DSQLITE_ENABLE_FTS5 para búsqueda de texto completo, -DSQLITE_ENABLE_RTREE para la extensión del motor de búsqueda R * Tree, -DSQLITE_ENABLE_JSON1 para incluir funciones JSON SQL o -DSQLITE_ENABLE_DBSTAT_V para la tabla virtual . Para ver comentarios adicionales en los listados EXPLAIN, agregue la opción -DSQLITE_ENABLE_EXPLAIN_COMMENTS. En sistemas Unix, agregue -DHAVE_USLEEP = 1 si la máquina host admite la llamada al sistema usleep (). Agregue -DHAVE_READLINE y las bibliotecas -lreadline y -lncurses para obtener soporte para la edición de la línea de comandos. También es posible que desee especificar algunos conmutadores de optimización del compilador. (La CLI precompilada disponible para descargar desde el sitio web de SQLite usa “-Os”.) Hay innumerables variaciones posibles aquí. Un comando para compilar un shell con todas las funciones podría verse así:

gcc -Os -I.-DSQLITE_THREADSAFE=0-DSQLITE_ENABLE_FTS4 
   -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 
   -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_EXPLAIN_COMMENTS 
   -DHAVE_USLEEP -DHAVE_READLINE 
   shell.c sqlite3.c -ldl -lm -lreadline -lncurses -o sqlite3

El punto clave es este: la creación de la CLI consiste en compilar dos archivos en lenguaje C. los shell.c archivo contiene la definición del punto de entrada y el bucle de entrada del usuario y la fusión de SQLite sqlite3.c contiene la implementación completa de la biblioteca SQLite.

La interfaz TCL para SQLite es un pequeño módulo que se agrega a la fusión regular. El resultado es un nuevo archivo fuente combinado llamado “tclsqlite3.c“. Este único archivo de origen es todo lo que se necesita para generar una biblioteca compartida que se puede cargar en un estándar tclsh o deseo utilizando el Comando de carga TCL, o para generar un tclsh independiente que viene con SQLite integrado. Se incluye una copia de la fusión de tcl en el página de descarga como un archivo en el Tarball de té.

Para generar una biblioteca cargable por TCL para SQLite en Linux, el siguiente comando será suficiente:

gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl

La construcción de bibliotecas compartidas para Mac OS X y Windows no es tan simple, desafortunadamente. Para esas plataformas, es mejor utilizar el script de configuración y el archivo MAKE que se incluye con el Tarball de té.

Para generar un tclsh independiente que esté vinculado estáticamente con SQLite, use esta invocación del compilador:

gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm

El truco aquí es la opción -DTCLSH = 1. El módulo de interfaz TCL para SQLite incluye un principal() procedimiento que inicializa un intérprete de TCL y entra en un bucle de línea de comandos cuando se compila con -DTCLSH = 1. El comando anterior funciona tanto en Linux como en Mac OS X, aunque es posible que sea necesario ajustar las opciones de la biblioteca según la plataforma y la versión de TCL a la que se está vinculando.

Las versiones de la fusión de SQLite que se suministran en el página de descarga normalmente son adecuados para la mayoría de los usuarios. Sin embargo, algunos proyectos pueden querer o necesitar construir sus propias fusiones. Una razón común para crear una fusión personalizada es utilizar ciertas opciones de tiempo de compilación para personalizar la biblioteca SQLite. Recuerde que la fusión de SQLite contiene una gran cantidad de código C generado por programas y scripts auxiliares. Muchas de las opciones en tiempo de compilación afectan este código generado y deben proporcionarse a los generadores de código antes de ensamblar la fusión. El conjunto de opciones en tiempo de compilación que se deben pasar a los generadores de código puede variar de una versión de SQLite a la siguiente, pero en el momento de escribir este artículo (alrededor de SQLite 3.6.20, 2009-11-04) el conjunto de opciones que deben ser conocidos por los generadores de códigos incluye:

  • SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  • SQLITE_OMIT_ALTERTABLE
  • SQLITE_OMIT_ANALYZE
  • SQLITE_OMIT_ATTACH
  • SQLITE_OMIT_AUTOINCREMENT
  • SQLITE_OMIT_CAST
  • SQLITE_OMIT_COMPOUND_SELECT
  • SQLITE_OMIT_EXPLAIN
  • SQLITE_OMIT_FOREIGN_KEY
  • SQLITE_OMIT_PRAGMA
  • SQLITE_OMIT_REINDEX
  • SQLITE_OMIT_SUBQUERY
  • SQLITE_OMIT_TEMPDB
  • SQLITE_OMIT_TRIGGER
  • SQLITE_OMIT_VACUUM
  • SQLITE_OMIT_VIEW
  • SQLITE_OMIT_VIRTUALTABLE

Para crear una fusión personalizada, primero descargue los archivos fuente individuales originales en una plataforma de desarrollo unix o similar a unix. Asegúrese de obtener los archivos fuente originales, no los “archivos fuente preprocesados”. Se puede obtener el conjunto completo de archivos fuente originales del página de descarga o directamente desde el sistema de gestión de la configuración.

Suponga que el árbol de fuentes de SQLite se almacena en un directorio llamado “sqlite”. Planee construir la fusión en un directorio paralelo llamado (por ejemplo) “bld”. Primero construya un Makefile apropiado ya sea ejecutando el script de configuración en la parte superior del árbol de fuentes de SQLite, o haciendo una copia de uno de los Makefiles de plantilla en la parte superior del árbol de fuentes. Luego edite manualmente este Makefile para incluir las opciones de tiempo de compilación deseadas. Finalmente ejecuta:

make sqlite3.c

O en Windows con MSVC:

nmake /f Makefile.msc sqlite3.c

El “sqlite3.c” make target construirá automáticamente el “regular”sqlite3.c“archivo fuente de fusión, su archivo de encabezado”sqlite3.h“, y el “tclsqlite3.c“Archivo fuente de fusión que incluye la interfaz TCL. Posteriormente, los archivos necesarios se pueden copiar en los directorios del proyecto y compilarlos de acuerdo con los procedimientos descritos anteriormente.

Para construir una DLL de SQLite para usar en Windows, primero adquiera los archivos de código fuente combinados apropiados, sqlite3.cy sqlite3.h. Estos se pueden descargar desde el Sitio web SQLite o personalizado generado a partir de fuentes como se muestra arriba.

Con los archivos de código fuente en el directorio de trabajo, se puede generar una DLL usando MSVC con el siguiente comando:

cl sqlite3.c -link -dll -out:sqlite3.dll

El comando anterior debe ejecutarse desde el símbolo del sistema de MSVC Native Tools. Si tiene MSVC instalado en su máquina, probablemente tenga varias versiones de este símbolo del sistema, para compilaciones nativas para x86 y x64, y posiblemente también para compilación cruzada en ARM. Utilice el símbolo del sistema apropiado en función de la DLL deseada.

Si usa el compilador MinGW, la línea de comando es esta:

gcc -shared sqlite3.c -o sqlite3.dll

Tenga en cuenta que MinGW solo genera archivos DLL de 32 bits. Hay un MinGW64 separado proyecto que se puede utilizar para generar archivos DLL de 64 bits. Presumiblemente, la sintaxis de la línea de comandos es similar. También tenga en cuenta que las versiones recientes de MSVC generan archivos DLL que no funcionarán en WinXP y versiones anteriores de Windows. Por lo tanto, para obtener la máxima compatibilidad de la DLL generada, se recomienda MinGW. Una buena regla general es generar DLL de 32 bits usando MinGW y DLL de 64 bits usando MSVC.

En la mayoría de los casos, querrá complementar los comandos básicos anteriores con opciones de tiempo de compilación apropiadas para su aplicación. Las opciones de tiempo de compilación más utilizadas incluyen:

  • -Os – Optimizar por tamaño. Haga que la DLL sea lo más pequeña posible.

  • -O2 – Optimice la velocidad. Esto hará que la DLL sea más grande al desenrollar bucles e incorporar funciones.

  • -DSQLITE_ENABLE_FTS4 – Incluya el código del motor de búsqueda de texto completo en SQLite.

  • -DSQLITE_ENABLE_RTREE – Incluir la extensión R-Tree.

  • -DSQLITE_ENABLE_COLUMN_METADATA – Esto habilita algunas API adicionales que son requeridas por algunos sistemas comunes, incluido Ruby-on-Rails.