Thread: PG Extensions: Must be statically linked?

PG Extensions: Must be statically linked?

From
"Craig A. James"
Date:
I'm creating user-defined server extensions, written in C per the manual "31.9. C-Language Functions".  Everything
workswell, but only if I fully link the .so such that there are *no* unresolved external references at all.  Not even
thestuff in libstdc++.a can be left out.  I've tried setting LD_LIBRARY_PATH everywhere possible, with no luck.  Here's
themake(1) line I have to use to link:
 

libmyfuncs.so.0.0:gcc -Wall -Wmissing-prototypes -Wpointer-arith \  -Wdeclaration-after-statement
-Wold-style-definition-Wendif-labels \  -fno-strict-aliasing -fpic -shared -Wl,-soname,libmyfuncs.so.0  \  $(OBJS) \
$(MYLIB)/lib/libmylibs.a\  /usr/lib/gcc/i386-redhat-linux/3.4.2/libstdc++.a \  -o libmyfuncs.so.0.0
 

Is this correct?  Do Postgres extension need to be fully statically linked?  Or is there some configuration that will
specifyLD_LIBRARY_PATH (or perhaps a Postgres-specific equivalent).
 

The manual's instructions are good regarding writing code, but don't say much about linking.

Thanks,
Craig


Re: PG Extensions: Must be statically linked?

From
Peter Eisentraut
Date:
Craig A. James wrote:
> I'm creating user-defined server extensions, written in C per the
> manual "31.9. C-Language Functions".  Everything works well, but only
> if I fully link the .so such that there are *no* unresolved external
> references at all.

What happens if you don't?

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/


Re: PG Extensions: Must be statically linked?

From
Tom Lane
Date:
"Craig A. James" <cjames@modgraph-usa.com> writes:
> I'm creating user-defined server extensions, written in C per the
> manual "31.9. C-Language Functions".  Everything works well, but only
> if I fully link the .so such that there are *no* unresolved external
> references at all.  Not even the stuff in libstdc++.a can be left out.

If you're using libstdc++.a, you are not writing C.  There is no support
for C++ in the backend, and I would strongly advise not trying to use
it, as any of C++'s moderately interesting features like exceptions will
not play nicely with the backend environment.
        regards, tom lane


Re: PG Extensions: Must be statically linked?

From
"Craig A. James"
Date:
Tom Lane wrote:
>>I'm creating user-defined server extensions, written in C per the
>>manual "31.9. C-Language Functions".  Everything works well, but only
>>if I fully link the .so such that there are *no* unresolved external
>>references at all.  Not even the stuff in libstdc++.a can be left out.
> 
> If you're using libstdc++.a, you are not writing C.  There is no support
> for C++ in the backend, and I would strongly advise not trying to use
> it, as any of C++'s moderately interesting features like exceptions will
> not play nicely with the backend environment.

Unfortunately, we're also using a second library (OpenBabel) that is written in C++.  A good portion of the code I've
writtenis a wrapper layer that hides the C++ objects and presents a simple C wrapper that works for Postgres.
 

Craig


Re: PG Extensions: Must be statically linked?

From
Peter Eisentraut
Date:
Craig A. James wrote:
> Unfortunately, we're also using a second library (OpenBabel) that is
> written in C++.  A good portion of the code I've written is a wrapper
> layer that hides the C++ objects and presents a simple C wrapper that
> works for Postgres.

I suggest if you want to get any concrete advice out of this, post us 
the commands that you execute and the error messages that you get.

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/


Re: PG Extensions: Must be statically linked?

From
John Gray
Date:
On Thu, 02 Mar 2006 13:43:35 -0800, Craig A. James wrote:

> I'm creating user-defined server extensions, written in C per the manual

[snip]
> Is this correct?  Do Postgres extension need to be fully statically
> linked?  Or is there some configuration that will specify LD_LIBRARY_PATH
> (or perhaps a Postgres-specific equivalent).
> 

Not generally, unless your platform requires it because of restrictive
dynamic loader behaviour. contrib/xml2 uses two external libraries
(libxml and libxslt) - they are dynamically referenced by the resulting
pgxml.so. Have a look at the Makefile for contrib/xml2 for hints on
options?


> The manual's instructions are good regarding writing code, but don't say
> much about linking.
> 

True - but I think the assumption has been that most
people wouldn't have any involved linking requirements. Your case doesn't
come into this category, but there are useful cases for linking to
external function libraries and exposing them to PG. 

Regards

John



Re: PG Extensions: Must be statically linked?

From
"Craig A. James"
Date:
Peter Eisentraut wrote:
>>Unfortunately, we're also using a second library (OpenBabel) that is
>>written in C++.  A good portion of the code I've written is a wrapper
>>layer that hides the C++ objects and presents a simple C wrapper that
>>works for Postgres.
> 
> I suggest if you want to get any concrete advice out of this, post us 
> the commands that you execute and the error messages that you get.

Thanks for your answers -- see below.

Based on Peter's and Tom's replies regarding C++, I think you've answered my question: I should be able to do this
withoutstatic linking.  But the Postgres linker uses the C (not the C++) linker to resolve references, so it's not
findingthe C++ libraries.
 

My original question was misleading.  I said, "I have to link everything statically...", when in fact what should have
saidwas, "If I link statically, it works."  I now realize that I'm not linking everything statically, just the
OpenBableand C++ libraries, and in fact Postgres is finding the other libraries I need, like libz, libm, and so forth.
 

Here's what happens when I don't statically link the C++ libraries or the OpenBabel libraries:

[root]# cp libmyfuncs.so /usr/local/pgsql/lib

$ psql -d myfuncs -U postgres
Welcome to psql 8.0.3, the PostgreSQL interactive terminal.
...
myfuncs=# CREATE FUNCTION myfunc(text, text) RETURNS boolean
myfuncs-# AS '/usr/local/pgsql/lib/libmyfuncs.so', 'myfunc'
myfuncs-# LANGUAGE 'C' STRICT;
ERROR:  could not load library "/usr/local/pgsql/lib/libmyfuncs.so": /usr/local/pgsql/lib/libmyfuncs.so: undefined
symbol:_ZdlPv
 

That symbol is obviously a C++ mangled name, so it's not finding the C++ library, and the fact that it prints the
mangledname suggests that it's a C linker, not a C++ linker.
 

So now my question is: Can I somehow add other directories/libraries to those that Postgres uses?  Or is there an
optionfor Postgres use the C++ dynamic linker?  I don't mind statically linking OpenBabel, but it seems like a bad idea
toput the specific version- and system-dependent location of libstdc++.a into my makefiles.
 

(Am I the only guy in the world who has to use a C++ library as part of a Postgres function?)

Thanks,
Craig




Re: PG Extensions: Must be statically linked?

From
Martijn van Oosterhout
Date:
On Fri, Mar 03, 2006 at 07:46:06AM -0800, Craig A. James wrote:
> Thanks for your answers -- see below.
>
> Based on Peter's and Tom's replies regarding C++, I think you've answered
> my question: I should be able to do this without static linking.  But the
> Postgres linker uses the C (not the C++) linker to resolve references, so
> it's not finding the C++ libraries.

<snip>

> So now my question is: Can I somehow add other directories/libraries to
> those that Postgres uses?  Or is there an option for Postgres use the C++
> dynamic linker?  I don't mind statically linking OpenBabel, but it seems
> like a bad idea to put the specific version- and system-dependent location
> of libstdc++.a into my makefiles.

There are a number of ways to indicate which extra libraries to load,
but by far the easiest is by specifying them on the link line.

Your problem is that when creating a shared library, you are not
required to make sure all your external symbols are defined somewhere.
You didn't post your compile/link line but if you're using C++ you
probably need to use g++ for the linking to include the special C++
libraries.

One way to find out what's going on is using readelf:

$ readelf -a /bin/bash |grep NEEDED0x00000001 (NEEDED)                     Shared library: [libncurses.so.5]0x00000001
(NEEDED)                    Shared library: [libdl.so.2]0x00000001 (NEEDED)                     Shared library:
[libc.so.6]

These are the libraries that will be loaded when someone tries to load
your shared lib (the above works on any ELF object). The easiest is to
specify "--no-undefined" on the link line so the linker checks up front
you won't get undefined symbols at run time. Remember it's
-Wl,--no-undefined if invoking from gcc/g++.

Hope this helps,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Re: PG Extensions: Must be statically linked?

From
Tom Lane
Date:
"Craig A. James" <cjames@modgraph-usa.com> writes:
> So now my question is: Can I somehow add other directories/libraries
> to those that Postgres uses?

This is not a Postgres problem, it's a dynamic-linker problem, and
I don't believe there is a different dynamic linker for C++ than C.
Your problem is just to get your shared library marked as needing
libstdc++.so.  (ldd on the .so should show what shared libraries it
needs.)  On Linux this should all happen pretty much automatically,
at least for libraries that are in the ldconfig search path.  I'm
not sure what is going wrong, but you could take a look at
contrib/dblink, which dynamically includes libpq.so (and the backend
certainly does not load libpq.so by default).  If that works on your
machine then try to figure out what dblink's Makefile does differently
from yours.

My concern about how nicely libstdc++ will play in the backend
environment still stands though.
        regards, tom lane


Re: PG Extensions: Must be statically linked?

From
Mark Dilger
Date:
Tom Lane wrote:
> My concern about how nicely libstdc++ will play in the backend
> environment still stands though.

I have had the same concern, though never any hard evidence of a problem.  If 
the C++ functions are wrapped with "extern C", and all exceptions caught 
(perhaps converted into error numbers which are then returned from the wrapper 
functions to the plain-C calling functions), are there any remaining known 
problems?  I have often considered making a C++ allocator which wrapped palloc 
and pfree, so that I could then use the STL within the backend...

Has anyone tried this?

mark


Re: PG Extensions: Must be statically linked?

From
Andreas Seltenreich
Date:
Mark Dilger writes:

> I have had the same concern, though never any hard evidence of a
> problem.  If the C++ functions are wrapped with "extern C", and all
> exceptions caught (perhaps converted into error numbers which are then
> returned from the wrapper functions to the plain-C calling functions),
> are there any remaining known problems?  I have often considered
> making a C++ allocator which wrapped palloc and pfree, so that I could
> then use the STL within the backend...
>
> Has anyone tried this?

I did some experiments on a C++ language handler last year (including
an allocator and a class loader to spare the extern "C"s/name
mangling):

<http://archives.postgresql.org/pgsql-general/2005-10/msg01570.php>
<news:87acgxjzsl.fsf@gate450.dyndns.org>

The remaining issue is the impedance mismatch between longjmp()ing and
exceptions.

regards,
Andreas
--