Re: [PATCHES] symbol visibility
- From: Dan Williams <dcbw redhat com>
- To: Marcel Holtmann <marcel holtmann org>
- Cc: network manager <networkmanager-list gnome org>
- Subject: Re: [PATCHES] symbol visibility
- Date: Fri, 15 Aug 2008 16:15:13 -0400
On Fri, 2008-08-15 at 22:07 +0200, Marcel Holtmann wrote:
> Hi Dan,
>
> > > while looking through the TODO list for 0.7 [1], I decided that I should
> > > contribute a bit, especially as it was me, that complained about the
> > > long list of exported symbols by libnm-glib and libnm-util.
> > >
> > > So I went ahead and studied the docs a bit.
> > > There are basically two approaches, how to trim down the list of
> > > exported symbols:
> > >
> > > a) GCC's visibility support [2]
> > > GCC extension, mostly used by C++ libraries
> > >
> > > b) ld linker/version scripts [3]
> > > b.1) either directly via LDFLAGS -Wl,--version-script
> > > b.2) or indirectly via libtools -export-symbols $FILE or
> > > -export-symbols-regex, which will create a version script on the fly.
> > >
> > > Before trying to evaluate which approach is best, I analyzed the list of
> > > exported symbols (see attached *.symbols files) and checked which
> > > symbols are not part of the public API (see attached *.diff files).
> > >
> > > There are basically 5 ways
> > > GCC visibility
> > > 1.) Use -fvisibility=default (all symbols are exported by default) and
> > > augment all function declarations, which shall not be exported with
> > > __attribute__ ((visibility("hidden")))
> > >
> > > Does not work, as we have autogenerated files, where we cannot add the
> > > visibility attribute.
> > >
> > > 2.) Use -fvisibility=hidden (all symbols are hidden by default) and
> > > augment all function declarations, which shall be exported with
> > > __attribute__ ((visibility("default"))).
> > >
> > > Lots of code changes in the header files. To be manageable we'd have to
> > > define a macro like DLLEXPORT. All installed header files would either
> > > have to define such a macro or we would have to create a new header file
> > > (like visibility.h) which contains this macro and all other header files
> > > include that. Imho quite cumbersome
> > >
> > > libtool
> > > 3.) -export-symbols-regex:
> > > as you can see from the attached symbols and diff files, we can't use a
> > > common prefix like nm_.*. We'd have to rename private function to
> > > something like _nm_* -> looks of code changes.
> > >
> > > 4.) -export-symbols $FILE
> > > List all exported symbols in a separate file and pass it to libtool.
> > > I chatted with libtool's upstream a bit, and he recommended though, to
> > > directly use a ld version script. as this provides the most flexibility,
> > >
> > > 5.) LDFLAGS = -Wl,--version-script=$FILE
> > > That's the way I implemented it in the patch. I listed each exported
> > > symbol explicitely (although the version script syntax would allow
> > > regexes). See patch 0001 and 0002 for the details.
> > > Imho this is the nicest and cleanest approaches which requires the least
> > > changes.
> > > I generated the version scripts automatically (by using objdump and
> > > grepping for the symbols in the installed header files, dropping all
> > > symbols which are not part of the public API), so a careful review would
> > > be very appreciated.
> > > NOTE: I didn't enable symbol versioning as I didn't see the need for it
> > > yet, I only used the version script to control the list of exported symbols
> > >
> > > After applying 0001 and 0002, the test-crypto binary will no longer
> > > build, as it uses private symbols from libnm-util. I simply removed it
> > > in patch 0003. An alternative would be, to add crypto.c and
> > > crypto_(gnutls|nss).c to test_crypto_SOURCES.
> > > If someone has a need for this binary, I could change that.
> > >
> > >
> > > Comments and feedback welcome.
> >
> > I poked into visibility and talked to people who know stuff (ie Drepper)
> > and the version script option seems to be most highly recommended one
> > for a number of reasons. So feel free to commit.
>
> I ran into a similar problem with ConnMan a while ago and using libtool
> for a binary doesn't seem to work. The versioning script is really the
> best solution I could come up with. With some automake magic, I was able
> to auto-generate the version file.
>
> connmand_LDFLAGS = -Wl,--version-script=connman.ver
>
> connmand_DEPENDENCIES = connman.ver
>
> CLEANFILES = connman.ver connman.exp
>
> connman.exp:
> nm -B *.o | awk '{ print $$3 }' | sort -u | grep -E -e '^connman_' > $@
>
> connman.ver: connman.exp
> echo "{ global:" > $@
> cat $< | sed -e "s/\(.*\)/\1;/" >> $@
> echo "local: *; };" >> $@
>
> So in this case, everything with the prefix connman_ will be made
> public.
Good point. Somebody did bring up the benefit that using a version
script gives you, _at a glance_, your entire public API, which is a good
thing. Plus it would also ensure that we don't leak API by accident,
though it does mean a maintenance overhead versus your solution here.
Dan
> If the versioning script would handle regular expression by itself, then
> that would be a lot simpler actually. At least I couldn't get that to
> work.
>
> Regards
>
> Marcel
>
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]