openexr
openexr copied to clipboard
Linking against static OpenEXR 3.0.3 appears to be broken with gcc
I built OpenEXR 3.0.3 as a static library on RHEL 7 using gcc 8.x, and when attempting to link against the resultant static libraries, I get a ton of missing symbols. There are hundreds and hundreds of lines of linking errors against pretty much everything across all of OpenEXR's constituent libraries; here's a random subset:
/usr/bin/ld: libOpenEXR.a(ImfAttribute.cpp.o): in function `Imf_3_0::Attribute::newAttribute(char const*)':
ImfAttribute.cpp:(.text+0x671): undefined reference to `iex_debugTrap()'
/usr/bin/ld: ImfAttribute.cpp:(.text+0x87d): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: libOpenEXR.a(ImfAttribute.cpp.o): in function `Imf_3_0::Attribute::registerAttributeType(char const*, Imf_3_0::Attribute* (*)())':
ImfAttribute.cpp:(.text+0x93b): undefined reference to `iex_debugTrap()'
/usr/bin/ld: libOpenEXR.a(ImfAttribute.cpp.o): in function `Imf_3_0::Attribute::newAttribute(char const*) [clone .cold]':
ImfAttribute.cpp:(.text.unlikely+0x3): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfAttribute.cpp:(.text.unlikely+0xa): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfAttribute.cpp.o): in function `Imf_3_0::Attribute::registerAttributeType(char const*, Imf_3_0::Attribute* (*)()) [clone .cold]':
ImfAttribute.cpp:(.text.unlikely+0x120): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfAttribute.cpp:(.text.unlikely+0x127): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfAttribute.cpp:(.text.unlikely+0x12e): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::operator[](char const*)':
ImfHeader.cpp:(.text+0x961): undefined reference to `iex_debugTrap()'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::erase(char const*)':
ImfHeader.cpp:(.text+0xebb): undefined reference to `iex_debugTrap()'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::operator[](char const*) const':
ImfHeader.cpp:(.text+0x12e1): undefined reference to `iex_debugTrap()'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::sanityCheck(bool, bool) const':
ImfHeader.cpp:(.text+0x1c06): undefined reference to `iex_debugTrap()'
/usr/bin/ld: ImfHeader.cpp:(.text+0x1e1c): undefined reference to `iex_debugTrap()'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o):ImfHeader.cpp:(.text+0x20ae): more undefined references to `iex_debugTrap()' follow
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::(anonymous namespace)::sanityCheckDisplayWindow(int, int) [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x18): undefined reference to `Iex_3_0::ArgExc::ArgExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x1f): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x26): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `void Imf_3_0::(anonymous namespace)::checkIsNullTerminated<256ul>(char const (&) [256ul], char const*) [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0xd1): undefined reference to `Iex_3_0::InputExc::InputExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0xd8): undefined reference to `Iex_3_0::InputExc::~InputExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0xdf): undefined reference to `typeinfo for Iex_3_0::InputExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::operator[](char const*) [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x174): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x17b): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x182): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::name[abi:cxx11]() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x21c): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x223): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x22a): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::chunkCount() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x262): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x269): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x270): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::tileDescription() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x2a8): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x2af): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x2b6): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::previewImage() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x2ee): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x2f5): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x2fc): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::version() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x334): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x33b): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x342): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::type[abi:cxx11]() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x37a): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x381): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x388): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::view[abi:cxx11]() [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x3c0): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x3c7): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x3ce): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::erase(char const*) [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x402): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x409): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x410): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::operator[](char const*) const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x4a2): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x4a9): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x4b0): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::name[abi:cxx11]() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x54a): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x551): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x558): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::chunkCount() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x590): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x597): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x59e): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::tileDescription() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x5d6): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x5dd): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x5e4): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::previewImage() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x61c): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x623): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x62a): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::version() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x662): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x669): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x670): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::view[abi:cxx11]() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x6a8): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x6af): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x6b6): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::type[abi:cxx11]() const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x6ee): undefined reference to `Iex_3_0::TypeExc::TypeExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x6f5): undefined reference to `Iex_3_0::TypeExc::~TypeExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x6fc): undefined reference to `typeinfo for Iex_3_0::TypeExc'
/usr/bin/ld: libOpenEXR.a(ImfHeader.cpp.o): in function `Imf_3_0::Header::sanityCheck(bool, bool) const [clone .cold]':
ImfHeader.cpp:(.text.unlikely+0x732): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x739): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x740): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x762): undefined reference to `Iex_3_0::ArgExc::ArgExc(std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x769): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x770): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x894): undefined reference to `Iex_3_0::ArgExc::ArgExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x89b): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x8a2): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x8de): undefined reference to `Iex_3_0::ArgExc::ArgExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x8e5): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x8ec): undefined reference to `typeinfo for Iex_3_0::ArgExc'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x910): undefined reference to `Iex_3_0::ArgExc::ArgExc(char const*)'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x917): undefined reference to `Iex_3_0::ArgExc::~ArgExc()'
/usr/bin/ld: ImfHeader.cpp:(.text.unlikely+0x91e): undefined reference to `typeinfo for Iex_3_0::ArgExc'
...and so on and so forth. Basically, it seems like when linking a static libOpenEXR.a and libIex.a, the static OpenEXR library can't find symbols from Iex.
If I attempt to link against a version of OpenEXR 3.0.3 that is built as dynamic libraries, everything links just fine.
Also, if I build OpenEXR 3.0.3 as static libraries using clang on macOS 11, I can link against those just fine too.
Am I missing something here? Or are static builds somehow broken with gcc but not with clang?
I managed to hack around this problem and get a working, usable static build by adding ../Iex/IexBaseExc.cpp and ../Iex/IexThrowErrnoExc.cpp to the CMakeLists.txt sources for IlmThread. This seems to be enough to get the symbols somewhere where everything else can pick up on them, but obviously this is a complete hack of a solution and completely breaks OpenEXR's internal library boundaries.
The actual problem seems to be that for static builds of OpenEXR using gcc, symbols for Iex don't seem to be properly exposed.
Thanks for the report and investigation.
I've tried repeating this on Centos 7 with gcc 6.3 and Ubuntu 20.04 with gcc 9.3 and it links fine, no errors. Symbol visibility did just change to export only necessary symbols, so that's likely the culprit. Can you describe more about exactly how you're invoking the link that fails? Could you possibly run nm on the .a files and attach the results?
Apologies for the long delay in responding to this; I'll get the nm dump and a small example project posted by the end of the week.