-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bundle binary footprint optimization and symbol visibility. #442
Comments
I think it would be good to reintroduce FRAMEWORK_EXPORT using new set of marcros and some documentation. For marcro, I was thinking about: //celix_export.h (part of celix_utils lib)
#define CELIX_EXPORT __attribute__((visibility ("default")))
#define CELIX_LOCAL __attribute__((visibility ("hidden"))) And applying the marcros to all C/C++ utils, dfi and framework headers. To be honest I am not sure how this needs to be applied to bundle libraries. @PengZheng Does this means that all C++ - note header only - methods needs to be declared as "CELIX_LOCAL" , with an exception for the C++ exceptions? Is an other option to let the |
Bundles are also shared libraries, so we only have to deal with shared objects. For shared library (and bundle) target, we set I think
No, these C++ headers does NOT form public API of any shared object. Users can use it to write static/shared library, executable, or whatever they want. They should take care of the symbol visibility themselves. With the help of CMake (GenerateExportHeader), it should not be burdensome. C++ ABI is notoriously hard to maintain, I'm happy we don't have it (please correct me if I were wrong). But CppMicroServices does have C++ API, and they control their class's visibility using similar approach. As for exception, since we only have C API (bundle activator) and they are nothrow by nature, any C++ exception should be catched and translated into error code before returning to the C framework. Currently we don't do it that way, a C++ exception will lead to crash.
I use version script (-Wl,--version-script=) as a last resort. It works like charm, especially when I can not modify the upstream. For example, when doing footprint optimization of OpenSSL, I use it to only export the used symbols (approximately 300) instead of 3000+. But it leads to less optimized code, see Section 2.2 of Ulrich Drepper's definitive How To Write Shared Libraries . |
@PengZheng I would like to try and tackle this. |
I will try to solve this issue in 4 steps:
|
I've implemented a C++ bundle named json_config, which depends on https://github.com/nlohmann/json and https://github.com/pboettch/json-schema-validator. It turns out that building using common settings will produce a 2.4M binary:
Further inspection reveals that a lot of C++ template instantiation unused is built into the final binary. Linking using the following linker script eliminated all these unused code from the binary, resulting in 300K binary, which is a huge win:
I noticed that the original API design took symbol visibility into account, but the new celix API did not:
celix/libs/framework/include/framework.h
Line 34 in d8b1f33
Shall we add symbol visibility control back to the whole Celix API? This is important especially for C++ bundle.
The text was updated successfully, but these errors were encountered: