避免 unix 中的标准库冲突
Avoiding standard library conflicts in unix
我有一个公开 C API (extern "C"
) 的共享库 (so) 对象。它不在 API 中使用 C++,也不抛出异常。它在内部确实使用 C++,尤其是 std::map
和其他容器,以及一些琐碎的模板。
我的目标是能够将这个库提供给 unix 中的任何程序(我为每个目标编译多个版本 linux 发行版),而加载程序(即一个程序,它使用 dlopen
加载我的库应该可以正常运行,即使它是用另一个版本的标准库编译的。
这是我通过阅读所做的:
- 静态链接 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
此时我的问题是:如果加载程序使用不同(major/minor/totally 不同)版本的标准库,这是否足以让我在内部使用 C++ 并避免所有冲突?如果我使用 C++14 或更新的东西并遵循上述过程怎么办?
My question at this point: will this suffice to keep me using C++ internally and avoid all conflicts if the loading program uses a different (major/minor/totally different) version of the standard library?
这就足够了。但请确认:
std::
和 nm -C --undefined-only <my.so>
中没有意外的未定义符号。
- 您的库不会使用
nm -C --defined-only --extern-only <my.so>
从 C++ 标准库中导出任何符号。以及您不希望它导出的任何符号。
readelf -d <my.so>
没有意外需要的共享库。
What if I use C++14 or something even more recent and follow the aforementioned procedure?
只要您验证您的库使用和导出的符号,此方法就应该有效。
我有一个公开 C API (extern "C"
) 的共享库 (so) 对象。它不在 API 中使用 C++,也不抛出异常。它在内部确实使用 C++,尤其是 std::map
和其他容器,以及一些琐碎的模板。
我的目标是能够将这个库提供给 unix 中的任何程序(我为每个目标编译多个版本 linux 发行版),而加载程序(即一个程序,它使用 dlopen
加载我的库应该可以正常运行,即使它是用另一个版本的标准库编译的。
这是我通过阅读所做的:
- 静态链接 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
此时我的问题是:如果加载程序使用不同(major/minor/totally 不同)版本的标准库,这是否足以让我在内部使用 C++ 并避免所有冲突?如果我使用 C++14 或更新的东西并遵循上述过程怎么办?
My question at this point: will this suffice to keep me using C++ internally and avoid all conflicts if the loading program uses a different (major/minor/totally different) version of the standard library?
这就足够了。但请确认:
std::
和nm -C --undefined-only <my.so>
中没有意外的未定义符号。- 您的库不会使用
nm -C --defined-only --extern-only <my.so>
从 C++ 标准库中导出任何符号。以及您不希望它导出的任何符号。 readelf -d <my.so>
没有意外需要的共享库。
What if I use C++14 or something even more recent and follow the aforementioned procedure?
只要您验证您的库使用和导出的符号,此方法就应该有效。