-
Notifications
You must be signed in to change notification settings - Fork 617
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
Make the default symbol visibility hidden for unixen builds #868
Merged
kdt3rd
merged 23 commits into
AcademySoftwareFoundation:master
from
kdt3rd:build_exr_with_hidden_symbols
Mar 15, 2021
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7d4a7e2
This commit makes the default symbol visibility hidden for unixen builds
kdt3rd 2ffc4ac
Remove extra export tag causing warning
kdt3rd 1e23e12
Remove extra exports now that the class is exported
kdt3rd 2579b71
Fix issue with msvc when building static only
kdt3rd 2ec3a4b
Remove additional extra export tags
kdt3rd 8728b35
Remove extra exports from util flat image channel
kdt3rd eca1304
Add missing include
kdt3rd df51009
Restore individual function exports
kdt3rd 3d1ba0b
Add symbols missed in previous commit to reinstate individual exports…
kdt3rd 81fea38
add custom dynamic_cast routines for types we mix across interfaces
kdt3rd d519dfb
Simplify vague linkage export macro
kdt3rd ecd683e
strings from typeid are const char *, not std::string
kdt3rd b72161c
Add include for strcmp definition on systems where it's not pre-included
kdt3rd bb445d5
Add typeinfo include for some flavors c++ which don't include that wi…
kdt3rd e846fc5
Fix includes and test to match ImfAttribute
kdt3rd 22a6116
Clean up headers, fix symbol visibility changes
kdt3rd 7077689
Remove extraneous exports unneeded for template type
kdt3rd dbc0232
Ensure the types from Imath we are re-exporting are exported in the w…
kdt3rd 1174e22
Add some documentation to the export files, option to control
kdt3rd 879513f
Fix typo introduced during documentation / cleanup pass
kdt3rd 6cf6719
Fix flat image to use same mechanism for extern template instantiatio…
kdt3rd e94f20f
Fix indenting, clarify comment, respect option in IlmThread
kdt3rd fd1d600
refactor public / default visibility macros to top level set to simplify
kdt3rd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Symbol Visibility in OpenEXR | ||
|
||
## Overview | ||
|
||
Managing symbol visibility in a C++ library can reduce library sizes, | ||
and with the extra information, the optimizer may produce faster | ||
code. To take advantage of this, OpenEXR 3.0 is switching to | ||
explicitly manage symbols on all platforms, with a hidden-by-default | ||
behavior on unix-based platforms. Managing symbols has always been | ||
required for Windows DLLs, where one must explicitly tag functions for | ||
import and export as appropriate. | ||
|
||
For C, this is trivial: just tag public functions or global variable | ||
as default visibility and leave everything else defaulting to | ||
hidden. However, in C++, this is not exactly the same story. Functions | ||
and globals are of course the same. And class member functions are | ||
largely the same, and other than the attribute specification | ||
mechanics, follow the same rules between gcc, clang, and | ||
msvc. However, types have richer information than they do in C. So, | ||
unless extra work is done, concepts for RTTI like the typeinfo and the | ||
vtable for virtual classes will be hidden, and not visible. These are | ||
referred to as "vague" linkage objects in some discussions. | ||
|
||
It is with the "vague" linkage objects where different properties | ||
arise. For example, if you have a template, it is happily instantiated | ||
in multiple compile units. If the typeinfo is hidden for one library, | ||
then this may cause things like dynamic_cast to fail because then the | ||
same typeinfo is not used, and even though one might think that | ||
ImfAttribute<Imath::Box2i> are the same in two places, because they | ||
are instantiated in separate places, they may be considered different | ||
types. To compound the issue, there are different rules for this in | ||
different implementations. For example, a default gcc under linux | ||
allows one to link against otherwise private "vague" linkage objects | ||
such that the typeinfo ends up as the same entity. clang, for MacOS | ||
anyway, follows a stricter approach and keeps those types separate, | ||
perhaps due to the two level namespace they maintain for symbols. | ||
|
||
Unfortunately, this is not clearly discussed as an overview of the | ||
differences between platforms, hence this document to add | ||
clarity. Each compiler / platform describes their own behavior, but | ||
not how that behaves relative to | ||
others. [libc++](https://libcxx.llvm.org/docs/DesignDocs/VisibilityMacros.html) | ||
from the llvm project is the closest to providing comparitive | ||
information, where by looking at how they define their macros and the | ||
comments surrounding, one can infer the behavior among at least | ||
windows DLL mode, then gcc vs. clang for unixen. Other compilers, for | ||
example, Intel's icc, tend to adopt the behavior of the predominant | ||
compiler for that platform (i.e. msvc under windows, gcc under linux), | ||
and so can generally adopt that behavior and are ignored here. If this | ||
is not true, the ifdef rules in the various library *Export.h headers | ||
within OpenEXR may need to be adjusted, and this table updated. | ||
|
||
As a summary, below is a table of the attribute or declspec that needs | ||
to be used for a particular C++ entity to be properly exported. This | ||
does not address weak symbols, ABI versioning, and only focusing on | ||
visibility. Under Windows DLL rules, if one exports the entire class, | ||
it also exports the types for the member types as well, which is not | ||
desired, so these are marked as N/A even though the compiler does | ||
allow that to happen. | ||
|
||
|
||
| C++ vs Compiler | MSVC | mingw | gcc | clang | | ||
|-----------------|---------------------|---------------------|-----------------------|----------------------------| | ||
| function | dllexport/dllimport | dllexport/dllimport | visibility("default") | visibility("default") | | ||
| hide a function | N/A | N/A | visibility("hidden") | visibility("hidden") | | ||
| class(typeinfo) | N/A | N/A | visibility("default") | visibility("default") | | ||
| template class | N/A | N/A | visibility("default") | type_visibility("default") | | ||
| template data | N/A | N/A | visibility("default") | visibility("default") | | ||
| class template<br>instantiation | dllexport/dllimport | N/A | N/A | visibility("default") | | ||
| enum | N/A | N/A | auto unhides (N/A) | type_visibility("default") | | ||
| extern template | N/A | dllexport/dllimport | visibility("default") | visibility("default") | | ||
|
||
With this matrix in mind, we can see the maximal set of macros we need to | ||
provide throughout the code. *NB*: This does not mean that we need to | ||
declare all of these, just that they might be needed. `XXX` should be | ||
substituted for the particular library name being compiled. | ||
|
||
| macro name | purpose | | ||
|--------------------------------|------------------------------------------------------------------| | ||
| `XXX_EXPORT` | one of export or import for windows, visibility for others | | ||
| `XXX_EXPORT_TYPE` | for declaring a class / struct as public (for typeinfo / vtable) | | ||
| `XXX_HIDDEN` | used to explicitly hide, especially members of types | | ||
| `XXX_EXPORT_TEMPLATE_TYPE` | stating the template type should be visible | | ||
| `XXX_EXPORT_EXTERN_TEMPLATE` | exporting template types (i.e. extern side of extern template) | | ||
| `XXX_EXPORT_TEMPLATE_INSTANCE` | exporting specific template instantiations (in cpp code) | | ||
| `XXX_EXPORT_TEMPLATE_DATA` | exporting templated data blocks | | ||
| `XXX_EXPORT_ENUM` | exporting enum types | | ||
|
||
For a new library, the preference might be to call `XXX_EXPORT` | ||
something like `XXX_FUNC`, and rename things such as `XXX_EXPORT_TYPE` | ||
to `XXX_TYPE` for simplicity. However, historically, OpenEXR has used | ||
the `_EXPORT` tag, and so that is preserved for consistency. | ||
|
||
## References | ||
|
||
LLVM libc++ visibility macros: | ||
https://libcxx.llvm.org/docs/DesignDocs/VisibilityMacros.html | ||
|
||
GCC visibility wiki: | ||
https://gcc.gnu.org/wiki/Visibility | ||
|
||
Apple library design docs: | ||
https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
|
||
#include "drawImage.h" | ||
|
||
#include <cfloat> | ||
#include <iostream> | ||
#include <limits> | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice explanation!