How to apply -fvisibility option to symbols in static libraries?
Basically, visibility is handled during linking, and the linker doesn't seem impose it on static archives. A related question (though not a duplicate) was asked on SO here.
What I would advise you to do is to replace your linking stage: gcc -shared -o mylib.so foo.o libbar.a
into a two stages process where you get back the object files:
ar x libbar.a
(possibly into a suitable, empty directory)gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
Selective Static Linking Of Library Functions In Shared Library
The following points attempt to answer the questions I had posed:
- ld does not seem to allow you to omit linking in certain symbols from a static library. The usage of
--just-symbols
or--undefined
(or theEXTERN
linker script command) will not prevent ld from linking the symbols. To convert a static library, libfoobar.a, into a shared one, libfoobar.so.1.0, and exporting all visible symbols. You can also use
--version-script
and other methods to export only a subset of symbols.ld -shared -soname libfoobar.so.1 -o libfoobar.so.1.0 --whole-archive libfoobar.a --no-whole-archive
It is better to delete archive members from a copy of your static library than it is to extract them because there may be internal dependencies you have to manage. For example, assuming you are exporting all symbols, you can generate a map file from your main executable. You can then grep for all the archive members that the executable pulled in from the copy of the static library and delete them from the copy. So when your DSO is linking in the static library, it will leave the same symbols unresolved.
It is possible to specify your main executable as a shared library for your DSO if you compile the executable with the
--pie
option. Your DSO will link first to your executable if it preceded the static library in the link command. The caveat is that the main executable must be available viaLD_LIBRARY_PATH
or-rpath
. Furthermore, using strace reveals that, since the executable is a dependency of your library, it is loaded again when your DSO loads.ld -shared -rpath '$ORIGIN' -L. -lc -ldl -o DSO.so DSO.o app libfoobar.a
The dynamic linker will use the executable's version of foo first unless you call dlopen() with the
RTLD_DEEPBIND
flag. Using strace reveals that the entire DSO is file mapped mmap2() into memory. However, Wikipedia claims that for mmap "The actual reads from disk are performed in "lazy" manner, after a specific location is accessed." If this is true, then the duplicate foo will not be loaded. Note that the override only happens if your DSO exported the function foo. Otherwise, the function foo that was statically linked into your DSO will be used whenever your DSO calls foo.
In conclusion, if mmap() uses a lazy read, then the best solution is to link your DSO in the normal manner and let the dynamic linker and linux take care of the rest.
Selectively linking symbols in archive
By default, the GNU linker should pull in only the necessary object files, unless you specify the --whole_archive
flag.
If you want dead-code elimination, follow use the following linker flags:
-Wl,-static
Link against static libraries. Required for dead-code elimination.
-fvtable-gc
C++ virtual method table instrumented with garbage collection information for the linker.
-fdata-sections
Keeps data in separate data sections, so they can be discarded if unused.
-ffunction-sections
Keeps functions in separate data sections, so they can be discarded if unused.
-Wl,--gc-sections
Tell the linker to garbage collect and discard unused sections.
-s
Strip the debug information, so as to make the code as small as possible. (I presume that you'd want to do this in a dead-code
removal build.)
Source: https://gcc.gnu.org/ml/gcc-help/2003-08/msg00128.html
libraries with both .a and .so - how can I force .a to be used?
So how do I indicate that I want it to link (statically) to the .a, not dynamically to the .so?
Two ways:
- Link using the full library path
/usr/lib/libuseme.a
instead of-luseme
- Tell the linker that you want archive copy:
-Wl,-Bstatic -luseme -Wl,-Bdynamic
Difference between shared objects (.so), static libraries (.a), and DLL's (.so)?
I've always thought that DLLs and shared objects are just different terms for the same thing - Windows calls them DLLs, while on UNIX systems they're shared objects, with the general term - dynamically linked library - covering both (even the function to open a .so on UNIX is called dlopen()
after 'dynamic library').
They are indeed only linked at application startup, however your notion of verification against the header file is incorrect. The header file defines prototypes which are required in order to compile the code which uses the library, but at link time the linker looks inside the library itself to make sure the functions it needs are actually there. The linker has to find the function bodies somewhere at link time or it'll raise an error. It ALSO does that at runtime, because as you rightly point out the library itself might have changed since the program was compiled. This is why ABI stability is so important in platform libraries, as the ABI changing is what breaks existing programs compiled against older versions.
Static libraries are just bundles of object files straight out of the compiler, just like the ones that you are building yourself as part of your project's compilation, so they get pulled in and fed to the linker in exactly the same way, and unused bits are dropped in exactly the same way.
Related Topics
Are Storyboards Going to Work on iOS 4
Nsurlsession Delegates Not Called
Changing iPad/iPhone Simulator Resolution for Xcode 4.3.2
iOS Are Methods Called by Delegates and Observers Executed on the Main Thread
Send an Email from My App Without Using Mfmailcomposeviewcontroller
Obtaining Weights in Cvsvm, the Svm Implementation of Opencv
Using iOS 6 Theme for iOS 7 App
Programmatically Access Image Assets
Error Setting Text in Collection View Cell
Using Private API to Read Wifi Rssi Value
Is Char Signed or Unsigned by Default on iOS
iOS Share Gif (Animated Image) Not Working
Font Descriptor Returns Nil in iOS 8
How to Convert Cmsamplebuffer to Data in Swift
Date Formats from Device Based on Locale
Access Iphone's Built-In Ringtones
How to Show "Would Like to Send You Push Notifications" Alert View Again