Undefined symbol with JsonCPP library in Linux 64. What am I missing? - c++

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.

Related

CLion - cannot solve undefined reference to constructor in class

I've already looked at this SO answer but I cannot seem to find the solution for my case.
I just started working in C++ and CLion. I did a basic test project that includes a header file and the main function then executes a method from the included class - all working just fine, CLion compiler is MinGW.
Now the real project I need to work on integrates a SDK from a vendor written in C++. They do have examples as well. Every time I run them, CLion breaks the build and complains about undefined references... the include file paths are all correct and CMakeList.txt looks like this:
project(test_2)
include_directories("../libraries/bin/headers/")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_EXE_LINKER_FLAGS "")
set(PROJECT_HEADERS
"../libraries/bin/headers/SDK.h"
"test.h"
)
set(PROJECT_SOURCES
main.cpp
)
add_executable(test_2 ${PROJECT_SOURCES} ${PROJECT_HEADERS})
the first undefined reference that is listed is the constructor of the SDK class, which is written simply as:
class SDK{
...
SDK();
...
}
Any suggestions what the problem is ?
Because of the current situation I cannot reach anybody on their end, so I thought I ask here...
Thanks !
Solution:
the solution was to compile the libs from the .cpp file an make a clean CMakeList file referencing those libs, this then resolved the undefined reference errors.
I'm not fluent in CMake - but you probably have to also link libraries/directories using something like target_link_libraries()/target_link_directories() if using external SDK. Seems to me that you simply tell the compiler "hey, here is my SDK header, do something" but compiler doesn't know where are the symbols for this SDK defined. Here is a little bit of an explanation what is the basic difference between the two, but I recommend checking CMake documentation directly.
c̛̣o̢̥m̯͕̖̠̙͡p͕̭͚͓̮̲ḭ͓͇͔̟̫l̪͈i͉̟̜̺͖͓͉n̮̻̼g͎̩̳̯ ̻̯̹̦̱̠̀w͕̬̜i̖̭̣th̹̠̕ C̙M̩a̲̮̹͉̻̥̥ķ͕̤̭̠͚e̩̙̼ ̫̮is̻̗͈͓͟ f̧̮͓̦u͏̯ͅń̹̣
I have no clue how the library that you're using is designed, but if there is no definition of the constructor in the header file, it is clearly not header-only. So you either have to link to that library, or add its implementation file (if you have one) to your project so linker gets what you promised. I suggest to look at target_link_libraries to see how to link in CMake (there are more ways to do it though).
Undefined reference error generally means that linker did not find something that was advertised in a header.
the solution was to compile the libs from the .cpp file an make a clean CMakeList file referencing those libs, this then resolved the undefined reference errors.

Including fftw in an idl call_external c++ shared library

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.

Need help understanding C++ libraries, compiling, linking, header files for specific project

This is my first stab at C++, also I know that the question is broad but I have a specific example that I'm working with so hopefully that will narrow everything down a bit.
I'm basically attempting to compile a C++ game manually in Linux (Ubuntu 14.04). The source code I am attempting to compile is located in this directory: https://github.com/akadmc/SmashBattle/tree/master/battle.
I'm CD'ing into the battle directory and, perhaps naively running
gcc *.cpp
I started seeing multiple issues as such:
compilation terminated.HealthPowerUp.cpp:1:21:
fatal error: SDL/SDL.h: No such file or directory #include "SDL/SDL.h"
and
compilation terminated.LaserBeamPowerUp.cpp:1:21:
fatal error: SDL/SDL.h: No such file or directory #include <SDL/SDL.h>
After researching header file includes I concluded that includes without <>'s are basically just relative paths to include a header file, and that when they are wrapped in <>'s they can either lookup the file through a listing of directories specified in an enviornment variable, or a command line option.
So my first question is, is there any reason the developer used
#include "SDL/SDL.h
AND
#include <SDL/SDL.h>
in different files? There was no SDL directory in the source code...
After realizing that SDL was missing from the source code / environment in one way or another I did tinkering. I was pretty confused (and still am) because I downloaded the SDL source files, didn't see any header files, ended up building a version of SDL by using cmake, and then build. I realized afterwards that I just made a local executable and didn't yield any header files. Then I realized that I just needed the development library, downloaded that, and put higher in the directory tree and then included it at compile with
c++ *.cpp -I $HOME/Desktop/smashProject/source/
Afterwards, the previous header file errors went away - but I started getting errors like the following:
Text.cpp:(.text+0x17): undefined reference to `SDL_RWFromFile'
Text.cpp:(.text+0x24): undefined reference to `SDL_LoadBMP_RW'
Text.cpp:(.text+0x34): undefined reference to `SDL_DisplayFormat'
And so on. Am I generally headed in the right path or do I have some misunderstanding about compiling, including development libraries, etc? Also I've read the the order of the compilation matters, and I'm not using any order + the developer didn't put a makefile in the source code or anything. I'm generally just confused as to how I should be doing this. Any help would be greatly appreciated.
Yes, you are on the right track. However, now you need to have a linkage to the SDL libraries. The -I just includes an extra library path but you have to actually link your assembly to the SDL files.
See this stack overflow question for more information.
How to compile an example SDL program written in C?

Creating shared library containing other libraries

i've written a class from that i want to create a shared library. But this class uses other libraries. The call that i use to generate the library is of the form
g++ -fpic -c [necessary *.cpp files] [necessary includes]
Unfortunately this call leads to an error, namely iostream.h: No such file or directory.
But when i build a testfile using the library code it compiles and works properly.
Where might be the problem?
Thanks for your help.
Firstly, I'm pretty sure that you should be using iostream rather than iostream.h so you could try changing that in your source code. E.g.
#include <iostream>
Secondly, you need to check the include directives on the compilation line, as what you're getting is a compilation error indicating that the preprocessor can't find this file. As you haven't listed either your failed or successful commands here, I can't add much more than that.

Problems including jsonCpp headers

I'm trying to implement the jsoncpp libraries in my C++ code, I wrote a simple piece of code just to try it out, and it's not even compiling.
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#ifndef json_included
#define json_included
#include "jsoncpp\include\json\json.h"
#endif
//#include "json\jsonC\json.h"
int main(int argc, char **argv)
{
std::string example = "{\"array\":[\"item1\", \"item2\"], \"not an array\":\"asdf\"}";
Json::Value value;
Json::Reader reader;
bool parsed = reader.parse(example, value, false);
std::cout << parsed;
return 0;
}
The errors i'm getting are:
undefined reference to `Json::Reader::parse(std::string const&, Json::Value&, bool)'
undefined reference to `Json::Reader::Reader()'
undefined reference to `Json::Value::~Value()'
undefined reference to `Json::Value::Value(Json::ValueType)'
I'm a bit new to C++, is there something I'm missing in the include statement? Or does jsonCpp need something extra?
Thank you for your time!
Your code is compiling, but it is not linking. You forgot to provide the JSON shared library files to your linker (or, on newer versions, to add the amalgamated jsoncpp.cpp to your project).
Without knowing more about your development environment, it's hard to give you more specific instructions.
BTW, you're writing C++; use C++ headers like cstdio, not stdio.h, please. You also failed to include C++ string and got lucky that it "worked" through some JSON header including it for you.
"Undefined reference" sounds like a linker problem. Does jsoncpp come with a library that you need to link to, such as a .so, .a, .lib or .dll file?
According to the jsoncpp README, the library must first be built using scons. Presumably this will then output a library file such as a .so, .a, .lib or .dll file. You must then follow your compiler's rule for linking against such a library (e.g. add it to the end of the command line when compiling, or add it to the "additional libraries" field in the project config in your IDE).
In my case (using CodeBlocks IDE on Ubuntu) the problem was that I needed to add the json.cpp file (generated with python amalgamate.py from within the jsoncpp project) to my build targets.
In other words, I added a -c jsoncpp.cpp option to my g++ compile statement.
You need to link to the json libraries, e.g. using -ljson_linux-gcc-4.4.3_libmt
You can find the exact library name by looking in the library directory, e.g. /usr/lib
If you're using Visual Studio, add the .lib file to Project Properties, Linker, Input, Additional Dependencies and specify the path in Project Properties, Linker, General, Additional Library Directories
Two potential issues:
There is a bug in some versions of the jsoncpp library code where amalgated needs to become amalgamation for the linking to work correctly.
As the other answers suggested, #include
After you compile jsoncpp you can find the libraries in the folder libs/ . For convenience you can put it in /usr/lib and then link it at run time by passing -llibjson_linux-gcc-4.4.3_libmt as an argument to g++.
I have renamed libjson_linux-gcc-4.4.3_libmt.so to libjson.so and can link it by specifying -ljson.