21

I'm not a frequent user of Linux and I think I did something wrong.

This is the code for a test dynamic library ".so" I'm generating.

class InternalClass
{
public:
    int Function(){ return 10; }
};

extern "C"
{
    int WrapperFunctionSimple() { return 10; }
    void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }
}

The compilation fails with the following error:

g++ -Wall -fexceptions -O2  -c /home/lidia/compartida/TestLibrary/TestLibrary/main.cpp -o obj/Release/main.o
g++ -shared  obj/Release/main.o  -o bin/Release/libTestLibrary.so -s  
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: warning: relocation against `_Znwm@@GLIBCXX_3.4' in read-only section `.text'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: relocation R_X86_64_PC32 against symbol `_Znwm@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

I tried with -fPIC as suggested and it compiles. But when using this library, It cannot be loaded when I add that last function:

void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }

The problem is using the InternalClass, without this function everything works.


I'm using VirtualBox. I installed OpenSUSE 64bit, the app that uses the library is also 64bit. In another linux distribution (Mint), with exactly the same project and settings (without fPIC), it can be compiled. When I use that library (.so) it works in SUSE.

I'm also using :

  • gcc (SUSE Linux) 7.5.0
  • g++ (SUSE Linux) 7.5.0
  • My IDE is Code::Blocks 20 (last version). Settings are empty except for the -m64 flag.

What am I doing wrong? This seems like something advanced Linux users could help me understand.

EDIT: To add more information, this can compile in Ubuntu with the same settings. Not in SUSE

Darkgaze
  • 2,280
  • 6
  • 36
  • 59
  • What does "It cannot be loaded" mean? – Sam Varshavchik Dec 22 '20 at 12:00
  • @SamVarshavchik It means that I get a DllImportException ( I use it from c# ), but it says the library cannot be loaded in the debug log. No more information returned – Darkgaze Dec 22 '20 at 13:13
  • I've tried reproducing the loading issue (used `-fPIC`) but a simple `dlopen` on the resulting shared library works. Please post what error you get from `dlerror()`, maybe try loading it from a C program first instead of C# – dyp Dec 03 '21 at 11:39

6 Answers6

11

It happened to me when I used GCC to compile a CPP file. So for C++ files use g++ only, and obviously not GCC, which is meant for c files.

Yugank Singh
  • 401
  • 6
  • 14
8

To me it happened, if one library (A) depends on another one (B) and library A was linked before library B. The solution is to link library B first and then A.

nee6AGag
  • 129
  • 1
  • 8
  • Can you also explain how can library A be linked before library B when using something like g++ or gcc? – cangozpi Mar 30 '23 at 13:35
3

In my case this happened when I had an abstract class A and two derived classes B and C like below.

class BaseAbstractClass
{
public:
    virtual void doNothing(void) = 0;
};

class A : public BaseAbstractClass
{
public:
    void doNothing(void){
        return;
    }
};

class B : public BaseAbstractClass
{
public:
    void doNothing(void);    // Only declaration, definition is nowhere
};

But one of derived classes (class B here) has only declaration of doNothing(), but lacks definition anywhere in project files.

1

I am using cmake and GCC in ubuntu and I got the same error.

In my case, I added the XX.h file to include directories, and used in my main.cpp a "typedef struct x" which is defined in XX.h header file. However I forgot to add XX.c to the executable sources.

This error is cleared when I added XX.c to the target executable sources in add_executable() of Cmake.

I hope I can clearly state my case.

0

I had a similar issue and the order of linking answer was useful for me. It ended up being I was including the cpp file rather than the header (include was called at wrong time.)

0

I have had this error on my project, both error messages.

I use CMake. In my CMakeLists.txt, I had such a code:

target_sources(${PROJECT_NAME}
    PUBLIC  ${HEADERS}
    PRIVATE ${SOURCES}
    )

target_link_libraries(${PROJECT_NAME} PRIVATE
   AnotherLib
)

A .cpp (mentioned in the SOURCES) was the culprit, it was not accessed. Removing PRIVATE fixed the problem.

Mykola Tetiuk
  • 153
  • 1
  • 13