Я пытаюсь запустить свою программу на C++ на других машинах Mac OSX, на которых может быть более старая копия libstdc++, но есть все остальные инструменты. Я попытался следовать этому подходу, также упомянутому в этот вопрос SO, хотя в нем обсуждается установка 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, и мы можем оставить это в стороне. Чтобы попытаться избавиться от libstdС++, я пытаюсь сделать это:
$ /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)
or,
$ /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++ (sstream.h, list.h, vector.c) и т. д. и просто включить их в компиляция. Несмотря на то, что это замедлит компиляцию, это может быть полезно для некоторых приложений. Это может даже привести к лучшей оптимизации!