在为 LINUX 创建共享库时如何避免 STL 的私有/弱副本

Posted

技术标签:

【中文标题】在为 LINUX 创建共享库时如何避免 STL 的私有/弱副本【英文标题】:how can one avoid a private/weak copy of the STL when creating a shared library for LINUX 【发布时间】:2020-07-08 14:36:50 【问题描述】:

在客户网站上有人抱怨我的产品编译时间。该产品创建 C++ 代码,并且此代码正在客户站点编译成共享库。当查看由该场景创建的空共享库时,总是包含一个 STL 代码的副本。如何通过从所有(在客户站点)生成的共享库使用的预编译共享库中导入它来避免这种情况?例如。想象下面的代码:

#include <string>
#include <map>
typedef std::map<std::string, std::string> MAP;
extern "C" const MAP *well_known_public_name(void) __attribute__((externally_visible));
const MAP *well_known_public_name(void)
       static const MAP s"1", "2";
        return &s;

我知道有两种构建方法——使用和不使用 -fwhole-program:

g++ -O3 -march=native -shared -fPIC test.cpp -std=c++11 -ffast-math -fwhole-program -DNDEBUG -funroll-loops

在这两种情况下,std::map 和 std::string 代码的副本都包含在共享库中。如何将其移至另一个共享库并避免包含在该共享库中?

【问题讨论】:

extern template? I know two ways of building this -- with and without -fwhole-program 你用 -fwhole-program 构建共享库? How can this be 您能否提供用于将源代码编译为共享库的简单编译命令以及带有将显示std::mapstd::string 符号在生成库中的命令的minimal reproducible example?跨度> @KamilCuk 除了包含的代码之外,您还需要什么来重现它?生成文件? 【参考方案1】:

这不是 LINUX 的答案。我只是想证明,这个问题可以在多年前在 Windows 上解决:

引用共享库的代码:

#include <iostream>
#include <vector>
#include <numeric>

template class __declspec(dllimport) std::allocator<int>;
template class __declspec(dllimport) std::vector<int>;
__declspec(dllimport) std::ostream &operator<<(std::ostream&, const std::vector<int>&);

int main(int argc, char**argv)
   std::vector<int> s(std::atoi(argv[1]));
    std::iota(s.begin(), s.end(), 0);
    std::cout << s << "\n";

共享库代码:

#include <vector>
#include <iostream>

template class __declspec(dllexport) std::allocator<int>;
template class __declspec(dllexport) std::vector<int>;
__declspec(dllexport)
std::ostream &operator<<(std::ostream&_rS, const std::vector<int>&_r)
   _rS << "(";
    for (const auto i : _r)
        _rS << i << ",\n";
    _rS << ")";
    return _rS;

【讨论】:

以上是关于在为 LINUX 创建共享库时如何避免 STL 的私有/弱副本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GCC Linux 中指定非默认共享库路径?运行时出现“加载共享库时出错”

在 C++ 中创建 Windows 共享库时如何实现接口隔离

Makefile 错误:找不到命令 - 创建共享库时

加载共享库时出错:在cent os上的libfontconfig.so.1

当存在同名的共享库时,如何强制链接静态库

当删库时如何避免跑路