views:

669

answers:

3

I am building a library, called physgameengine, to aid in building games. This game library links against several libraries, including: Ogre3d, Bullet Physics and SDL, which are in the library files libOgreMain-1.6.5.so, libBulletCollision.a, libBulletDynamics.a, libBulletSoftBody.a, libSDL-1.2.so.0. This Library/Shared object appears to build just fine in Ubuntu 9.10, using GCC and Code::blocks. It does build fine on windows with mingw and Code::blocks.

In windows I can make games that compile/link using the library I built just fine, those programs run and do exactly what I expect it to. In Ubuntu when I try to compile/link a game that uses this Library I am making I get lots of undefined reference errors. But none to the functions or objects in the library I built, but rather to the items that my library calls. Here is an example of the errors I get.

> ||warning: libOgreMain-1.6.5.so, needed by ../physgameengine/bin/ubuntudebug/libphysgame.so, not found (try using -rpath or -rpath-link)|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::Root(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::StringUtil::BLANK'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::updateAabbs()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::createRenderWindow(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int, bool, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Timer::getMilliseconds()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::createSceneManager(unsigned short, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::~Root()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::~btCollisionWorld()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::renderOneFrame()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionObject::btCollisionObject()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Timer::getMillisecondsCPU()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btSimulationIslandManager::buildAndProcessIslands(btDispatcher*, btCollisionWorld*, btSimulationIslandManager::IslandCallback*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Viewport::getActualWidth() const'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::initialise(bool, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Camera::lookAt(Ogre::Vector3 const&)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::removeCollisionObject(btCollisionObject*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Viewport::getActualHeight() const'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Timer::reset()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::restoreConfig()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Timer::~Timer()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::NedAllocImpl::deallocBytes(void*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::convexSweepTest(btConvexShape const*, btTransform const&, btTransform const&, btCollisionWorld::ConvexResultCallback&, float) const'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::NedAllocImpl::allocBytes(unsigned int, char const*, int, char const*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `typeinfo for btCollisionWorld'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionObject::~btCollisionObject()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btSimulationIslandManager::btSimulationIslandManager()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Root::showConfigDialog()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionObject::setActivationState(int)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::LogManager::getSingleton()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::performDiscreteCollisionDetection()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::LogManager::logMessage(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Ogre::LogMessageLevel, bool)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Timer::Timer()'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::btCollisionWorld(btDispatcher*, btBroadphaseInterface*, btCollisionConfiguration*)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `typeinfo for btCollisionObject'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `Ogre::Camera::setPosition(Ogre::Vector3 const&)'|
../physgameengine/bin/ubuntudebug/libphysgame.so||undefined reference to `btCollisionWorld::addCollisionObject(btCollisionObject*, short, short)'|
||=== Build finished: 36 errors, 1 warnings ===|

The bulk of the code is identical between windows and Linux they seem to have equivalent compile/linker settings. But the Linux game appears to be linking against the original libraries that my library should be linking against. What is going on? Any Ideas on how to fix it?

+2  A: 

Just based on the first line:

> ||warning: libOgreMain-1.6.5.so, needed by ../physgameengine/bin/ubuntudebug/libphysgame.so, not found (try using -rpath or -rpath-link)|

It looks like your linker is having trouble finding your shared object. Check to make sure your linker's include paths are properly set up.

Adam Maras
This warning is produced by compiling the game. It should never be looking this shared object, in the first place.
Sqeaky
+1  A: 

The very first line of your error tells you the problem:

libOgreMain-1.6.5.so, needed by libphysgame.so, not found (try using -rpath or -rpath-link)|

You need to specify the directory where libOgreMain is installed. Since you need to use a linker option, you need to use the -Wl feature of gcc. Assuming the files is in /opt/lib, you would add:

gcc -Wl,-rpath-link,/opt/lib ...rest of linker line...
R Samuel Klatchko
Would I add this to the game, or to the library. If I add this to the game this removes a key advantage of building the separate library?
Sqeaky
I misunderstood. I thought this did something else at first. This defines where this executable will look for its shared libraries, so I actually need it in both so the library know where to look for Ogre/bullet/ whatever unless that can be determined by normal means at compile time, and I need it in the game to find my library.
Sqeaky
+1  A: 

Unlike in Windows, in Linux systems it's not enough to place a shared library file into the same folder as executable.

You should either provide an LD_LIBRARY_PATH variable or follow the linker's advice and use -rpath (check this question)

Pavel Shved
I am marking this response as the answer because the link provide is what made me realize that I was looking at this completely incorrectly.
Sqeaky