Issues with linking library C++ - c++

My problem is I am not able to include a library into my current project. [The way to include a library in netbeans into a project is to link it via linker to the project]. However, in my current project(which is written by another programmer who left the organization) the option of linker is not appearing. I have attached a screenshot. I am faced with the issue that the option of linking the library via linker to my current project is not appearing in IDE. Can someone please please help me out. I'll be highly thankful to you for the same.
Please guide me as to how should I link the library to my project. I have really spent a lot of days doing it but I did not succeed.

Assuming you are only interesting in libspatialindex:
Make sure you have the appropriate files installed: try a locate libspatialindex and see where it is installed. You could have a *.a, *.so or similar extension. Note the path.
Go into your project root directory, i.e: /home/keira/netbeans/projects/myproject
Try: gcc -i main.cpp -L/usr/lib/ -lspatialindex -o myfile
Replace the -L/usr/lib with the actual location where you know the library is at.
The cxx link flag is usually the name of the library with an -l prefix. If for example the name found in the system is libspatialindex.so then its a good bet to try with -lspatialindex.
There is a way to find the actual flags on Debian & Ubuntu systems but I cannot atm remember it. Alternatively you can always look on google or read the library documentation.
When you usually see linker errors with undefined functions, etc, it means you're not linking, provided you have included the headers and they are found.
Now for Netbeans, I assume there is the option of passing extra arguments to the compiler. In this case, all you need is the -lspatialindex flag, provided Netbeans knows where to find the library and the headers. That is how it works in KDevelop and other IDE's I have used.
Alternatively if you want more control and more automation, you may want use a tool like cmake.

Related

Locating "undefined" references in a C/C++ Project

I am building a C++ project on my Ubuntu 64bit system using a provided Makefile, and this project also provides an API library for developers.
The compilation was successful, no errors at all, but when I try to include in my files the API libraries provided in the "api" folder, then g++ complains about undefined references.
It is not a problem about dependencies (I already built the project succesfully), in fact the missing references are about classes and functions provided by the project, but they are in some specific (sub-)folders (I don't know which ones!), I guess in some .so files, and g++ is not finding them, probably because it does not know they are in those specific subfolders.
It is not the first time this happens when trying to use APIs from any project, then I think I am missing something or I am doing something wrong in general when trying to use the libraries provided in a project.
In particular, the main problem is that I don't know how to tell the compiler where some classes or data structures are declared, and moreover I don't know how to locate them in order to know where they are.
Usually, a workaround I use to avoid this problem is to run make install (as root or using sudo) so that libraries and APIs are installed in standard folders (like /usr/include or /usr/lib) and if I do this thend I can include the API libraries using #include <library>, but in this last case it didn't work either, because perhaps some required files containing the not found classes/structures are not properly installed in the right folders in the system.
Another workaround I used sometimes is to try to put all the project files in the same folder instead of using the project folder structure, but clearly this is not good! :-)
But I noticed that several other people managed to use the APIs, then apparently they know some way of finding the files containing the "undefined" references and including them in the compilation.
Then my general question is: given a "classic" C++ project based on "Makefile" files and with usual folder names like src, lib, build, bin, etc., if I want to write C++ files using the libraries provided by the project, but the compiler complains about undefined references, how can I find the files (.so or .o or .cpp) containing such references? Is there any tool to find them? And how can I tell the compiler where they are? Should I use some command-line option for g++ or should I use the #include macro in some smart way?
PS I also tried to use the pkc-config linux tool to get right options to use for compilation and they were available, but the compiler still complains about the undefined references.
Some more degails about the project i tried:
For interested people a link to the project is below:
https://github.com/dreal/dreal3
And instructions on how to build it:
http://dreal.github.io/download/
Look into the -rpath linker option - specifically with the "$ORIGIN" argument. That lets you find libraries relative to your executable location so you don't have to install them to the standard locations but just need to put them somewhere known, relative to the executable. That should help you with one piece of the puzzle.
Note: -Wl, can be used to pass arguments to the linker via g++.
As for pointing the compiler/linker at a library so it can resolve undefined references by using that library, use the -l (that's lowercase L) option to specify the library name and -L to specify directories to search for libraries.
As for looking into a library (.so) file to see what symbols are in there, you have a few tools at your disposal: objdump, nm, readelf and objcopy.

Using 3rd Party Libraries in C++

I'm totally spinning my wheels with getting a couple of 3rd party libraries to work with my c++ programs. I'm looking for some general advice (40,000 foot level) about the general steps that one needs to take when implementing libraries.
First, some specifics: I am using code::blocks in Windows as my IDE. I like this IDE and really don't want to switch to anything else if I don't have to (I've tried visual c++ and also some things in linux). The libraries that I am trying to use are GMP and crypto++.
OK. What I think I know is this: After downloading the library, I unzip the file to a folder. I've been unzipping directly to C:\ with each zip file extracted to its own folder (e.g. c:\cryptopp and c:\gmp). I think that the next step is to build the library, but this is where I get totally stuck. How is this done? There are no executable files among those extracted. From what I can tell, I believe that I do this in code::blocks, but I have no idea how?
Finally, assuming that I can get this done, which I believe creates the .lib files, the last step before actually using the library in my code, is to link into the library. This part, I believe that I understand.
So, my question is broad: do I understand this process overall? And if so, how do I go about building these libraries, if in fact that it the thing that I am missing.
Thanks very much for indulging my ignorance. I'm totally rudderless right now and despite hours and hours on google, I'm making no progress. Also, feel free to correct anything that I have stated as fact that is not correct. Thanks a lot!
Usually libraries have a special file called makefile in them, and are built with a utility called Make (or one of it's variations, whatever works uder windows).
Usually all you have to do is to run Make in the directory where you have unpacked the source files, and it will do the rest itself.
If those libraries you mention (GMP and crypto++; disclaimer: I'm not familiar with either of them) don't have project files for code::blocks then you may still be able to compile them under Windows with MinGW.
If you have installed MinGW you use the MinGW shell to navigate to the appropriate directories which would be /c/cryptopp/ and /c/gmp in your examples - The MinGW shell works like a Unix shell, and has different naming conventions.
Then you need to compile the libraries. Check whether there's a Makefile in those directories, if there isn't you can check whether there's a configure script, which will generate the Makefile. If you have the Makefile you can type make which will compile the libraries with MinGW's port of the GCC compiler.
When the compilation is complete you should have a library in the form of a .a file (say libcryptopp.a) that you can link to your project. In code::blocks you would set the linker path (the -L command line option in GCC) to C:\cryptopp\bin or wherever the library has been compiled, and then add libcryptopp.a to the list of libraries you want to link (this is associated with the -l option in GCC). The convention is to leave out the lib prefix and the .a extension, so you would just add cryptopp to your library list. In the end your linker options should look like -LC:\cryptopp\bin -lcryptopp along with the
Also, to be able to use the libraries you need to add the path to the headers directory to the include path of your project. This is associated to the -I command line option in GCC, so your compiler's command line options would have something like -IC:\cryptopp\include somewhere.
Of course, all of the above assumes that you use code::blocks with GCC. If you're using it with VisualC++ then the principles are the same, but the specific steps differ.

Linux C++ linker /usr/bin/ld

I wrote a small application on Redhat Linux 6 using g++ 4.4.6. After compilation, I received an error
/usr/bin/ld: cannot find -lcrypto
I did a search for the crypto library and find them here,
[root#STL-DUNKEL01 bin]# find / -name libcrypto*
/usr/lib64/libcrypto.so.0.9.8e
/usr/lib64/libcrypto.so.10
/usr/lib64/libcrypto.so.6
/usr/lib64/libcrypto.so.1.0.0
My question is whether the compilation error is caused by /usr/bin/ld not having /usr/lib64/ in the search path? If yes, how can I add it?
Thanks.
No, you have likely incorrectly diagnosed the cause.
You need a libcrypto.so to link against. This is usually a symlink to one of the actual libraries, whose soname (libcrypto.so.??) will be embedded into the binary. Only that library is needed at runtime, but the symlink is necessary to compile.
See Diego E. Pettenò: Linkers and names for more details.
You have to add -L/usr/lib64 when calling gcc or ld.
Note, you can specify LD_LIBRARY_PATH as well/instead, but it is considered harmful to do so. (The link mentions Solaris specifically, but the issues apply to other OSs as well.)
Quote:
LD_LIBRARY_PATH is used in preference to any run time or default system linker path. If (God forbid) you had it set to something like /dcs/spod/baduser/lib, if there was a hacked version of libc in that directory (for example) your account could be compromised. It is for this reason that set-uid programs completely ignore LD_LIBRARY_PATH.
When code is compiled and depends on this to work, it can cause confusion where different versions of a library are installed in different directories, for example there is a libtiff in /usr/openwin/lib and /usr/local/lib. In this case, the former library is an older one used by some programs that come with Solaris.
Sometimes when using precompiled binaries they may have been built with 3rd party libraries in specific locations; ideally code should either ship with the libraries and install into a certain location or link the code as a pre-installation step. Solaris 7 introduces $ORIGIN which allows for a relative library location to be specified at run time (see the Solaris Linker and Libraries Guide). The alternative is to set LD_LIBRARY_PATH on a per-program basis, either as a wrapper program to the real program or a shell alias. Note however, that LD_LIBRARY_PATH may be inherited by programs called by the wrapped one ...
Add the directory to /etc/ld.so.conf
then run "sudo ldconfig" to make the changes take effect.
You can provide the directories to search for the libraries in as a parameter to gcc like so -L<directory_to_search_in>. And note that there can be multiple parameters to -L. Also, are you trying to build a 32-bit application or a 64-bit one?

g++ linking issues: undefined reference to functions

I used CMake and Visual C++ to build the HyDE library. Then, still in VC++, I was able to successfully create code and build an executable that links into HyDE.lib and the HyDE header files.
I then discovered that in order to work with others at my company, it would be preferable to develop in Eclipse CDT. Knowing very little about Eclipse CDT, I created a default hello world project, deleted the code and then dumped in all of my code into the src folder. Then I attempted to change the includes and lib path and libs to mirror what had worked in VC++. At this point everything seems to compile, but I get an error in linking:
/cygdrive/c/EclipseWorkspace/425HyDE/Debug/../src/FS5HyDE.cpp:16: undefined reference to `HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)'
(There are many more errors like this, all referring to HyDE methods.) Here is what is being run at the command line:
g++ -L"C:\Progra~1\boost\boost_1_42\lib" -L"C:\EclipseWorkspace\HyDE" -o"425HyDE.exe" ./src/Adapter_FS5HyDE.o ./src/EPSCommands.o ./src/EPSCurrentSensor.o ./src/EPSFault.o ./src/FS5HyDE.o ./src/HyDEObservation.o ./src/MCDH.o ./src/MCDH_Module.o ./src/PDBComponent.o ./src/PowerSystem.o ./src/Program.o ./src/SSPCComponent.o ./src/Telemetry.o ./src/TelemetryReport.o -l:libboost_thread-vc90-mt-gd-1_42.lib -lHyDE
This is definitely not a library ordering problem because I've the other ordering as well (there are only two). Is it possible that there is a problem with compiling HyDE.lib in VC++ (which uses a Windows compiler) and compiling my program with g++? Could there be a problem in the way that Eclipse CDT is autogen'ing the makefiles? Any other ideas?
(Note: there appear to be plenty of others questions on SO with similar problems, but after reading through them I have yet to find one that addresses my problem.)
Classic missing symbol error. Which source file defines:
HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)' ?
Was this file added to the compilation? Can you spot it on the command line you pasted?
If this symbol belongs to an external library, after adding the directory path with -L , you could add the name of the specific library you want to link with your program using -l.
I'm going to suggest that you try to add to the compilation command the directory path to HyDE.lib, followed immediately by the library name, like this:
-L"C:\path_to_hyde_library" -l:HyDE.lib
and then tell us what happened.
Solution: Since the HyDE library was compiled with the Visual Studios compiler and I'm attempting to build the code that links to it with the Cygwin toolchain the two compilers use different name mangling schemes so that the latter linker can not find the expected symbols in the HyDE library. The only solution that I've found is to recompile the HyDE library with the Cygwin toolchain or compile the new code with whatever compiler Visual Studios is using. (grumble grumble)
./src/FS5HyDE.o and ./src/HyDEObservation.o should be the latest parameter if other object files (*.o files) need them, it means that the most needed object files should be appeared as last as possible in the parameters list.

Linker options for Boost

I'm wondering if there are any simple ways to link boost libraries (all or individual) via some entry like....
-lSDL_ttf
The above links SDL's True Type Font library. Can this be done with boost? If so, I'm not sure what file I'm linking for to link. I'm currently using boost_1_40_0.
If this isn't possible, or there are better ways to do this, I'd be happy to hear them.
P.S. I'm using the CodeBlocks IDE.
Most boost libraries don't need to be linked as they are header only.
For those that are not header only, see the instructions here on the naming conventions and make sure you put the folder containing the boost libraries in your library search path if you want to avoid specifying it explicitly.
For Xcode 7, A few updates to this post:
a. Following installation instructions the following link, I placed the zipped file in /usr/local, resulting in an installation directory of:
/usr/local/boost_1_60_0
http://www.boost.org/doc/libs/1_60_0/more/getting_started/unix-variants.html
b. As stated on the above page, many of the Boost libraries are "header only." In other words, there is no library, and you don't have to link the libraries; there is nothing to link! If you try and link them, you will get an error! You just have to specify the header location, like so:
Of course, if you're using a Boost library that must be compiled, you may have to link it differently, but it's important to keep this in mind.
c. Be sure to check the permissions on the installation directory. I installed as root, and had to do a chmod 755 on the install, as show below. If permission are not set, you will get the generic and utterly unhelpful "library not found" error.