避免 unix 中的标准库冲突
Posted
技术标签:
【中文标题】避免 unix 中的标准库冲突【英文标题】:Avoiding standard library conflicts in unix 【发布时间】:2018-06-25 15:15:27 【问题描述】:我有一个共享库 (so) 对象,它公开了一个 C API (extern "C"
)。它不在 API 中使用 C++,也不抛出异常。在内部,它确实使用了 C++,尤其是 std::map
和其他容器,以及一些琐碎的模板。
我的目标是能够将此库提供给 unix 中的任何程序(我为每个目标 linux 发行版编译多个版本),而不会与加载程序(即使用 @987654325 加载我的库的程序)存在标准库符号问题@ 应该可以正常工作,即使它是用另一个版本的标准库编译的)。
这是我通过阅读所做的:
-
静态链接 libstdc++ 和 libgcc
使用链接器脚本将所有符号标记为本地符号,但从 API 导出的 C-ABI 符号除外
linker_script.lds
global: my_api_func;
local: *;
g++ shared.cpp -Wl,--version-script=vs.lds -fPIC -static-libstdc++ -static-libgcc -shared -o libshared.so
此时我的问题是:如果加载程序使用不同(主要/次要/完全不同)版本的标准库,这是否足以让我在内部使用 C++ 并避免所有冲突?如果我使用 C++14 或更新的版本并遵循上述程序会怎样?
【问题讨论】:
我通常会看到程序在一些“$LIB”文件夹中发布它们自己的库版本,然后使用LD_PRELOAD="/usr/$LIB/libstdc++.so.6 ...."
,如steam。我想使用 docker 或 snaps 是一种方法。
@KamilCuk 这太恶心了。他们应该了解-Wl,-rpath=$ORIGIN
。
【参考方案1】:
此时我的问题是:如果加载程序使用不同(主要/次要/完全不同)版本的标准库,这是否足以让我在内部使用 C++ 并避免所有冲突?
应该够了。但一定要验证:
std::
和 nm -C --undefined-only <my.so>
中没有意外的未定义符号。
您的库不会使用nm -C --defined-only --extern-only <my.so>
从 C++ 标准库中导出任何符号。以及您不希望它导出的任何符号。
readelf -d <my.so>
没有意外的必需共享库。
如果我使用 C++14 或更新的版本并遵循上述程序会怎样?
只要您验证您的库使用和导出哪些符号,此方法就可以正常工作。
【讨论】:
以上是关于避免 unix 中的标准库冲突的主要内容,如果未能解决你的问题,请参考以下文章
python常用标准库(时间模块time和datetime)
VS2017 #error: : snprintf 的宏定义与标准库函数声明冲突