If you're building shared objects to be used with Android, you'll probably want to be careful about what exactly is the API that you're making available.
There are a few gotchas along the way that I'll be covering here.
While there are ways of annotating your source directly, I usually find this rather messy. The APIs exposed form a proper contract, and it's good to be clear and explicit about that.
The Visual C++ linker supports .def files, while define various properties of a module (a DLL for our purposes). The EXPORTS directive gives you a way to list all the functions that you want exported. You then simply provide the .def file to the linker with something like /DEF:mydll.def
and off you go.
For example, it might look something like this:
EXPORTS
my_fun_1
my_fun_2
The ld linker, on the other hand, doesn't support .def files, but you can get some measure of control with version scripts.
You can then feed a text file such as the following one to the linker, with something like -Wl,--version-script=my-exports.txt
and you should then see the right symbols exposed.
CODEABI_1.0 {
global:
my_fun_1;
my_fun_2;
with_prefix_matching_*;
local:
*;
};
Note that the way the shared object is put together is quite different from the way DLLs are built on Windows.
On Windows, you'll typically have a number of exports (including things like DllMain). The linker can then do reachability analysis for those, and include all the code it needs, and discard all the code it doesn't need.
When building shared objects, however, the model is different. Instead, the linker will including all of the object files referenced, but not any static libraries.
Which means that you might very well find yourself with a mostly empty binary if you just refer to a static library they way you might on Windows. Note that even if you use the linker script, the tools won't complain if the APIs are not available.
If you run into this while building a cmake-based project, read on for some tips.
CMake has two ways of building libraries of code with static linking.
STATIC
, these are your classic .a
or .lib
files that include a number of object files all put together.If you use normal libraries and get the "empty shared object" effect, you might want to start by switching to an object library.
There are a few more interesting kinds of "libraries" you can define in CMake: imported libraries (usually .so on non-Windows, the import lib on Windows), interface (settings only, no code), and alias. In general, understanding these will give you more options to better organize your project.
Happy exports!