Я пытаюсь запустить мою программу на C++ на других машинах Mac OSX, которые могут иметь более старую копию libstdC++, но имеют все остальные инструменты. Я попытался следовать этому approach, также упоминаемому в this SO question, хотя в нем обсуждается установка Linux. У меня есть небольшая программа try.cpp:Можно ли связать libstdC++ статически в Mac OSX 10.6?
#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++ статически
- Если г ++ не делает, это нормально использовать GCC и поставить libstdC++ вручную? Тогда почему предупреждения о видимости?
- Если ни один из двух подходов не работает из-за проблем видимости в скомпилированных библиотеках, почему бы не использовать libstdC++ файлы источника (sstream.h, list.h, vector.c) и т. Д. И просто включить их в компиляцию. Несмотря на то, что это сделает компиляцию медленной, она может быть полезна для некоторых приложений. Это может даже привести к лучшей оптимизации!
Чтобы ответить наполовину на мой собственный вопрос, можем ли мы сделать это, скомпилировав его с помощью g ++ -c сначала и связав с ld требуемые библиотеки. Здесь я не вижу никаких нарушенных правил, так как мы используем компилятор g ++ для C++, а затем связываем библиотеки, чтобы предоставить все функции. Я не знаю, какие библиотеки нам нужно предоставить ld. По-видимому, нам нужно больше, чем просто libstdC++, поскольку ld дает массу ошибок для недостающих символов. – highBandWidth