避免 unix 中的标准库冲突

Avoiding standard library conflicts in unix

本文关键字:冲突 标准 unix 避免      更新时间:2023-10-16

我有一个共享库(so(对象,它公开了一个C API(extern "C"(。它不会在 API 中使用C++,也不会引发异常。在内部,它确实使用C++,尤其是std::map和其他容器,以及一些琐碎的模板。

我的目标是能够将此库提供给 unix 中的任何程序(我为每个目标 linux 发行版编译多个版本(,而不会在加载程序上出现标准库符号问题(即加载我的库的程序dlopen即使它使用另一个版本的标准库编译,也应该正常运行(。

以下是我通过阅读所做的:

  1. 静态链接libstdc++和libgcc
  2. 使用链接器脚本将所有符号标记为本地,但从 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 或更新的内容并遵循上述程序怎么办?

我在这一点上的问题:如果加载程序使用标准库的不同(主要/次要/完全不同的(版本,这是否足以让我在内部使用 C++ 并避免所有冲突?

这应该足够了。但请验证:

  1. 没有意外的未定义符号来自std::nm -C --undefined-only <my.so>.
  2. 您的库不会从带有nm -C --defined-only --extern-only <my.so>的C++标准库中导出任何符号。以及您不希望它导出的任何符号。
  3. 没有意外需要的共享库与readelf -d <my.so>.

如果我使用 C++14 或更新的内容并遵循上述程序怎么办?

只要验证库使用和导出的符号,此方法就应该有效。