我已经编写了一个相当庞大的C ++ 11库,我计划允许从我的网站下载预编译的版本。
所以我已经设置了一个自动构建,它使用clang编译库并使其可供下载,但这暴露了一个问题:如果我尝试使用GCC的clang编译库我会得到未定义的引用(主要与std::string
有关)。我认为这与GCC 5.1中的GCC双ABI变化有关,但我不确定如何解决它。
我的问题是,我应该设置哪些标志,或者我应该遵循哪些做法使C ++库与clang和GCC兼容?
或者我应该放弃并编译两个独立的库?
答案 0 :(得分:4)
正如在几个地方已经提到的那样(例如here),libc ++与libstdc ++并不是完全二进制兼容的。 有几个选项,但其中一些选项有点不那么直接。
-stdlib=libstdc++
标志的libstdc ++的clang与libstdc ++兼容(如其他答案所示)。但是,在某些平台上设置此解决方案可能更难。我建议在评论中已经提到选项1。
答案 1 :(得分:3)
有几种选择:
请勿以二进制形式分发。相反,可以轻松地在任何地方构建(例如,通过使用CMake或autotools或......)
仅限标题。这是迄今为止最简单的解决方案,但可能不是您想要的。它只对模板化代码有意义,并对库的编译时性能产生重大影响。
使用Clang和您的库时,告诉人们链接libstdc ++。次优解决方案(我喜欢检查我的代码与libc ++以及libstdc ++),但(实际上)每个Linux用户都安装了libstdc ++。确保选择稍微旧的版本(最新的Debian Stable发行版中提供的版本是一个不错的选择),因为较新的版本可能会引入新的符号缺少版本。无论如何,新版本应该与ABI兼容。
请注意,Visual Studio用户的情况更糟,每个编译器发布都需要一个新的二进制文件,因为它们对C ++库或编译器的ABI完全没有保证。
答案 2 :(得分:2)
另一个选择是您的共享库不在其接口中公开任何C ++标准库类型。并且您的共享库提供了一个头文件,可以将std::string
转换为库所使用的类型,例如struct my_string_span { char const *begin, *end; };
和其他标准容器。