【发布时间】:2021-07-02 17:31:12
【问题描述】:
我有一个库,我在 Ubuntu 18.04 上使用捆绑在 build-essential 包中的 gcc 版本编译,gcc 7.5.0。
如果我尝试在 Ubuntu 20.04 上编译应用程序并链接到我之前使用默认 gcc 版本 gcc 9.3.0 构建的那个库,那么我会收到一堆错误,例如对 __expf_finite 的未定义引用。请注意,我确实使用 -Ofast 编译了我的原始库,因为我需要利用所有优化。根据this SO question,它表明libc 更新不再支持math-finite.h。
因此,作为一种可能的解决方案,我尝试使用 gcc 9.3.0 在 Ubuntu 20.04 上编译我的库,然后查看是否可以使用在 Ubuntu 18.04 上使用 gcc 7.5.0 编译的应用程序链接到该库(基本上与第一种情况)。
但是,当我这样做时,我会收到 std::string 的 ABI 兼容错误:
./trueface_sdk/libtf.a(ocl.cpp.o): In function `cv::ocl::Kernel::set(int, cv::ocl::KernelArg const&)':
ocl.cpp:(.text._ZN2cv3ocl6Kernel3setEiRKNS0_9KernelArgE+0x375): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text._ZN2cv3ocl6Kernel3setEiRKNS0_9KernelArgE+0x49d): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../trueface_sdk/libtf.a(ocl.cpp.o): In function `oclCleanupCallback.cold':
ocl.cpp:(.text.unlikely.oclCleanupCallback+0x36): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text.unlikely.oclCleanupCallback+0xcf): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
ocl.cpp:(.text.unlikely.oclCleanupCallback+0x184): undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()'
../trueface_sdk/libtf.a(ocl.cpp.o):ocl.cpp:(.text._ZN2cv3ocl6Device4ImplC2EPv[_ZN2cv3ocl6Device4ImplC5EPv]+0xb7b): more undefined references to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()' follow
../trueface_sdk/libtf.a(sqlite3.c.o):(.data.rel+0xb0): undefined reference to `fcntl64'
我还得到了对 fcntl64 的未定义引用。
那么解决方法是什么?如何编译兼容多个版本 gcc 的库?
【问题讨论】:
-
问题不在于
-Ofast本身,这对于从 4.6 开始的所有 gcc/g++ 版本都很常见。由于库和版本差异,您通常会遇到 soname 问题(库版本要求)。将所有内容粘合在一起的方式会有微小的变化,因为缺少更好的词,并且确保库兼容性可能很棘手,尤其是当您告诉编译器尽可能地优化时,即使这违反了一些标准合规性.将优化返回到-O2,看看是否会出现同样的问题。 (运行时差异可以忽略不计) -
罪魁祸首可能是构建环境之间的 glibc 差异。检查每个 glibc 的版本。那里的不匹配可能会导致您描述的问题。
标签: c++ gcc compatibility