cpdo  Update of "AmalgamationBuild"

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview

Artifact ID: 71c5d92bf4a0cae59ab0ec444c800412a0d96b83
Page Name:AmalgamationBuild
Date: 2011-05-17 18:39:27
Original User: stephan
Parent: f5aad0ea2b0c707293b7386b767714c80ec8cd11
Content

ACHTUNG: THE CPDO WIKI IS NOW (AS OF 2011-May-17) MAINTAINED ON A DEDICATED WIKI SITE: http://whiki.wanderinghorse.net/wikis/cpdo/?page=AmalgamationBuild

The amalgamation build...

The build tree supports the generation of a so-called "amalgamation build". This is a single pair of header/impl files which are easy to import into arbitrary source trees.

It is created like this:

~> make amal

That creates the following files:

  • C mode: cpdo_amalgamation.[ch]
  • C++ mode: cpdo_amalgamation.[ch]pp. These include the C library and the C++ wrapper.

They include the driver-specific parts, but they are if-def'd out by default. To enable them, define CPDO_ENABLE_SQLITE3 and/or CPDO_ENABLE_MYSQL5 to a true value when compiling the amalgamation or edit the header file(s) and set them to a true value (they are set at the very top of the header files).

From client code that looks a bit like:

#define CPDO_ENABLE_MYSQL5 1
#define CPDO_ENABLE_SQLITE3 1
#include "cpdo_amalgamation.h" // or .hpp

The macros can of course be passed to the compiler instead of defined in a source file. If they are not set when cpdo_amalgamation.c is compiled, there will be no drivers available. If they are not set when cpdo_amalgamation.h is included, driver-dependent function declarations (see below) will be #if'd out.

When using the amalgamation, you will need to tell cpdo about those drivers. That looks like this:

#if CPDO_ENABLE_SQLITE3
  cpdo_driver_sqlite3_register();
#endif
#if CPDO_ENABLE_MYSQL5
  cpdo_driver_mysql5_register();
#endif

Maybe someday i'll add a dynamic loader, but it's not on the immediate TODO list.

If you're using C++ code, the above can be executed as part of the initialization of a dummy variable, meaning you don't have to call those functions directly from main(). For example:

#include "cpdo_amalgamation.hpp"
namespace {
#if CPDO_ENABLE_SQLITE3
        static const int placeholder_sq3 = cpdo_driver_sqlite3_register()
#endif
#if CPDO_ENABLE_MYSQL5
        static const int placeholder_my5 = cpdo_driver_mysql5_register()
#endif

When compiling and linking, you may need to specify driver-specific compilation/linker flags. For sqlite3 the following normally suffices:

  • LDFLAGS: -lsqlite3

For mysql you can get the flags necessary by running mysql_config --libs or mysql_config --cflags.

For example:

# Compile:
~> gcc -c \
   -fPIC \
   -Wall -Werror -pedantic -ansi \
   -I. \
   -DCPDO_ENABLE_SQLITE3=1 \
   -DCPDO_ENABLE_MYSQL5=1 \
   $(mysql_config --cflags) \
   cpdo_amalgamation.c

# Create shared library:
~> g++ \
   -shared \
   -o libcpdo.so \
   $(mysql_config --libs) 
   -lsqlite3 \
   cpdo_amalgamation.o

The core code compiles fine with tcc as well (well, with some versions - some are missing stdarg.h!), but the mysql_config script assumes GCC and might emit options which tcc can't handle, so you may have to manually define the linker arguments for that compiler.

To compile with tcc:

~> tcc -fPIC -c  \
     -DCPDO_ENABLE_SQLITE3=1 -DCPDO_ENABLE_MYSQL5=1 \
     cpdo_amalgamation.c

tcc can run applications from source code directly, without intermediary linking. See the file tcc-test.c for an example.