How to apply -fvisibility option to symbols in static libraries?

非 Y 不嫁゛ 提交于 2019-11-26 15:11:10
F'x

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

Simply pass -Wl,--exclude-libs,ALL to gcc

This will tell the linker to transform all the symbols in the static libraries to hidden.

--exclude-libs also accepts a list of archives (i.e. static library names) for finer granularity on which libraries to hide symbols from.

Note: this will only work in systems using GNU binutils (e.g. Linux) or with a linker supporting --exclude-libs (e.g. it won't work with OSX's ld64)

This is an answer to the problem for OS X.

The Mac ld doesn't support --exclude-libs, but it does support -exported_symbol sym and it does apply this to object files in static libraries. And when you're filtering to a public API, the whitelist is small enough to spell it out.

I ended up with the following in my Makefile to generate a -Wl,-exported_symbol,_api_func_1 flag for each exported symbol:

SYMBOLS   = api_func_1 api_func_2 api_func_3 api_func_4
SYMBOLS   += api_func_5 # add more as necessary
COMMA     = ,
LDFLAGS   += $(addprefix -Wl$(COMMA)-exported_symbol$(COMMA)_,$(SYMBOLS))

# ...

libmyapi.so: # ...
    $(CC) -shared -o $@ ... $(LDFLAGS)

Then you can if-gate between this version of the flags and the GNU ld version after detecting which linker the system has.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!