Hiding the symbols of a static library in a dynamic library in MAC OS X?

Rajasekhar picture Rajasekhar · Jul 18, 2011 · Viewed 7.6k times · Source

I am using a static library (eg: boost.a) and some *.o files to create a dynamic library (Eg: libdynamic.dylib) in MAC OS X.

I am able to hide the symbols from the *.o files since I created those by -fvisibility=hidden flag. But, I can't hide the symbols from boost.a library since they have been compiled already.

Is there any way to hide the symbols (functions) of the static library, in the dynamic library ?
i.e., If I have a function (hidden) in myfuncs.o file which calls the functions(visible) in boost.a file, the boost.a functions are visible when I use "nm tool".

Please Suggest me a solution.

Answer

tahome picture tahome · Oct 16, 2011

First you need to make sure you declare all symbols that you want to keep as extern "C" attribute((visibility("default"))) and check "symbols hidden by default" in the code generation tab of your Xcode project (I think this is checked by default).

Then you need to create an exported symbols file that contains all the symbols that you want to export (keep).

You need to point Xcode to this file by adding "symbols.exp" as an "exported symbols file" entry in the Xcode project linker prefs.

Make sure that the symbols in that file start with an underscore. You can create an exported symbols file from your static lib (or the raw dylib) using the build script:

nm -g $BUILT_PRODUCTS_DIR/lib$PRODUCT_NAME.dylib | ruby -ne 'if /^[0-9a-f]+.*\s(\S+)$/.match($_) then print $1,"\n" end' > symbols.exp

You can also do this from the command line (replace $BUILT_PRODUCTS_DIR/lib$PRODUCT_NAME.dylib by the name of your library in this case).

This will create an exported symbols file "symbols.exp" in your project directory. You can then use this symbols file to strip all nonessential symbols from your dylib, like so:

strip -u -r -s symbols.exp libXYZ.dylib 

It might be a good idea to also put this at the end of the run script in your project as well, like so:

strip -u -r -s symbols.exp $BUILT_PRODUCTS_DIR/lib$PRODUCT_NAME.dylib 

If you use this script in your dylib project make sure you add the symbols.exp file to your project as well but disable it (click the checkbox next to its name), so Xcode can find the file.


Under Xcode 5 the strip command will complain as shown below, though the command appears to work correctly:

/Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.9.xctoolchain/usr/bin/strip: removing global symbols from a final linked no longer supported. Use -exported_symbols_list at link time when building: /path/to/libYourlib.dylib

As the warning states, using the -exported_symbols_list option (or Xcode's Exported Symbols File setting) allows you to precisely control which symbols will be exported by excluding anything not in the file you specify.