0

I'm trying to create a shared library (.so file I believe) for use with a Python script using SWIG. The program will compile and run fine on it's own, but when I create the shared library and try to import the library using, I get an error like so:

ImportError: /path/to/file.so: undefined symbol: _ZNK4Glib5Error4whatEv

I checked out the symbol using c++filt to see what was causing the issue:

c++file _ZNK4Glib5Error4whatEv ---> Glib::Error::what() const

I'm not really sure what's causing this error. I tried using pkg-config --cflags with glib-2.0 as the first library, but that didn't solve the issue. I read on some other posts about linking the LD path, but I'm not sure what that is or how to do it.

Additionally, I tried including an extra header in my CPP file

#include <glib/gerror.h>

But that didn't make a different either. Here are the steps I took before things didn't work:

  1. Compile program and save *.o files using

     CPPFLAGS := i_include/ -rdynamic -Wall -ggdb3 -std=c++11 $(shell pkg-config --cflags gtk+-3.0 gtkmm-3.0
     ...
     g++ -c $(CPPFLAGS) $^ -o $@ -rdynamic
     //(This line executes for many files^)
    
  2. Move to directory that contains the Python file that I'd like to call CPP funcitons from and create a .i file as an interface for SWIG/Python.

  3. Run swig -python file.i

  4. Run g++ -shared /path/to/files.o -o newFile.so

  5. Import module in Python and try to run Python script, but get import error instead.

It seems like the only place I even have a call to Glib::Error is when I'm trying to open a file that doesn't exist, but like I said, the program compiles and runs fine. If there's any information that I left out, comment and I'll add it!

UPDATE: I ran ld -o outifle.o /path/to/files.o and I hundreds of undefined reference errors (it look like every function call was undefined). Did I use ld wrong?

UPDATE: @AsteroidsWithWings was patient enough to suggest a solution that worked for other users, where linking the libraries comes at the end of a command. Unfortunately, this did not solve my problem. I placed the linking for every relevant Make directive at the end and repeated the below process.

UPDATE: @PhilipWithnall suggested that I run pkg-config --cflags --libs ... (addition of --libs flag). After recompiling and running again, this unfortunately did not solve my problem.

Alex Eastman
  • 305
  • 1
  • 10
  • _"as the first library"_ What happens if you put it at the end? – Asteroids With Wings Jul 16 '20 at 19:33
  • Does this answer your question? [Why does the library linker flag sometimes have to go at the end using GCC?](https://stackoverflow.com/questions/9417169/why-does-the-library-linker-flag-sometimes-have-to-go-at-the-end-using-gcc) – Asteroids With Wings Jul 16 '20 at 19:34
  • _"I hundreds of undefined reference errors (it look like every function call was undefined). Did I use ld wrong?"_ No; you'll be missing the definition/reference for every single non-inlined glib symbol used in your project. – Asteroids With Wings Jul 16 '20 at 19:35
  • We usually don't list library dependencies in `CPPFLAGS`. You should consult a Makefile best-practices guide. – Asteroids With Wings Jul 16 '20 at 19:35
  • I can try putting it at the end. It's not explicitly called right now though, since it's part of gtk+-3.0. I don't think that will answer my question either, since I'm compiling and then running `gcc -shared`, but I might be mistaken. – Alex Eastman Jul 16 '20 at 19:37
  • Where should I list the library dependencies instead? :-) – Alex Eastman Jul 16 '20 at 19:37
  • I've already suggested further research resources. – Asteroids With Wings Jul 16 '20 at 19:40
  • I can find a best practices guide. However, I'm a little confused about the link you presented. I'm not sure how to apply it to my own situation. Like I mentioned, I'm compiling and *then* using `gcc -shared` – Alex Eastman Jul 16 '20 at 19:43
  • Regardless. You're putting the glib lib references first in your build commands. You said so yourself, and showed an example (it's done via your `CPPFLAGS`). But, with GCC, you list the libraries _after_ the modules that depend on them, otherwise nothing happens. So just do that - make them come after `$^`. It's up to you to find a way to structure your Makefile to achieve it in an elegant way, but for now, to solve this problem, you can just put your `$(shell pkg-config .....)` at the _end_ of the build command and observe that it now links properly, no? – Asteroids With Wings Jul 16 '20 at 19:44
  • You mean like so? My apologies, I'm new to Make and I didn't write this file, I'm only working with it. `g++ -c $(CPPFLAGS) -o $@ -rdynamic $^` – Alex Eastman Jul 16 '20 at 19:50
  • Perhaps you should have a discussion with the person who wrote it. :) – Asteroids With Wings Jul 16 '20 at 19:50
  • No, I didn't say to move `$^`, but to move the Glib library flags. So that they come after `$^`. They can't come "after" a thing that's at the end! You could put `$^` before `$(CPPFLAGS)` I guess (for now). – Asteroids With Wings Jul 16 '20 at 19:51
  • I moved the $^ to immediately after the -c and before $(CPPFLAGS), and re-ran `gcc -shared /path/to/files.o -o outfile.so` but I'm still getting the same error. – Alex Eastman Jul 16 '20 at 19:57
  • Because you're not running the modified commands. You only re-ran a command that hasn't been changed. So it's not a surprise the result is the same. Do a rebuild with the new Makefile. – Asteroids With Wings Jul 16 '20 at 19:58
  • I `make clean; make`'d - I should've said that. – Alex Eastman Jul 16 '20 at 20:00
  • Then I don't know what the problem is. I suggest you discuss with the author of the Makefile. Good luck! – Asteroids With Wings Jul 16 '20 at 20:00
  • Try `pkg-config --cflags --libs` rather than just `pkg-config --cflags` – Philip Withnall Jul 17 '20 at 07:34
  • Added --libs and recompiled, but no dice. – Alex Eastman Jul 17 '20 at 13:38

0 Answers0