【发布时间】:2014-05-24 02:17:35
【问题描述】:
我有一个关于将一个库嵌入另一个库的问题。
我有一个纯 C 代码,我的用户依赖它,他们不想依赖 C++ 库。但是,需要将第 3 方库 (ICU) 嵌入到我的库中。不会导出任何 ICU 功能,它们只会在我的库内部使用。不幸的是,ICU 是一个 C++ 库,尽管它确实有一个 C 包装器。 ICU 不使用异常,但确实使用 RTTI(抽象基类)。
问题是如何创建我的静态库,以便
- ICU 嵌入在我的库中(所有对 ICU 函数的引用都在我的库中解析)
- 所有对 libstdc++ 的引用也已解决,必要的代码已嵌入到我的库中
- 如果用户甚至没有在他们的系统上安装 libstdc++,则一切正常
- 如果用户碰巧在 C++ 项目中使用了我的库,那么与他使用的任何 libstdc++(可能是系统 libstdc++)都不会发生冲突。
这可能吗?目标平台几乎是一切:windows(我的库是动态的)和各种 unix 版本(linux、solaris、aix、hpux - 我的库需要是静态的)。
gcc-4.5 及更高版本确实有 --static-libstdc++,但据我了解,它仅用于创建共享库或可执行文件,而不是静态库。
感谢您的帮助!
【问题讨论】:
-
这可能是不可能的.. 至少在“我的经验”中。使用特定版本的 libstdc++ 编译的库似乎并不总是与另一个版本兼容。通常会给出链接器错误。即使对于 Visual Studio。我注意到像 OpenCV 这样的库提供了不同的版本。 VC10、VC11、VC12 等(我昨晚构建的).. 我以前做的是将所有内容编译成它们的 .o 文件。然后运行
ar -rcs *.oo 文件将是所有依赖项,如 zlib、libpng 等。但不要认为你可以摆脱 libstd ......我也很想回答这个问题。 -
dlopen+dlsym 可能是在不创建编译时依赖项的情况下从 C 中使用 ICU 的方式。
-
@ArtemGr :这很好,除了一件事:我需要分发 icu 库,因为我不能假设用户拥有它。但是,当然,我需要编译它。并且(假设我在 linux 上)我在构建机器上的编译器的 C++ ABI 可能与用户在他的机器上的 C++ ABI 不兼容(例如,对于 RTTI 分辨率)。因此,如果我对已分发的 icu 库进行 dlopen+dlsym,则在开始运行时可能会遇到问题。这就是为什么我想以这种方式解决和绑定所有内容并创建我的库。
-
在 UNIX 相关操作系统上正确的做法是安装系统 ICU。如果你绝对不能这样做,那么人迹罕至的路径是从源代码构建 ICU(构建指令的一个示例:ceph.com/docs/master/install/build-ceph),但这是错误的路径,除非你想要您的用户可以使用未来的安全补丁手动升级 ICU。
-
我并不是说使用系统范围的 ICU 安装不是最好的。我是说这对我来说不是一个选项:-(。鉴于这不是一个选项,我想让我的用户免于任何可能的 C++ ABI 冲突。
标签: c++ c linker static-linking