On Mon, Dec 05, 2011 at 04:47:08PM +0000, Richard Sandiford wrote:
> Richard Sandiford <richard.sandif...@linaro.org> writes:
> > Dave Martin <dave.mar...@linaro.org> writes:
> >> Another way of doing a similar thing is to mark __mylib_constructor
> >> as undefined in all the objects that make up the library.
> >>
> >> Unfortunately, there seems to be no obvious way of doing that: the
> >> assembler generates undefined symbol references automatically for
> >> unresolved references at assembly time.  There's no way for force
> >> the existence of an undefined symbol without an actual reference to
> >> it.
> >
> > One way of doing this is to create an R_ARM_NONE relocation
> > against it, such as:
> >
> >         .reloc   .,R_ARM_NONE,__mylib_constructor
> >
> > This isn't as hacky as it might sound, because undefined references
> > don't really make much sense without an associated reloc.
> 
> Not that I recommend this as a fix for the original problem btw. :-)
> Just FYI.

Agreed -- it's possible, but it doesn't feel like a nice solution.

> As Kito says, the easiest way of treating a static link like a shared
> one is to use --whole-archive -lfoo --no-whole-archive.  If the library

Ideally, a lot of unused code can be discarded automatically in a static
link (although this may vanish into the noise when considering that
_any_ use of stdio will typically pull in over 300K of probably mostly
dead code from libc).  --whole-archive would completely defeat this,
though the degree to which this matters depends somewhat on the size of
the library.

> is compiled with -ffunction-sections -fdata-sections, --gc-sections
> should remove the unnecessary code.

Most projects don't use those options though, and a fair number of
projects make assumptions which cause them to break if --gc-sections is
used.

Requiring people to link with a special option doesn't really solve the
problem as stated -- they could link directly with mylib_ctors.o or
-u __mylib_constructor after all.

Building a static library which "just works" with regard to running
initialisation code is possible, but there seems to be no really good
way of doing it.


Where the library has some notion of a session (where you create some
kind of heavyweight context, do something with it and then release it),
Mans' suggestion of tying the construction/destruction to this context
seems the most convenient option.  This exposes the link-time
dependencies in a way which the linker can understand correctly without
extra help, and provides a natural and convenient API to the user.

Provding you're careful to do it in a thread-safe way, you can also
tie lazy initialisation of the library (if it needs global
initialisation) to take place at the first "create context or session"
call.

Libraries which are sessionless seem less likely to need global
initialisation anyway, though it will depend on the library.

Cheers
---Dave

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to