3

Decided to try LTO in my build (CentOS 7, CMake 3.14.3, gcc 8.2.1, -std=c++17):

# this adds "-flto -fno-fat-lto-objects"
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)

All projects build fine, with exception of one:

/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(operation_context.cpp.o): In function `_GLOBAL__sub_I_operation_context.cpp':
operation_context.cpp:(.text.startup+0x9c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(cloud_block_blob.cpp.o): In function `_GLOBAL__sub_I_cloud_block_blob.cpp':
cloud_block_blob.cpp:(.text.startup+0x9c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(cloud_blob_container.cpp.o): In function `_GLOBAL__sub_I_cloud_blob_container.cpp':
cloud_blob_container.cpp:(.text.startup+0x9c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(cloud_blob_shared.cpp.o): In function `_GLOBAL__sub_I_cloud_blob_shared.cpp':
cloud_blob_shared.cpp:(.text.startup+0x9c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(cloud_blob_ostreambuf.cpp.o): In function `_GLOBAL__sub_I_cloud_blob_ostreambuf.cpp':
cloud_blob_ostreambuf.cpp:(.text.startup+0x9c): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/home/user/vcpkg/installed/x64-linux/lib/libazurestorage.a(cloud_blob_client.cpp.o):cloud_blob_client.cpp:(.text.startup+0x9c): more undefined references to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' follow
collect2: error: ld returned 1 exit status

For some mysterious reason libazurestorage.a provided by vcpkg (where it is built without LTO) can't resolve std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (and only that symbol!).

To make it even more interesting -- other projects that use libazurestorage.a build just fine. I've checked linker's cmdline -- they look practically identical (almost same set of libs, almost same order).

Any ideas what could be wrong? Or how to figure out why other projects build fine?

C.M.
  • 2,353
  • 1
  • 11
  • 25
  • Just guessing, but I would bet that destructor is inline. Your LTO code probably doesn't produce a non-inline copy of it since it does the code generation all in one step, while regular compilation will actually produce one copy per file and use the linker to remove all unused copies. – Zan Lynx Jul 19 '19 at 18:49
  • I don't know if it will help but you could try adding an explicit instantiation of `std::basic_string` to one of your cpp files. – Zan Lynx Jul 19 '19 at 18:53
  • @ZanLynx So, you're saying other projects are just lucky to generate non-inlined `std::basic_string::~basic_string()`? I am skeptical... Also, aren't this symbol is supposed to be taken from std library? (unless `libazurestorage.a` observed wrong `std::basic_string` -- i.e. I have some sort of ODR violation) – C.M. Jul 19 '19 at 20:35
  • The C++ standard library does not provide out of line implementations of its inline functions. Obviously, or there'd be one defined for your project. – Zan Lynx Jul 19 '19 at 23:11
  • @ZanLynx It is quite weird... This project is the largest one. If anything, I would expected others to not generate `~basic_string()`. – C.M. Jul 21 '19 at 03:34
  • Another thing that might be going on is LTO setting all the symbols to "hidden." Which is a thing it does, because symbols that aren't exported are free to be mangled, inlined, and removed entirely. You might try linking a file that uses `std::string` without compiling it with LTO. – Zan Lynx Jul 21 '19 at 06:45
  • Or using GCC's `externally_visible` attribute. – Zan Lynx Jul 21 '19 at 06:46
  • @ZanLynx Thanks, I'll give it a try. It occurred to me that `libazurestorage.a` is the only one having problems (and there is a bunch of others being linked that use `std::string` (e.g. aws cpp sdk) -- I bet it is smth to do with how `vcpkg` builds this particular lib. – C.M. Jul 22 '19 at 14:24

0 Answers0