【发布时间】:2010-10-14 20:12:51
【问题描述】:
我正在尝试在其他 Mac OSX 机器上运行我的 C++ 程序,这些机器可能具有较旧的 libstdc++ 副本,但具有所有其他工具。我试图关注这个approach,在this SO question 中也提到过,尽管它讨论了一个 linux 设置。我有小程序try.cpp:
#include <iostream>
int main() {
int a = 10;
std::cout << a << '\n';
return 1;
}
显然,如果我只是编译它,我会得到
$ /usr/bin/g++ try.cpp
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
我理解对 libSystem.B.dylib 的依赖,我们可以把它放在一边。为了尝试摆脱 libstdc++,我试试这个:
$ /usr/bin/g++ try.cpp /usr/lib/libstdc++-static.a
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
所以,我试试
$ ln /usr/lib/libstdc++-static.a .
$ /usr/bin/g++ try.cpp -L.
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
或者,
$ /usr/bin/g++ try.cpp -L. -lstdc++-static
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
终于,这行得通了:
$ /usr/bin/gcc try.cpp -L. -lstdc++-static
$ otool -L a.out
a.out:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
这样好吗? (使用 gcc 将 C++ 程序与 libstdc++ 链接)。我在某处听说 g++ 实际上是一个使用 gcc 和 libstdc++ 编译 C++ 程序的脚本。如果是这样,而且我们使用得当,应该没问题。
但是,我实际上使用的是 macport 编译器和一个更复杂的程序,gcc 会为此生成一些警告,但它是 C++ 兼容的。大意是:
ld: warning: std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf() has different visibility (hidden) in /opt/local/lib/gcc44/libstdc++.a(sstream-inst.o) and (default) in /var/folders/2u/2uLPtE+3HMi-BQIEfFVbSE+++TU/-Tmp-//ccoE2rqh.o
这表明我们不应该将 gcc 用于 c++ 编译。综上所述,问题是:
- 如何静态链接 libstdc++
- 如果 g++ 不这样做,是否可以使用 gcc 并手动提供 libstdc++?那么为什么会出现能见度警告呢?
- 如果由于编译库中的可见性问题而导致这两种方法都不起作用,为什么不使用 libstdc++ source 文件(sstream.h、list.h、vector.c)等并仅包含他们在编译。尽管这会使编译变慢,但它可能对某些应用程序很有用。它甚至可能带来更好的优化!
【问题讨论】:
-
为了回答我自己的问题,我们可以先用 g++ -c 编译它,然后用 ld 链接所需的库。我在这里看不到任何破坏规则,因为我们使用 g++ 编译器来编译 c++,然后链接库以提供所有功能。我不知道我们需要向 ld 提供哪些库。显然我们需要的不仅仅是 libstdc++,因为 ld 会因缺少符号而产生大量错误。
标签: c++ macos gcc static-linking libstdc++