Ошибка компоновщика OpenSceneGraph на Mac с Macports

У меня возникла проблема с правильной компоновкой проекта OpenSceneGraph на моем Mac. Я установил его через macports, и я заставил osgviewer и другие программы osg работать, то есть он был каким-то образом скомпилирован и связан. Код является частью более крупного проекта, однако я отделил код OSG до голых костей, чтобы изолировать свои проблемы. Сначала я подумал, что это проблема CMake, поэтому я создал Makefile, чтобы попытаться изолировать его. Это не имело значения.

Вот пример кода.

// OpenSceneGraph Libraries
#include <osg/Geode>
#include <osg/Group>
#include <osg/ShapeDrawable>
#include <osgUtil/Optimizer>
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/Simplifier>
#include <osg/Node>
#include <osg/Texture1D>
#include <osg/Texture2D>
#include <osg/TexGen>
#include <osg/Material>
#include <osgViewer/Viewer>
#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osgDB/ReadFile>
#include <osgSim/Version>
#include <osgFX/Version>
#include <osgTerrain/Version>
#include <osgVolume/Version>



// C++ Libraries 
#include <iostream>
#include <string>


/**
 * @brief Main Application
*/
int main( int argc, char* argv[] )
{

    // Define Write Options
    osgDB::Options* write_options = new osgDB::Options("WriteImageHint=IncludeData Compressor=zlib");

    // Create the Root Nodes
    osg::ref_ptr<osg::Group> root_node(new osg::Group());



    // Write the Node File
    osgDB::writeNodeFile( *root_node.get(),
                           "output.osgb",
                           write_options );

    // Return
    return 0;
}

Вот код Makefile. Я добавил намного больше, чем нужно, но безрезультатно.

OSG_LIBS=-lOpenThreads -losgDB -losg -losgUtil -losgTerrain

LIBS=-L/opt/local/lib $(OSG_LIBS)
INCL=-I/opt/local/include

CPP=clang++

foo: foo.cpp
    $(CPP) foo.cpp $(LIBS) $(INCL)

Вот вывод make с VERBOSE=1 для конкретной команды.

$ make VERBOSE=1
clang++ foo.cpp -L/opt/local/lib -lOpenThreads -losgDB -losg -losgUtil -losgTerrain -I/opt/local/include
Undefined symbols for architecture x86_64:
  "osgDB::writeNodeFile(osg::Node const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, osgDB::Options const*)", referenced from:
  _main in foo-2c45f6.o
  "osgDB::Options::parsePluginStringData(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char, char)", referenced from:
  osgDB::Options::Options(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in foo-2c45f6.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [foo] Error 1

Я запустил otool и другие приложения для общих библиотек, чтобы попытаться найти, где находится неопределенная ссылка. Я знаю, что когда я запускаю nm, символ для обоих этих методов находится в libosgDB.dylib, но связывание не работает.

Я начинаю компилировать OpenSceneGraph из исходного кода, но это также создает ошибки компиляции. Мне предстоит долгая борьба. Заранее большое спасибо за ваше время.

Обновлять:

Наблюдения

  • Переупорядочивание библиотек в строке компилятора не работает.

person msmith81886    schedule 27.11.2015    source источник
comment
Ошибки компоновщика С++ в OS X, где единственными отсутствующими символами являются те, которые содержат std::__1::basic_string? Это очень похоже на несовместимость стандартной библиотеки C++. Убедитесь, что и ваша библиотека, и приложение построены либо для libstdc++, либо для libc++ (и это также означает, что вы не можете использовать g++ для компиляции одного и clang++ для компиляции другого).   -  person neverpanic    schedule 27.11.2015
comment
Хороший улов. Я копаюсь в спецификации файла порта для OSG на MacPorts, чтобы выяснить, какой компилятор они используют. Поскольку MacPorts вручную создает каждый пакет на вашем компьютере, это определенно вызывает доверие. Я обновлю, как только я сделаю больше исследований.   -  person msmith81886    schedule 27.11.2015
comment
MacPorts всегда пытается использовать системный компилятор по умолчанию и следует выбранной системой по умолчанию стандартной библиотеке C++. Таким образом, если Portfile не делает что-то конкретное (а это не похоже), это будет clang++ использование libc++ для чего угодно ›= 10.9.   -  person neverpanic    schedule 28.11.2015
comment
В итоге у меня возникла эта проблема снова в отдельном проекте всякий раз, когда он находил используемую библиотеку строк. Я переустанавливаю MacPorts, чтобы убедиться, что это не помогло. Это похоже на то, как связывание проекта, использующего строки C++, вызывает неопределенные символы. Я проверил свой профиль bash, чтобы убедиться, что у меня нет плохих путей. Если ничего не помогает, я удалю все, включая XCode, и попробую еще раз.   -  person msmith81886    schedule 29.11.2015
comment
Несколько дополнительных вещей, которые вы можете проверить: Используйте otool -L для библиотек и двоичных файлов, чтобы проверить, какие библиотеки времени выполнения C++ они связывают. Убедитесь, что используемые вами заголовки C++ соответствуют библиотеке времени выполнения C++. Попробуйте явно использовать /usr/bin/clang++ -stdlib=libc++ в качестве компилятора и убедитесь, что в вашей среде не установлен MACOSX_DEPLOYMENT_TARGET (потому что это изменит библиотеку времени выполнения по умолчанию для clang).   -  person neverpanic    schedule 29.11.2015


Ответы (1)


Хм, я могу воспроизвести вашу проблему. Похоже, что libosgDB.dylib, установленный портом MacPorts OpenSceneGraph, связывается с libstdС++:

$ otool -L /opt/local/lib/libosgDB.dylib
/opt/local/lib/libosgDB.dylib:
    /opt/local/lib/libosgDB.100.dylib (compatibility version 100.0.0, current version 3.2.1)
    /opt/local/lib/libosgUtil.100.dylib (compatibility version 100.0.0, current version 3.2.1)
    /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 157.0.0)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 22.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
    /opt/local/lib/libosg.100.dylib (compatibility version 100.0.0, current version 3.2.1)
    /opt/local/lib/libOpenThreads.20.dylib (compatibility version 20.0.0, current version 3.2.1)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1255.1.0)
    /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 728.4.0)

Я считаю это ошибкой порта OpenSceneGraph. Пожалуйста, отправьте тикет, чтобы исправить это. Между тем, используйте -stdlib=libstdc++ в командной строке вашего компилятора, чтобы ваш пример был связан. Обратите внимание, что это означает, что вы не можете использовать возможности C++11.

person neverpanic    schedule 29.11.2015