Re: statically compiling postgres and problem with initdb

From: Craig Ringer <craig(at)postnewspapers(dot)com(dot)au>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: mona attariyan <mona_attarian(at)yahoo(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: statically compiling postgres and problem with initdb
Date: 2011-07-02 03:13:09
Message-ID: 4E0E8CC5.30705@postnewspapers.com.au
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 1/07/2011 11:48 PM, Tom Lane wrote:

> It might be easier to rip out the functionality that expects loadable
> libraries to work. I think you could probably get through initdb if you
> just disabled creation of encoding-conversion functions and text search
> dictionaries (try #ifdef'ing out the relevant sections of initdb.c).

Good point. If all that's needed is basic functionality...

> Of course, you'll end up with a pretty crippled version of PG --- no
> encoding conversions, no text search, no procedural languages --- but
> maybe that's enough for what you want to do. If it's not, then as Craig
> says, you're looking at some pretty major work to bind those pieces into
> the executable statically.

I had to do something quite similar for Scribus years ago, and it wasn't
anywhere near as hard as I'd feared. It did have two really annoying
bits, though. One was having to prefix each shared library's public
symbols with the name of the shared library to avoid conflicts and allow
me to differentiate different implementations of the same public
interfaces. The second was modifying the build system to link each
library to the main executable.

This is from increasingly vague memory, but:

First I created a function pointer list entry struct type that maps
function names to function pointers.

I then modified the loader code so it prefixed the function names it was
expecting with the library name. Instead of "funcname" it'd try to
resolve "libname_funcname".

I went through EVERY SINGLE LIBRARY and prefixed the library name to the
names of every non-static function. It was ugly, but the alternative
would've been a horrid token-pasting macro hack that would've still
required changing each function declaration.

The libraries already had headers. If they hadn't, I would've had to
write a header for each library that declared prototypes for its functions.

I added a new header file to the main build that included all the
library headers and declared a global array of function pointer list
entries. In the associated .c (well, .cxx in Scribus) I defined the
array, populating it with the library-name-prefixed function names and
pointers to each function.

I modified each site where Scribus used dlopen() and dlsym() so it
called them via a wrapper. The wrapper for dynamic linking was just a
trivial header of inline wrappers around dlopen() and dlsym(). The
static linking replacement for dlopen() just returned the input library
name char* as void*, and the dlsym() replacement cast the void* back to
char*, joined the library name and function name, looked the result up
in the function pointer list, and returned the resulting function pointer.

Finally, I had to modify the build process so it produced static
libraries instead of shared libraries for each add-on, and modify the
final application linkage so it linked each library. This was made a lot
easier by the fact that Scribus used CMake instead of autotools; I don't
know what it'd be like to try to do this with autohell, but I suspect
"ugly" would be a start.

--
Craig Ringe

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Andrew Shved 2011-07-02 03:50:15 dblink and insert?
Previous Message David Johnston 2011-07-02 00:28:02 Re: Adding Foreign Key Constraint To Existing Table