openexr icon indicating copy to clipboard operation
openexr copied to clipboard

Linking against static OpenEXR 3.0.3 appears to be broken with gcc

Open betajippity opened this issue 4 years ago • 4 comments
trafficstars

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?

betajippity avatar May 21 '21 08:05 betajippity

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.

betajippity avatar May 21 '21 22:05 betajippity

Thanks for the report and investigation.

meshula avatar May 21 '21 23:05 meshula

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?

cary-ilm avatar May 22 '21 18:05 cary-ilm

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.

betajippity avatar Jun 02 '21 23:06 betajippity