Можно ли статически связать libstdc ++ в Mac OSX 10.6? - PullRequest
4 голосов
/ 15 октября 2010

Я пытаюсь запустить свою программу 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, и мы можемоставь это в стороне.Чтобы попытаться избавиться от 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 files (sstream.h, list.h,vector.c) и т. д. и просто включите их в компиляцию.Даже если это замедлит компиляцию, это может быть полезно для некоторых приложений.Это может даже привести к лучшей оптимизации!

Ответы [ 2 ]

3 голосов
/ 15 октября 2010

Похоже, вы просто хотите использовать более ранние версии Mac OS X, что можно сделать без статической связи с libstdc++.Я думаю, что GCC, который поставляется с Xcode, по умолчанию предназначен для среды хоста.Однако он может обрабатывать специальный флаг под названием -mmacosx-version-min для изменения целевой среды.Если вы укажете номер целевой версии OS X, он автоматически создаст двоичные файлы, совместимые с этой версией Mac OS X.

#include <iostream>

int main(void)
{
    std::cout << "Hello world!" << std::endl;
    return 0;
}

Скомпилируйте так:

g++ -mmacosx-version-min=10.4 test.cpp

Я скомпилировалэту программу дважды, один раз с флагом и один раз без, а затем я скопировал оба бинарных файла на Mac с 10.4.Скомпилированный с флагом выполнен правильно, однако скомпилированный без флага сказал «Неверный тип CPU в исполняемом файле» (несмотря на то, что он был скомпилирован на идентичной машине, только что работающейболее поздняя версия OS X).

В некоторых заголовках есть макрозадержатели, которые не позволяют использовать функции / классы, представленные в 10.5 или 10.6, если вы указали 10.4 в качестве минимальной цели (я не уверен насчетЗаголовки C ++, но определенно это делают заголовки фреймворков Cocoa, Foundation, AppKit и т. Д.).

1 голос
/ 15 октября 2010

Это натяжение моего знания, но я вижу здесь несколько ответов!

GCC - это драйвер компилятора, который также управляет компоновщиком. g ++, насколько я понимаю, это больше, чем просто компилятор. Поэтому для правильной сборки G ++ я считаю, что вам нужно создавать объектные файлы и связывать их вручную. В верхней части головы я не могу сказать, как это сделать, поскольку у меня поврежден мозг IDE.

Что касается ошибки, которую вы видели, это может быть связано с неверной привязкой файлов. Я сейчас на моем iPhone, поэтому я не собираюсь разбирать напечатанное вами сообщение об ошибке. Я не фанат MacPorts, так что не удивляйтесь, что эта установка облажалась. Сначала убедитесь, что вы используете библиотеки MacPorts с компилятором MacPorts.

В конце концов, я не сомневаюсь, что вы можете делать то, что хотите. Тем не менее, вам нужно будет начать читать файлы Make и дополнительную документацию набора инструментов GCC. Сосредоточьтесь на создании и связывании файлов в программах. Возможно, вы захотите найти небольшую программу с открытым исходным кодом, которая прекрасно собирается на Mac, и посмотрите там файлы Make.

Конечно, найти хороший проект на основе C ++ для изучения нелегко. Однако я бы порекомендовал установить LLVM & CLang, особенно учитывая, что новая версия должна быть готова к C ++. Очевидно, это другой набор инструментов, но CLang может решить ваши проблемы или, по крайней мере, дать вам лучшую информацию для отладки. Может быть, кто-то может присоединиться к проекту C ++ с открытым исходным кодом с помощью простых чистых make-файлов. Наиболее близким, который я видел в последнее время, является проект под названием HeeksCAD.

В конце концов, при создании чего-то нетривиального вам в конечном итоге понадобится больше, чем просто GCC. Многое об этом сейчас решается с IDE, однако я не уверен, что XCode может быть правильно настроен на то, что вы хотите.

...