[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#167604: debian-policy: provides the exception of static libraries.



>>>>> On Fri, 15 Nov 2002 13:27:49 +0100,
>>>>> "BA" == Bill Allombert <allomber@math.u-bordeaux.fr> wrote:

>> Subject: debian-policy: provides the exception of static libraries.
>> In Libraries section,
>> 
>> In general, libraries must have a shared version in the
>> library package and a static version in the development
>> package.
>> 
>> But, if libraries uses dlopen(3) internally, then some
>> programs links the static version, it doesn't work
>> correctly. because dlopen(3) doesn't try to resolve the
>> symbols in the static-linked program. in most cases, the
>> static version of such libraries is meaningless to be
>> provided.

BA> You need to link your executable binary with -export-dynamic:
BA> man ld:
BA>        -export-dynamic
BA>               When  creating  an ELF file, add all symbols to the
BA>               dynamic symbol table.  Normally, the dynamic symbol
BA>               table contains only symbols which are used by a dy­
BA>               namic object.  This option is needed for some  uses
BA>               of dlopen.

No, it doesn't help.
try this case:

---Makefile
all: libfoo.so libfoo.a module.so t-shared t-static

test: all
	LD_LIBRARY_PATH=. ./t-shared
	LD_LIBRARY_PATH=. ./t-static

libfoo.so: libfoo.c
	gcc -fPIC -c -o $@_d.o $<
	gcc -shared -Wl,-soname,$@ -o $@ $<

libfoo.a: libfoo.c
	gcc -c -o $@_s.o $<
	ar ru $@ $@_s.o

module.so: module.c libfoo.so
	gcc -shared -fPIC -Wl,-soname,$@ -o $@ -L. -lfoo $<

module_s.so: module.c libfoo.a
	gcc -shared -fPIC -Wl,-soname,$@ -o $@ $< libfoo.a

t-shared: t.c libfoo.so
	gcc -rdynamic -ldl -L. -lfoo -o $@ $<

t-static: t.c libfoo.a
	gcc -static -export-dynamic -o $@ $< -L. -lfoo -ldl

clean:
	rm -f libfoo.so libfoo.a *.o t-shared t-static module.so

---libfoo.c
#include <string.h>
#include "libfoo.h"

static char *foo_msg = NULL;
static char *bar_msg = NULL;

void foo_init (char *s)
{
	foo_msg = (char *)strdup (s);
}

char *foo_get (void)
{
	return foo_msg;
}

void bar_init (char *s)
{
	size_t len;

	if (!foo_msg) {
		printf ("foo_msg isn't initialized.\n");
		return;
	}
	len = strlen (foo_msg) + strlen (s) + 3;
	bar_msg = (char *)malloc (sizeof (char) * len);
	sprintf (bar_msg, "%s: %s", foo_msg, bar_msg);
}

char *bar_get (void)
{
	return bar_msg;
}

---libfoo.h
void foo_init (char *s);
char *foo_get (void);
void bar_init (char *s);
char *bar_get (void);

---module.c
#include "libfoo.h"

void plugin_init (char *s);
char *plugin_get (void);

void plugin_init (char *s)
{
	bar_init (s);
}

char *plugin_get (void)
{
	return bar_get ();
}

---t.c
#include <stdio.h>
#include <dlfcn.h>
#include "libfoo.h"

int main (int argc, char **argv)
{
	void *handle;
	void (*init)(char *);
	char *(*get)(void);
	char *error;
	char *msg = "test.";
	char module[256];

	foo_init (msg);
	printf ("%s\n", foo_get ());

	if (argc > 1) {
		if (strlen (argv[1]) >= 256) {
			printf ("too long\n");
			exit (1);
		}
		strcpy (module, argv[1]);
	} else {
		strcpy (module, "module.so");
	}
	handle = dlopen (module, RTLD_LAZY);
	if (handle) {
		init = dlsym (handle, "plugin_init");
		if ((error = dlerror ()) != NULL) {
			printf ("error: %s\n", error);
		}
		init (msg);
		get = dlsym (handle, "plugin_get");
		if ((error = dlerror ()) != NULL) {
			printf ("error: %s\n", error);
		}
		printf ("%s\n", get ());

		dlclose (handle);
	}
	return 0;
}

then, runs make and make test.

This is the simple codes for reproducing a problem which
GTK+ has. but I don't think this is GTK+ specific problem,
because as I said, it's actually dlopen(3) issue.

--
Akira TAGOH  : tagoh@gnome.gr.jp  / Japan GNOME Users Group
at@gclab.org : tagoh@gnome-db.org / GNOME-DB Project
             : tagoh@redhat.com   / Red Hat, Inc.
             : tagoh@debian.org   / Debian Project



Reply to: