1

I am having a problem getting an OpenSceneGraph project to link properly on my Mac. I installed it via macports and I have gotten osgviewer and other osg programs to work, meaning it was compiled and linked somehow. The code is part of a larger project, however I separated out the OSG code down to the bare bones to isolate my problems. I first thought it was a CMake issue, so I created a Makefile to try and isolate there. That made no difference.

Here is the the sample code.

// 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;
}

Here is the Makefile code. I have added way more than needed to no effect.

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)

Here is the make output with VERBOSE=1 on the specific command.

$ 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

I have run otool and other apps against the shared libraries to try and find where the undefined reference is. I know when I run nm, the symbol for both of these methods are in libosgDB.dylib, yet linking it does not work.

I am starting to compile OpenSceneGraph from source, but that is also creating compile errors on its own. I have a long fight ahead of me. Thank you very much in advance for your time.

Update:

Observations

  • Reordering the libraries on the compiler line does not work.
msmith81886
  • 2,286
  • 2
  • 20
  • 27
  • 1
    C++ linker errors on OS X where the only missing symbols seem to be those that contain `std::__1::basic_string`? That looks a lot like a C++ standard library incompatibility. Make sure that both your library and application are built against either libstdc++ or libc++ (and that also means you cannot use g++ to compile one and clang++ to compile the other). – neverpanic Nov 27 '15 at 10:42
  • Good catch. I am digging into the portfile spec for OSG on MacPorts to figure out which compiler they use. As MacPorts manually builds each package on your machine, that definitely gives this credence. I will update once I do more research. – msmith81886 Nov 27 '15 at 17:55
  • MacPorts always tries to use the system default compiler and follows the system's default choice of C++ standard library. So unless the `Portfile` does anything specific (and it doesn't seem to), that would be `clang++` using `libc++` on anything >= 10.9. – neverpanic Nov 28 '15 at 19:20
  • I ended up having this issue again on a separate project whenever it found the string library used. I am reinstalling MacPorts to make sure it did not contribute. It is like linking a project which uses C++ strings is causing undefined symbols. I checked my bash profile to make sure I didn't have bad paths. If all else fails, I will uninstall everything including XCode and give it another shot. – msmith81886 Nov 28 '15 at 21:59
  • A couple of additional things you could check: Use `otool -L` on libraries and binaries to check against which C++ runtime libraries they link. Make sure that the C++ headers you use match the C++ runtime library. Try explicitly using `/usr/bin/clang++ -stdlib=libc++` as compiler and make sure you don't have `MACOSX_DEPLOYMENT_TARGET` set in your environment (because it will change the default runtime lib of clang). – neverpanic Nov 29 '15 at 16:22

1 Answers1

1

Hm, I can reproduce your problem. It seems the libosgDB.dylib installed by MacPorts' OpenSceneGraph port links against libstdc++:

$ 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)

I consider this to be a bug of the OpenSceneGraph port. Please file a ticket to get this fixed. Meanwhile, use -stdlib=libstdc++ in your compiler command line to get your example to link. Note that this means you cannot use C++11 features.

neverpanic
  • 2,918
  • 18
  • 27