I am making a c++ shared library to include in an IDL program on linux. I'm using call_external and that is all working fine. However I am used to dynamically linking fftw in the code I wish to include in the library. The code compiles into a library file fine but when I try to run it the idl program crashes with the error 'symbol lookup error.. undefined symbol: fftw_plan...'
I suspect it is due to the dynamic link not working in the shared library but am not sure how to deal with that. I've looked at the fftw documentation and IDL help. I've tried googling the subject but it is a little niche.
So in my makefile I'm linking the shared library using 'FFTWFLAG=-lfftw3 -lm'
And making the library file with
OneTurn.so: $(OBJECTS)
$(CC) $(INCFLAGS) $(LDFLAGS) $(FFTWFLAG) -o OneTurn.so $(OBJECTS)"
I'm then calling the c++ library from idl with
IDL> a=double(1)
IDL> t=call_external('OneTurn.so', 'OneTurn', a, a, /D_VALUE, /UNLOAD,/CDECL)
Making bunch
/usr/local/harris/idl87/bin/bin.linux.x86_64/idl: symbol lookup error: ./OneTurn.so: undefined symbol: fftw_plan_r2r_2d
If I don't include the fftw stuff everything works as expected.
Update
I had to pass the fftw linker arguments through to the shared library with -Wl,-lfftw3,lm.
This now compiles and runs however the fftw code still does not work! Working on it...
Thanks for your answers and suggestions so far!
Update 2
I was being a muppet: hadn't included a bit of code for one function, that was the undefined symbol... I didn't recognise it as it had a pre- and post-fix. Thanks for your help!
I haven't done this with C++ recently. Could there be a name mangling problem? Look at the .so file with nm to see make sure you have the right symbols and to check their names.
Related
Working on a code that enables Python to call a C++ code compiled into shared library file (.so file) via Python's ctypes module, using the standard ctypes.CDLL method. The C++ code performs the numerical calculations and the Python code mainly serves as a controller and performs data analysis. Everything worked fine. However, as soon as I included jsoncpp library in C++ code, Python started to complain about undefined symbol errors such as undefined symbol: _ZN4Json5ValueaSES0_ etc. I used jsoncpp library in C++ mainly to export data to a JSON file. Having searched the internet for a while, it appears this hasn't been discussed that much. Any idea how to handle this?
Well, looks like the solution is to also include -ljsoncpp flag while compiling towards the shared .so file:
$(CC) -shared -o testcode.so testcode.o -ljsoncpp
I am only asking this as a last resort, it's been days that I have been trying to fix this linker problem and I have tried so many solutions found at stackoverflow that I have lost count.
Basically, I am trying to use the constuctor from a class included in a shared library. Let's call it LibraryClass(string) and let's call this library liblibrary.so.
Ok, so I am trying to use this constructor in a class called DummyClass and then compiling this one and lots of other DummyClasses and then compiling the objects into a single executable
I am using SCons btw, so it first compiles all the DummyClasses without including any library
g++ -o DummyClass.o -I.... -I.... .... DummyClass.cpp
g++ -o DummyClass2.o -I.... -I.... .... DummyClass2.cpp
Then it compiles into a final executable linking the necessary libraries
g++ -o executable DummyClass.o DummyClass2.o -L/path/to/libs -llibrary -ldependency
Also, the library depends on functions from another library, let's call it libdependency.so
After compiling the executable, it gives me an undefined reference to LibraryClass(string) in DummyClass.o : DummyClass.cpp line ...
It's a big project and there are lots of other libraries involved and lots of other classes being compiled into the 'executable'
First, I've tried to verify that the function is indeed included in the library so i tried to use nm -C liblibrary.so and I can indeed see the function on the output. However if I try to use
nm -CD liblibrary.so I cannot find the function in there (I don't know why but some answers at stack overflow used -CD others used -C)
It doesn't make sense, it should work, first it compiles all the classes, then it compiles the objects with undefined references into a single executable linking with all the required libraries.
What else can I check for?
About the possible duplicate of another question. I believe my question is unique since it is been shown that it might be a problem with the library itself, the question that has been marked as a possible duplicate doesn't mention my probable solution. I do believe my question might help others in the future since I have been looking for answers on stackoverflow for a whole week.
This problem is not specific to Fubi, but a general linker issue. These past few days (read as 5) have been full of linking errors, but I've managed to narrow it down to just a handful.
I'm trying to compile Fubi (Full Body Interaction framework) under the Linux environment. It has only been tested on Windows 7, and the web is lacking resources for compiling on a *nix platform.
Now, like I mentioned above, I had a plethora of linking problems that dealt mostly with incorrect g++ flags. Fubi requires OpenNI and NITE ( as well as OpenCV, if you want ) in order to provide it's basic functionality. I've been able to successfully compile both samples from the OpenNI and NITE frameworks.
As far as I understand, Fubi is a framework, thus I would need to compile a shared library and not a binary file.
When I try to compile it as a binary file using the following command
g++ *.cpp -lglut -lGL -lGLU -lOpenNI -lXnVNite_1_5_2 -I/usr/include/nite -I/usr/include/ni -I/usr/include/GL -I./GestureRecognizer/ -o FubiBin
and I get the output located here. (It's kind of long and I did not want to ruin the format)
If I instead compile into object files (-c flag), no errors appear and it builds the object files successfully. Note, I'm using the following command:
g++ -c *.cpp -lglut -lGL -lGLU -lOpenNI -lXnVNite_1_5_2 -I/usr/include/nite -I/usr/include/ni -I/usr/include/GL -I./GestureRecognizer/
I then am able to use the ar command to generate a statically linked library. No error [probably] occurs (this is only a guess on my end) because it has not run through the linker yet, so those errors won't appear.
Thanks for being patient and reading all of that. Finally, question time:
1) Is the first error regarding the undefined reference to main normal when trying to compile to a binary file? I searched all of the files within that folder and not a single main function exists.
2) The rest of the undefined reference errors complain that they cannot find the functions mentioned. All of these functions are located in .cpp and .h files in the subdirectory GestureRecognizer/ which is a subdirectory of the path I'm compiling in. So wouldn't the parameter -I./GestureRecognizer/ take care of this issue?
I want to be sure that when I do create the shared library that I won't have any linking issues during run-time. Would all of these errors disappear when trying to compile to a binary file if they were initially linked properly?
You are telling the compiler to create an executable in the first invocation and an executable needs a main() function, which it can't find. So no, the error is not normal. In order to create a shared library, use GCC's "-shared" option for that. Trying some test code here, on my system it also wants "-fPIC" when compiling, but that might differ. Best idea is to dissect the compiler and linker command lines of a few other libraries that build correctly on your system.
In order to add the missing symbols from the subdirs, you have to compile those, too: g++ *.cpp ./GestureRecognizer/*.cpp .... The "-I..." only tells the compiler where to search when it finds an #include .... I wouldn't be surprised if this wasn't even necessary, many projects use #include "GestureRecognizer/Foo.h" to achieve that directly.
BTW:
Consider activating warnings when running the compiler ("-W...").
You can split between compiling ("-c") and linking. In both cases, use "g++" though. This should decrease your turnaround time when testing different linker settings.
I'm adding two classes and libraries to a system, parent.so and child.so deriving from it.
The problem is when the program is loading child.so it cannot find parent's virtual function's definition from parent.so.
What happens,
nm -D child.so will gives something like (I just changed the names)
U _ZN12PARENT15virtualFunctionEv
The program will crash running
_handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL); //filename is child.so
it'll give an error with LD_DEBUG = libs
symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv (fatal)
The thing I cannot explain is, I tried LD_DEBUG = symbols using GDB, when running dlopen, the log shows it tried to look up basically in all libaries in the system except parent.so, where the symbol is defined. But from libs log parent.so is already loaded and code is run, and it is at the same path of all other libraries.
......
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libm.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libc.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/ld-linux.so.2
27510: child.so: error: symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv(fatal)
How the program or system is managing which library to look for a symbol's definition?
I'm new to Linux, can anybody point me some directions to work on?
Thanks.
EDIT
The command used to generate parent.so file is
c++ -shared -o parent.so parent.o
Similar for child.so. Is any information missing for linking here? Looks like child is only including parent's header file.
EDIT2
After another test, calling
_handle = dlopen("parent.so", RTLD_NOW|RTLD_GLOBAL);
before the crashing line will solve the problem, which I think means originally parent.so was not loaded. But I'm still not very clear about the cause.
You need to tell the linker that your library libchild.so uses functionality in libparent.so. You do this when you are creating the child library:
g++ -shared -o libchild.so child_file1.o child_file2.o -Lparent_directory -lparent
Note that order is important. Specify the -lparent after all of your object files. You might also need to pass additional options to the linker via the -Wl option to g++.
That still might not be good enough. You might need to add the library that contains libparent.so to the LD_LIBRARY_PATH environment variable.
A couple of gotchas: If you aren't naming those libraries with a lib prefix you will confuse the linker big time. If you aren't compiling your source files with either -fPIC or -fpic you will not have relocatable objects.
Addendum
There's a big potential problem with libraries that depend on other libraries. Suppose you use version 1.5 of the parent package when your compile your child library source files. You manage to get past all of the library dependencies problems. You've specified that your libchild.so depends on libparent.so. Your stuff just works. That is until version 2.0 of the parent package comes out. Now your stuff breaks everywhere it's used, and you haven't changed one line of code.
The way to overcome this problem is to specify at the time you build your child library that the resultant shared library depends specifically on version 1.5 of libparent.so`.
To do this you will need to pass options from g++/gcc to the linker via the -Wl option. Use -Wl,<linker_option>,<linker_option>,... If those linker options need spaces you'll need to backslash-escape them in the command to g++. A couple of key options are -rpath and -soname. For example, -rpath=/path/to/lib,-soname=libparent.so.1.5.
Note very well: You need to use the -soname=libparent.so.1.5 option when you are building libparent.so. This is what lets the system denote that your libchild.so (version 1.0) depends on libparent.so (version 1.5). And you don't build libparent.so. You build libparent.so.1.5. What about libparent.so? That needs to exist to, but it should be a symbolic link to some numbered numbered version (preferably the most recent version) of libparent.so.
Now suppose non-backward compatible parent version 2.0 is compiled and built into a shiny new libparent.so.2.0 and libparent.so is symbolically linked to this shiny new version. An application that uses your clunky old libchild.so (version 1.0) will happily use the clunky old version of libparent.so instead of the shiny new one that breaks everything.
It looks like you're not telling the linker that child.so needs parent.so, use something like the following:
g++ -shared -o libparent.so parent.o
g++ -shared -o libchild.so -lparent child.o
When you build your main program, you have to tell the compiler that it links with those libraries; that way, when it starts, linux will load them for it.
Change their names to libparent.so and libchild.so.
Then compile with something like this:
g++ <your files and flags> -L<folder where the .so's are> -lparent -lchild
EDIT:
Maybe it would be a smaller change to try loading parent.so before child.so. Did you try that already?
I'm using JsonCPP as a parser for Json in C++, the problem is when I declare my var Json::Value root;, its compiles very well but when I use it the program crashes showing this msg: undefined symbol: _ZN4Json5ValueD1Ev.
What I missing?
I thought that is was a linker problem so I put my library libjson_linux-gcc-4.1.2_libmt.so in /usr/lib and /usr/lib64, and the .h to /usr/include/json so when I call for the library in my code I do #include <json/json.h>.
Everything is fine because I can compile it very well! but I recieve the same crashes.
Is there any path that I am missing to link?
Thank you all!
PD: I forget to say that I'm not compiling with g++, I'm compiling with a makefile
In addition to including the header file, you need to link to the library as well.
At the linking stage, add the argument -ljson_linux-gcc-4.1.2_libmt
This works for me, putting the libjson_linux-gcc-4.1.2_libmt.so to the same dir of your program located when running it.