Discussion:
Shared library linking with external static libraries.
FloofLeBo
2010-10-12 10:24:33 UTC
Permalink
Hi,

I'm having trouble figuring out how to do the following:

I have a fairly large project of an SDK that I need to compile as a shared
library for Linux. This SDK consists of 3 static libraries (home-made) and
uses several external static libraries (freetype, FTGL, and others).

The 3 home-made sub-libraries have been compiled with -fvisibility=hidden,
so their symbols don't get exported by the shared object. This works and I
am very happy with this.

I have two questions:
- How can I tell gcc (used with "-shared") to not expose the externals
libraries's symbols, since they were compiled without -fvisibility=hidden ?
- How can I dead-strip the shared object ?

Thanks for any help.

Florent.
--
View this message in context: http://old.nabble.com/Shared-library-linking-with-external-static-libraries.-tp29941925p29941925.html
Sent from the gcc - Help mailing list archive at Nabble.com.
Pawel Sikora
2010-10-12 10:46:26 UTC
Permalink
Post by FloofLeBo
- How can I tell gcc (used with "-shared") to not expose the externals
libraries's symbols, since they were compiled without -fvisibility=hidden ?
you can instruct linker to expose/hide symbols (via global/local section)
in version script. see the 'info ld', section '3.9 VERSION Command' for ex.

BR,
Pawel.
FloofLeBo
2010-10-12 12:30:39 UTC
Permalink
Post by Pawel Sikora
Post by FloofLeBo
- How can I tell gcc (used with "-shared") to not expose the externals
libraries's symbols, since they were compiled without -fvisibility=hidden ?
you can instruct linker to expose/hide symbols (via global/local section)
in version script. see the 'info ld', section '3.9 VERSION Command' for ex.
BR,
Pawel.
I tried this command below:

/usr/bin/gcc -melf_i386 -shared -Wl,-soname,libMySdk.so.1 -o libMySdk.so
$(OBJS) -Wl,--exclude-libs,ALL $(LIBS) $(SUBLIBS)

where:
- $(OBJS) contains my SDK's objects files (*.o)
- $(LIBS) contains -L and -l statements
- $(SUBLIBS) contains the path to the home-made sub-libraries .a files

But this did not do the trick, and the symbols from $(LIBS) still get
exported in the .so shared object.

What am I missing ?

Thanks,
Florent.
--
View this message in context: http://old.nabble.com/Shared-library-linking-with-external-static-libraries.-tp29941925p29942684.html
Sent from the gcc - Help mailing list archive at Nabble.com.
Ian Lance Taylor
2010-10-12 15:06:32 UTC
Permalink
Post by FloofLeBo
Post by Pawel Sikora
Post by FloofLeBo
- How can I tell gcc (used with "-shared") to not expose the externals
libraries's symbols, since they were compiled without -fvisibility=hidden ?
you can instruct linker to expose/hide symbols (via global/local section)
in version script. see the 'info ld', section '3.9 VERSION Command' for ex.
BR,
Pawel.
/usr/bin/gcc -melf_i386 -shared -Wl,-soname,libMySdk.so.1 -o libMySdk.so
$(OBJS) -Wl,--exclude-libs,ALL $(LIBS) $(SUBLIBS)
- $(OBJS) contains my SDK's objects files (*.o)
- $(LIBS) contains -L and -l statements
- $(SUBLIBS) contains the path to the home-made sub-libraries .a files
But this did not do the trick, and the symbols from $(LIBS) still get
exported in the .so shared object.
What am I missing ?
You are missing a version script.

Ian
FloofLeBo
2010-10-12 16:37:19 UTC
Permalink
Thanks, I'm getting closer to what I want.

I've created a simple Version script:

[code]
VERSION {
{
global:
SomeRootNameSpaceClass*;
SomeOtherRootNameSpaceClass*;
SomeNameSpace::*;
SomeOtherNameSpace::*;
local:
*;
};
}
[/code]

But then, if I try to link with the produced so, i get undefined references
to methods that should be exported:

/usr/bin/gcc -o myApp $(OBJS) -L/path/to/the/SdkDir -lMySdk
someObj.o: In function `SomeClass::someMethod()':
someObj.cpp:(.text+0x367): undefined reference to
`SomeNameSpace::SomeClass::someMethod(<params>)'

And a lot of other missing symbols appear. This happens eventhough when i
execute following command:

nm -C --defined-only /path/to/the/SdkDir/libMySdk.so | grep
"SomeNameSpace::SomeClass::someMethod"

I get, the proper method, which should have been exported:

00087790 t SomeNameSpace::SomeClass::someMethod(<params>)

I bet i'm still missing something.

Thanks again,
Florent.
Post by Ian Lance Taylor
Post by FloofLeBo
Post by Pawel Sikora
Post by FloofLeBo
- How can I tell gcc (used with "-shared") to not expose the externals
libraries's symbols, since they were compiled without
-fvisibility=hidden
?
you can instruct linker to expose/hide symbols (via global/local section)
in version script. see the 'info ld', section '3.9 VERSION Command' for ex.
BR,
Pawel.
/usr/bin/gcc -melf_i386 -shared -Wl,-soname,libMySdk.so.1 -o libMySdk.so
$(OBJS) -Wl,--exclude-libs,ALL $(LIBS) $(SUBLIBS)
- $(OBJS) contains my SDK's objects files (*.o)
- $(LIBS) contains -L and -l statements
- $(SUBLIBS) contains the path to the home-made sub-libraries .a files
But this did not do the trick, and the symbols from $(LIBS) still get
exported in the .so shared object.
What am I missing ?
You are missing a version script.
Ian
--
View this message in context: http://old.nabble.com/Shared-library-linking-with-external-static-libraries.-tp29941925p29944993.html
Sent from the gcc - Help mailing list archive at Nabble.com.
Ian Lance Taylor
2010-10-12 17:00:30 UTC
Permalink
Post by FloofLeBo
Thanks, I'm getting closer to what I want.
[code]
VERSION {
{
SomeRootNameSpaceClass*;
SomeOtherRootNameSpaceClass*;
SomeNameSpace::*;
SomeOtherNameSpace::*;
*;
};
}
[/code]
But then, if I try to link with the produced so, i get undefined references
It looks like you need to use extern "C++" in your version script. Look
for extern "lang" in
http://sourceware.org/binutils/docs-2.20/ld/VERSION.html .

Ian
FloofLeBo
2010-10-12 17:30:06 UTC
Permalink
Thanks !

My application links with the shared object, and it runs with no problems !
My symbols appear in "nm -C -g --defined-only" and only the symbols I want !
Nice !

Thanks you so much ! You guys rock !

And now I'll go to the dead-stripping. How can I be sure that unused code
from the external and internal static libraries is not shipped with the
shared object ?

I tried naively to add the "-Wl,-dead-strip" to the gcc -shared command, but
this gave me the warning:

/usr/bin/ld: warning: cannot find entry symbol ad-strip; defaulting to
0000000000071f00

What would gcc need to only pull needed code for the static libs ?

Kind regards,
Florent.
Post by Ian Lance Taylor
Post by FloofLeBo
Thanks, I'm getting closer to what I want.
[code]
VERSION {
{
SomeRootNameSpaceClass*;
SomeOtherRootNameSpaceClass*;
SomeNameSpace::*;
SomeOtherNameSpace::*;
*;
};
}
[/code]
But then, if I try to link with the produced so, i get undefined references
It looks like you need to use extern "C++" in your version script. Look
for extern "lang" in
http://sourceware.org/binutils/docs-2.20/ld/VERSION.html .
Ian
--
View this message in context: http://old.nabble.com/Shared-library-linking-with-external-static-libraries.-tp29941925p29945444.html
Sent from the gcc - Help mailing list archive at Nabble.com.
Paweł Sikora
2010-10-12 17:35:27 UTC
Permalink
Post by FloofLeBo
Thanks !
My application links with the shared object, and it runs with no problems !
My symbols appear in "nm -C -g --defined-only" and only the symbols I want !
Nice !
Thanks you so much ! You guys rock !
please don't top-post ;-)
Post by FloofLeBo
And now I'll go to the dead-stripping. How can I be sure that unused code
from the external and internal static libraries is not shipped with the
shared object ?
-Wl,--gc-sections should be enough.
Ian Lance Taylor
2010-10-12 17:41:47 UTC
Permalink
Post by FloofLeBo
And now I'll go to the dead-stripping. How can I be sure that unused code
from the external and internal static libraries is not shipped with the
shared object ?
I tried naively to add the "-Wl,-dead-strip" to the gcc -shared command, but
/usr/bin/ld: warning: cannot find entry symbol ad-strip; defaulting to
0000000000071f00
What would gcc need to only pull needed code for the static libs ?
Neither the GNU linker nor gold support an option -dead-strip. That is
two options: -d, and -e ad-strip. Hence the warning. They both support
an option --gc-sections, which tells them to discard sections that are
not needed. To use that to full effect, you need to compile with
-ffunction-sections -fdata-sections. So this will look like

gcc -ffunction-sections -fdata-sections -c file.cc
gcc -o file file.o -Wl,--gc-sections

Ian
FloofLeBo
2010-10-13 10:36:34 UTC
Permalink
Post by Ian Lance Taylor
Post by FloofLeBo
And now I'll go to the dead-stripping. How can I be sure that unused code
from the external and internal static libraries is not shipped with the
shared object ?
I tried naively to add the "-Wl,-dead-strip" to the gcc -shared command, but
/usr/bin/ld: warning: cannot find entry symbol ad-strip; defaulting to
0000000000071f00
What would gcc need to only pull needed code for the static libs ?
Neither the GNU linker nor gold support an option -dead-strip. That is
two options: -d, and -e ad-strip. Hence the warning. They both support
an option --gc-sections, which tells them to discard sections that are
not needed. To use that to full effect, you need to compile with
-ffunction-sections -fdata-sections. So this will look like
gcc -ffunction-sections -fdata-sections -c file.cc
gcc -o file file.o -Wl,--gc-sections
Ian
Ok, I adapted all my projects makefiles, and recompiled my external static
libs with -ffunction-sections and -fdata-sections. The shared object did
drop from 4.3MB to 3.0MB. Nice!

Nevertheles a new problem appeared. One of the external libraries i use now
causes ld to segfault. How can I debug that ? It's one of the biggest
external libs I use, and I think I use < 20% of it ...

Again, thanks for your help & kind regards
Florent.
--
View this message in context: http://old.nabble.com/Shared-library-linking-with-external-static-libraries.-tp29941925p29951444.html
Sent from the gcc - Help mailing list archive at Nabble.com.
Ian Lance Taylor
2010-10-13 13:28:49 UTC
Permalink
Post by FloofLeBo
Nevertheles a new problem appeared. One of the external libraries i use now
causes ld to segfault. How can I debug that ? It's one of the biggest
external libs I use, and I think I use < 20% of it ...
Certainly a segfault in ld is a bug in ld. If you can provide the
object, you can report a bug at http://sourceware.org/bugzilla/ .
Otherwise your first step is going to be to run gcc -Wl,-debug
--save-temps to see precisely how ld is being run, and then run ld under
a debugger. Well, actually, the first step would be to make sure that
you are using the most recent GNU binutils release, in case the bug has
already been fixed.

Ian

Continue reading on narkive:
Loading...