ccan icon indicating copy to clipboard operation
ccan copied to clipboard

autodata and static library ?

Open picca opened this issue 10 years ago • 3 comments

Hello, I will try to explain my problem here:

I have a library which use autodata.

hkl-factory-private.h:

struct _HklFactory { const char *name; const char *description; const darray_string axes; HklFactoryGeometryFunction create_new_geometry; HklFactoryEngineListFunction create_new_engine_list; };

define REGISTER_DIFFRACTOMETER(name_, real_name_, description_) \

static HklFactory name_ = {                 \
    .name = real_name_,                 \
    .description = description_,                \
    .axes = DARRAY(hkl_geometry_ ## name_ ## _axes),    \
    .create_new_geometry = &hkl_geometry_new_ ## name_, \
    .create_new_engine_list = &hkl_engine_list_new_ ## name_ \
};                              \
AUTODATA(factories, &name_)

AUTODATA_TYPE(factories, HklFactory);

hkl-factory.c

HklFactory **hkl_factory_get_all(size_t *n) { return autodata_get(factories, n); }

HklFactory _hkl_factory_get_by_name(const char *name, GError *_error) { size_t i, n; HklFactory **factories;

factories = autodata_get(factories, &n);
for(i=0;i<n; ++i)
    if (!strcmp(name, factories[i]->name))
        return factories[i];

return NULL;

}

and then I declare all my registered structure in a bunch of other .c files REGISTER_DIFFRACTOMETER(twoC, "TwoC", HKL_GEOMETRY_TWOC_DESCRIPTION); ...

When I compile this code as a shared library, there is no problem, I have the expected section filled with all the factories

com-sixs@sixs7:~/picca/hkl.ssh/hkl/.libs$ nm -o libhkl.so | grep xauto libhkl.so:00000000002467e0 D __start_xautodata_factories libhkl.so:0000000000246850 D __stop_xautodata_factories

but when I try to generate a static library, I got htis error message

./.libs/libhkl.a(libhkl_la-hkl-factory.o): In function hkl_factory_get_all': /home/experiences/sixs/com-sixs/picca/hkl.ssh/hkl/hkl-factory.c:29: undefined reference to__stop_xautodata_factories' /home/experiences/sixs/com-sixs/picca/hkl.ssh/hkl/hkl-factory.c:29: undefined reference to __start_xautodata_factories' ./.libs/libhkl.a(libhkl_la-hkl-factory.o): In functionhkl_factory_get_by_name': /home/experiences/sixs/com-sixs/picca/hkl.ssh/hkl/hkl-factory.c:37: undefined reference to __stop_xautodata_factories' /home/experiences/sixs/com-sixs/picca/hkl.ssh/hkl/hkl-factory.c:37: undefined reference to__start_xautodata_factories'

and indeed:

com-sixs@sixs7:~/picca/hkl.ssh/hkl/.libs$ nm -o libhkl.a | grep xauto libhkl.a:libhkl_la-hkl-factory.o: U __start_xautodata_factories libhkl.a:libhkl_la-hkl-factory.o: U __stop_xautodata_factories libhkl.a:libhkl_la-hkl-binding.o: U __start_xautodata_factories libhkl.a:libhkl_la-hkl-binding.o: U __stop_xautodata_factories

So my question is, how can I fix this ?

thanks

Frederic

picca avatar Feb 20 '15 13:02 picca

picca [email protected] writes:

Hello, I will try to explain my problem here:

I have a library which use autodata.

Ah, I see. That doesn't work: the linker won't include the xautodata section when it links against the static libraries.

I tried a few variants, but it was all fail here. I'll have to document this in autodata :(

Sorry, Rusty.

rustyrussell avatar Feb 23 '15 12:02 rustyrussell

Hello, In fact if I put all the AUTODATA(factories, &name_) in the same file it works, but tis is no more a plugging register function which allow to distribute well organize code...

Do you think that it could be possible to solve this problem by asking on the gcc mailing list ?

Cheers

picca avatar Feb 24 '15 08:02 picca

picca [email protected] writes:

Hello, In fact if I put all the AUTODATA(factories, &name_) in the same file it works, but tis is no more a plugging register function which allow to distribute well organize code...

Do you think that it could be possible to solve this problem by asking on the gcc mailing list ?

Actually, I was wrong about the problem.

The linker tries to be "smart"; it sees that you don't use any symbols in the .o within your .a, so it doesn't link it in.

For gcc (actually, the GNU linker) you can force it to include the entire library with '-Wl,-whole-archive', eg:

main: main.o libfoo.a $(LINK.o) -Wl,-whole-archive $^ -Wl,-no-whole-archive $(LOADLIBES) $(LDLIBS) -o $@

(Note that I surrounded only the library with the options to enable and disable this feature, so other libraries are effected).

Hope that helps! Rusty.

rustyrussell avatar Feb 25 '15 04:02 rustyrussell