Thread: Whose bug is this?

Whose bug is this?

From
Lloyd Parkes
Date:
Hi all,
I'm having a lot of trouble developing with PostgreSQL on OS X and
I've tracked it down to the way that various client libraries are
compiled and installed. I'll use the ecpg library as an example. With
PostgreSQL 8.4.5 on OS X we have the library "libecpg.6.1.dylib" and
two symbol links to it from "libecpg.6.dylib" and "libecpg.dylib".
These all live in /Library/PostgreSQL/8.4/lib. I (and most other
people I guess) link to it with a command like "gcc ... -L/Library/
PostgreSQL/8.4/lib -lecpg" and linking works fine. The linker reads
the install name from libecpg.6.1.dylib and stores it in my executable
so that it can load the correct shared library and runtime.

Unfortunately the install name in all the PostgreSQL libraries on the
Mac are unqualified names such as "libecpg.6.dylib" instead of full
pathnames like "/Library/PostgreSQL/8.4/lib/libecpg.6.dylib" meaning
that no PostgreSQL client program on OS X can possibly ever run
because the runtime linker doesn't know where the files are. That's
obviously crazy because plenty of PostgreSQL clients run fine. It gets
worse.

The programs that run fine only do so because the installer puts a
symbolic link in /usr/lib for libpq.5.dylib. Libraries in /usr/lib can
always be found and so most things work. I've double checked with
other software I have installed and their libraries always have the
full pathname recorded as their install name.

My problem is that I don't know who will want to own which bugs. The
install name can be set in the library at compile time by ld(1), or at
package install time by install_name_tool(1). In the latter case, a
compile time option must be used to reserve enough space in the
library for the correct install name to be set. The /usr/lib symlink
is a nasty hack that fails as soon as you have two different versions
of PostgreSQL installed.

Cheers,
Lloyd


Re: Whose bug is this?

From
Tom Lane
Date:
Lloyd Parkes <lloyd@must-have-coffee.gen.nz> writes:
> I'm having a lot of trouble developing with PostgreSQL on OS X and
> I've tracked it down to the way that various client libraries are
> compiled and installed. I'll use the ecpg library as an example. With
> PostgreSQL 8.4.5 on OS X we have the library "libecpg.6.1.dylib" and
> two symbol links to it from "libecpg.6.dylib" and "libecpg.dylib".
> These all live in /Library/PostgreSQL/8.4/lib. I (and most other
> people I guess) link to it with a command like "gcc ... -L/Library/
> PostgreSQL/8.4/lib -lecpg" and linking works fine. The linker reads
> the install name from libecpg.6.1.dylib and stores it in my executable
> so that it can load the correct shared library and runtime.

> Unfortunately the install name in all the PostgreSQL libraries on the
> Mac are unqualified names such as "libecpg.6.dylib" instead of full
> pathnames like "/Library/PostgreSQL/8.4/lib/libecpg.6.dylib" meaning
> that no PostgreSQL client program on OS X can possibly ever run
> because the runtime linker doesn't know where the files are. That's
> obviously crazy because plenty of PostgreSQL clients run fine.

AFAICT, the way this works on OS X is that

(1) At the time of shared library build, you specify its eventual
install location with "-install_name /full/path/and/filename".

(2) When an executable is linked against such a library, the
install_name is recorded in the executable (whether the library was
found in that location or not --- this supports linking in a build
tree).

(3) At runtime, the library had better be in the declared location.

So what the symptoms sound like is that you're trying to use libraries
that were built to be in someplace other than where they are.
"otool" might help you in figuring out their intended location.

You say that the recorded install_name is just the library name without
path --- how sure are you of that?  Because it appears to me that the
Postgres makefiles will always specify a full path when building a shlib
on Darwin.  Somebody would have had to hack up src/Makefile.shlib, or
munge the libraries after the fact, to get a path-less install_name.

> My problem is that I don't know who will want to own which bugs.

A build from the unmodified sources works fine for me on OS X.
I think the error is either yours or whoever built the PG package
you're using.

            regards, tom lane

Re: Whose bug is this?

From
Scott Ribe
Date:
On Nov 18, 2010, at 8:22 AM, Tom Lane wrote:

> AFAICT, the way this works on OS X is that
>
> (1) At the time of shared library build, you specify its eventual
> install location with "-install_name /full/path/and/filename".
>
> (2) When an executable is linked against such a library, the
> install_name is recorded in the executable (whether the library was
> found in that location or not --- this supports linking in a build
> tree).
>
> (3) At runtime, the library had better be in the declared location.
>
> So what the symptoms sound like is that you're trying to use libraries
> that were built to be in someplace other than where they are.
> "otool" might help you in figuring out their intended location.
>
> You say that the recorded install_name is just the library name without
> path --- how sure are you of that?  Because it appears to me that the
> Postgres makefiles will always specify a full path when building a shlib
> on Darwin.  Somebody would have had to hack up src/Makefile.shlib, or
> munge the libraries after the fact, to get a path-less install_name.

Basically correct. I believe it is possible to link just a file name without a path so that standard locations will
searched.It is also possible to use some notations or other like @executable/... for paths relative to an app's actual
location(to support embedding the libraries in an app bundle and avoid having to install them separately). 

Possibilities:

- Forget whatever package you used. Download the source, configure & make & install the usual way to get a normal
installation.This has the advantage that it will give you an installation that everybody here understands. It has the
disadvantagethat it will only build libraries for your particular platform, PPC or x86, 32- or 64-bit. Then you have to
gothrough some gyrations to get fat binaries. (Of course, we don't know whether or not you currently have a fat build
anyway.)

- Whether you use the current package or build from source yourself, copy the static versions of the libraries in to
yourproject somewhere, and link them in. Then you have no worries about paths for dynamic linking. (You must copy them,
becausethe linker has a strong preference for dynamic libraries. If you try to link to a static library, and it finds
thedynamic library in the path, it will use that instead. So you have to get the static libs into a path where the
dynamiclibs won't be found.) 

- Copy the dynamic libraries into your app bundle, and use name_tool (IIRC) to change the install paths to ones
relativeto the executable. 


--
Scott Ribe
scott_ribe@elevated-dev.com
http://www.elevated-dev.com/
(303) 722-0567 voice