This question has been asked before, but digging into the documentation for the various development tools it seems like this is possible, just not obvious.
Moti
This is really not possible, I'm sorry to say. It has to do with the way static libraries work. A static library is little more than a bunch of object *.o
files bundled together, but a dynamic library is a loadable binary image, just like an executable.
Suppose you have four files,
common
, which is "private"fn1
, which calls common
.fn2
, which calls common
.other
.In a dynamic library, the linker bundles everything up into one big chunk of code. The library exports other
, fn1
, and fn2
. You have to load the entire library or none of it, but two programs can both load it without putting multiple copies in memory. The entry point to common
is simply missing from the symbol table — you can't call it from outside the library because the linker can't find it.
Note that an application and a shared library have essentially the same format: an application is basically a shared library that only exports one symbol, main
. (This is not exactly true, but close.)
In a static library, the linker never runs. The files all get compiled into *.o files and put into a *.a library archive. Internal references will be unresolved.
Suppose your application calls fn1
. The linker sees an unresolved call to fn1
, and then looks through the libraries. It finds a definition for fn1
in fn1.o. Then the linker notices an unresolved call to common
, so it looks it up in common.o. This program won't get the code from fn2.c or other.c, because it doesn't use the definitions from those files.
Static libraries are very old, and they do not have any of the features of dynamic libraries. You can think of a static library as basically a zip file full of compiled source code, unlike a dynamic library which is linked together. Nobody ever bothered to extend the archive format to add symbol visibility. When you link with a static library, you get the same result as if you had added the library's source code to your program.
The short version: A dynamic library has one symbol table of all of the exported symbols, but none of the private symbols. In the same way, an object file has a list of all of its extern
symbols but none of the static
ones. But a static library has no symbol table, it is just an archive. So there is no mechanism to make code private to a static library (other than defining objects static
, but that doesn't work for Objective-C classes).
If we knew why you were trying to do this, perhaps we could give you a suggestion. (Is it for security? Name clashes? All of these questions have solutions.)
XCode BuildSetting can do this!
1. Set Perform Single-Object Prelink
to YES
2. Set Exported Symbols File
to path_for_symbols_file
maybe you should remove -static
, -exported_symbols_list
can not work static lib, but can take effect on object file.