top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

build libstdc++ and libgcc from source with -fPIC

+1 vote
1,027 views

I am building a shared library which will be distributed to clients in binary form only. I am attempting to make the same binary run on as many Linux variants as possible, and so when I build it I specify the
options -shared and -fPIC. As part of the effort of making the library as independent as possible, I also link both the C and C++ standard libraries statically into the final shared library. I want to do this because I use
C++11 features internally, and I don't want to force the users of my library to have a C++11 compiler handy.

When doing this, do I need to build libstdc++ and libgcc from source with -fPIC as well? Or is it okay to link with the static versions of these libraries that are provided in my Ubuntu 13.04 gcc package?

To clarify, no exceptions are thrown over library boundaries; all exceptions used internally in the library are caught and processed behind the scenes. None of them ever reach the client code, as the client communicates with the library using a plain C interface.

My exact build flags are as follows:

g++ -fvisibility=hidden -fvisibility-inlines-hidden -static-libstdc++ -static-libgcc -s -DNDEBUG -std=c++11 -Wall -shared -fPIC -o libtest.so test.cpp -lpthread -O2

posted Oct 18, 2013 by Sheetal Chauhan

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

1 Answer

+1 vote

On GNU/Linux the static versions of libstdc++ and libgcc are normally compiled with -fPIC, precisely to support the kind of thing you are doing. So it should work fine.

answer Oct 18, 2013 by Jagan Mishra
As per your suggestion, I inspected the output of readelf -r with libgcc and libstdc++. I get an enormous amount of output, but among all the entries I see things like the following for libgcc:

000015a2 00000b04 R_386_PLT32 00000000 __addtf3
00000113 00001304 R_386_PLT32 00000000 __fabstf2
0000001d 00000c04 R_386_PLT32 00000000 __fixunssfdi
... And lots of others.

For libstdc++, I see things like:
0000003e 00001904 R_386_PLT32 00000000 _ZNSi6sentryC1ERSib
00000017 00001304 R_386_PLT32 00000000 _Znwj
0000001e 00001604 R_386_PLT32 00000000 _ZN10__cxxabiv116__enu
0000011e 00005904 R_386_PLT32 00000000 _Unwind_Resume

I just chose some of these entirely at random, but I am having a hard time interpreting this output. Does it seem as though these libraries have relocation information in them? I assume yes?

Once I have compiled my shared library, is there any trivial way of verifying whether or not everything was compiled correctly for maximum independence so to speak?
1) Yes, they have relocation information. More importantly, the presence of the R_386_PLT32 relocation means that the code was compiled with -fPIC.

2) You can use readelf -rd on the shared library to see what other shared libraries and symbols your library depends on.
Similar Questions
+2 votes

I want to build a 'static toolchain', with option --disable-shared, for no shared library include/depend in the toolchain-self

cause I don't want the target binary runs depend on the toolchain, such as libc.so, ld-xxx.so.

But when the target binary need the function dlopen, it give a build error that libc.a need to recompile with -fPIC

So, how to compile glibc with -fPIC? or maybe I should ask is it possible to gen a shared library with
static toolchain?

+2 votes

I want to use the init_priority(prio) attribute
(https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes)

to initialize stuff in my library early so that users of the library can use the library during their own static objects construction. However, my library uses standard C++ library facilities like std::string,
std::vector, etc. The question is:

What is the lowest priority for init_priority attribute that I can use to still have libstdc++ initialize itself before my library is initialized?

0 votes

is it possible to add a private extension to the core language (C/C++) by writing a gcc plugin?

The extension in mind is something like this

[variable_definitions;]

Later I want this be possible also inside statement headers, for example

for ([double d = 1.0; bool f = false;] size_t i = 0; i < vec.size(); ++i)
 ...

The scope of the so-defined variables shall be the same scope they are in, ie. in the for-loop case just the scope of the for-loop itself, much like the case with i.

+1 vote

I have an oversight in my code where I'm declaring & defining a function
with C-linkage, though it's not possible.

Example snippet:

#ifdef __cplusplus
extern "C"
{
#endif

// ... some functions which are compatible with C linkage

// Intended to be a helper function not exposed from library
std::string GetEngineVersion()
{
 // ...
}

#ifdef __cplusplus
}
#endif

Obviously the GetEngineVersion function cannot have C linkage because it returns a C++ class.

My question is: does GCC have a warning for this scenario? Specifically, can it warn when something is declared extern "C" that's incompatible with C linkage?

I compile with the following warning flags and I didn't get a warning:

-Wall -Wunused-parameter -Wextra -Weffc++ -Wctor-dtor-privacy
-Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual
-Werror

Incidentally, when I compile the same code in VS2013 I get this warning:

warning C4190: 'GetEngineVersion' has C-linkage specified, but returns UDT 'std::basic_string' which is incompatible with C
0 votes

how can I configure GCC to emit the calls to __cxa_thread_atexit() for destructor registration? On a Linux PowerPC target I see the registration of destructors, but not on the powerpc-rtems target. I guess I missed a configuration option or define. Has someone a hint for me?

...