Matthew Hoggan
Matthew Hoggan

Reputation: 7604

Undefined symbols, though they are defined in our .cpp file

I am working on getting a library to build in linux. This builds and works in Windows, but on Linux I am getting an unresolved symbol in our library when consuming the static lib. The code appears as follows:

class MyClass : public AnotherClassRefCounded
{
public:
  static bool queryInstance(MyClass **ppmyClass);
};

Inside the .cpp file for this class I have:

#include "stdafx.h"
#include "MyClass.h"

MyClass* MyClass::m_pInstance = NULL;

bool MyClass::queryInstance(MyClass **myClass)
{
  if(m_pInstance == NULL)
  {
    m_pInstance = new MyClass();
    m_pInstance->incRef(); 
  }

  m_pInstance->incRef();
  *myClass = m_pInstance;
  return true;
}

Now when running nm -Cu on libMyLib.a I get the following output:

[matt6809@hogganz400 libDebug]$ nm -Cu libMappingd.a | grep queryInstance
                 U AFewMoreScopes::MyClass::queryInstance(AFewMoreScopes::MyClass**)

My system info is:

[matt6809@hogganz400 libDebug]$ cat /etc/redhat-release ; gcc --version
Red Hat Enterprise Linux Server release 6.1 (Santiago)
gcc (GCC) 4.4.5 20110214 (Red Hat 4.4.5-6)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

For copyright reasons I cannot post the identical code. I have reproduced the code to the best of my abilities. If you feel I am missing any info please don't hesitate to ask for it.


UPDATE

Example of build:

...

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp

...

ar cqs libMappingd.a <all object files>

UPDATE 0

This is very interesting. Inside the object file for "MyClass" the symbol is not undefied:

MyClass.o:
                 <My Symbol Not Undefined>

However if you go to another one of the object files:

<Other Object>.o:
                 ...
                 U Scope::MyClass::queryInstance(Socpe::MyClass**)

UPDATE1

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp
g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o OtherClass.o OtherClass.cpp
rm -f libMappingd.a
ar cqs libMappingd.a <Other Objects> MyClass.o OtherClass.o

and

g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o OtherClass.o OtherClass.cpp
g++ -c -include Mappingd -pipe -w -g -fPIC -Wall -W -DLINUXx86 <DEFINE FLAGS> <INCLUDE FLAGS> -o MyClass.o MyClass.cpp
rm -f libMappingd.a
ar cqs libMappingd.a <Other Objects> OtherClass.o MyClass.o

Make no difference I still get undefined symbol in the other library.

Upvotes: 1

Views: 2357

Answers (2)

Matthew Hoggan
Matthew Hoggan

Reputation: 7604

After much research, I discovered that the archiver on RHEL 6.1 has a bug in it. I stopped trying to pull in the static libs directly into the shared dynamic library, and instead I unpacked the static libs, and pulled the corresponding object files directly into the .so file. I now have 0 undefined symbols in our library apart from the ones that I am not statically linking against.

Upvotes: 0

Asaf
Asaf

Reputation: 4407

The main difference I know between VC++ and GCC is that the order of the object files you give the linker matters. A symbol which is used in object file A, must be defined either in it or after it in the link order.

Try moving MyClass.o to the end of the object files list.

Upvotes: 1

Related Questions