Re: Cleaning up multiply-defined-symbol warnings on OS X

From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-patches(at)postgresql(dot)org
Subject: Re: Cleaning up multiply-defined-symbol warnings on OS X
Date: 2006-05-09 15:11:02
Message-ID: 20060509151102.GF29652@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

On Tue, May 09, 2006 at 09:18:17AM -0400, Tom Lane wrote:
> Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:
> > Eh? It stops a program expecting libpq4 being linked to libpq3 for any
> > reason, so the above situation can't happen. You don't need to version
> > any structs, only the functions using them.
>
> If we have an existing app built against an unversioned libpq, what
> happens if we roll in a versioned libpq? Does it break completely?
> That is, is the introduction of versioning by itself an incompatible
> ABI break?

This is a special rules:

- If a program (like psql) requires a symbol but specifies no symbol
version, it will match against that symbol without a version, or if not
found, the symbol with the lowest version number.

So if you slide a versioned library under a program that doesn't know
about it, it will load fine because unversioned symbols match anything.

Here is a quick example of how it works:

$ cat prog.c
extern int func();

int main()
{
return func();
}
$ cat lib.c
int func()
{
return 1;
}
$ cat ver_script
VERSION_1 { global: *; };

### Create the various versions ###
$ gcc -shared lib.c -Wl,--version-script=ver_script -Wl,-soname=liblib.so -o liblib_ver.so
$ gcc -shared lib.c -Wl,-soname=liblib.so -o liblib_nover.so
$ gcc -o prog_ver prog.c -L$PWD -llib_ver
$ gcc -o prog_nover prog.c -L$PWD -llib_nover

### Test ###
$ mkdir test
$ cp liblib_nover.so test/liblib.so
$ cp prog_nover test/prog
$ LD_LIBRARY_PATH=$PWD/test test/prog # Works (both no version)
$ cp liblib_nover.so test/liblib.so
$ cp prog_ver test/prog
$ LD_LIBRARY_PATH=$PWD/test test/prog # Doesn't work (prog with version, lib without)
test/prog: /tmp/t/test/liblib.so: no version information available (required by test/prog)
$ cp liblib_ver.so test/liblib.so
$ cp prog_ver test/prog
$ LD_LIBRARY_PATH=$PWD/test test/prog # Works (both with version)
$ cp liblib_ver.so test/liblib.so
$ cp prog_nover test/prog
$ LD_LIBRARY_PATH=$PWD/test test/prog # Works (prog without version, lib with)

You can make that broken variation work too, if the version is marked
as weak, but I couldn't quickly find out how.

http://people.redhat.com/drepper/symbol-versioning

Hope this helps,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

In response to

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2006-05-09 15:35:32 Re: Have configure complain about unknown options
Previous Message Hiroshi Saito 2006-05-09 14:46:24 Encryption of .pgpass