cpdo  Artifact Content

Artifact 71c5d92bf4a0cae59ab0ec444c800412a0d96b83:

Wiki page [AmalgamationBuild] by stephan 2011-05-17 18:39:27.
D 2011-05-17T18:39:27.364
L AmalgamationBuild
P f5aad0ea2b0c707293b7386b767714c80ec8cd11
U stephan
W 3636
<strong>ACHTUNG: THE CPDO WIKI IS NOW (AS OF 2011-May-17) MAINTAINED ON A DEDICATED WIKI SITE:</strong> [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:

<verbatim>
~> make amal
</verbatim>

That creates the following files:

   *  C mode: <tt><nowiki>cpdo_amalgamation.[ch]</nowiki></tt>
   *  C++ mode: <tt><nowiki>cpdo_amalgamation.[ch]pp</nowiki></tt>. These include the C library and the [cpdopp|C++ wrapper].

They include the driver-specific parts, but they are if-def'd out by
default. To enable them, define <tt>CPDO_ENABLE_SQLITE3</tt> and/or 
<tt>CPDO_ENABLE_MYSQL5</tt> 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:

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

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

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

<verbatim>
#if CPDO_ENABLE_SQLITE3
  cpdo_driver_sqlite3_register();
#endif
#if CPDO_ENABLE_MYSQL5
  cpdo_driver_mysql5_register();
#endif
</verbatim>

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 <tt>main()</tt>. For example:

<verbatim>
#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
</verbatim>

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

   *  LDFLAGS: <tt>-lsqlite3</tt>

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

For example:

<verbatim>
# 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
</verbatim>

The core code compiles fine with [http://bellard.org/tcc/|tcc] as well (well, with some versions - some are missing <tt>stdarg.h</tt>!), but the <tt>mysql_config</tt> 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:

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

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

Z df2d74b1f7086aa424d2ee92ade76466