Using library files in Linux - c++

I'm trying to use some of the functions that are in the /lib/libproc-3.2.6.so library in my Ubuntu distribution.
I have downloaded and installed the header files and they are defined in my source files.
Currently, this is all I'm trying to do, just for starters...
proc_t **read_proc = readproctab(0);
But I get the following compiler error:
/tmp/cclqMImG.o: In function `Sysmon::initialise_sysmon()':
sysmon.cpp:(.text+0x494): undefined reference to `readproctab'
collect2: ld returned 1 exit status
I'm aware I'm probably doing some wrong with the command I'm using to compile it, but due to lack of experience I'm not sure what I'm doing wrong. This is the g++ command I'm using to compile my cpp file:
g++ -o sysmon.o sysmon.cpp `pkg-config --libs --cflags gtk+-2.0`
Can someone please give me some pointers as to where I'm going wrong.

You are not linking your executable against libproc (that is a linker error message).
Try adding -lproc to the linker command.

You are not actually linking against the library that you wish to use, you are merely including its header files, therefor, the compiler will complain about undefined references.
You can read up on linking against shared libraries here.
A small suggestion, start using the build tool SCons, it can take care of linking to libraries for you, just add the ones you wish to use in the SConstruct file required by SCons and then you don't have to mess about with compiler specifics. You also gain lots of other good stuff that SCons provide. It's highly recommended.

Ubuntu 17.04
You probably want to use -lprocps instead of -lproc.

Related

How to correctly set GSL path on mac

I have 'correctly' installed gsl on mac 10.13.2.
In my c++ program, I am calling like usual, for example:
#include <gsl/gsl_math.h>
However while running the code, it can not find the gsl.
fatal error: 'gsl/gsl_math.h' file not found
I was wondering how to correctly link gsl PATH and libraries.
I have tried,
setting PATH and LD_LIBRARY_PATH in .bash_profile
setting PKG_CONFIG_PATH to .../Gsl2.3/lib/pkgconfig
$which gsl-config returns
/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/bin/gsl-config
$pkg-config --libs gsl returns
-L/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/lib -lgsl -lgslcblas -lm
The only solution I can find is to run everytime with gsl linked.
Like:
g++ $(gsl-config --cflags) mycode.cc $(gsl-config --libs) && ./a.out
But I was wondering if the GSL PATH can be set globally so that I can simply run
g++ mycode.cc && ./a.out
This is how c++ code is compiled and built:
COMPILATION
A compilation unit will take each cpp file and work its way through included headers to locate forward declaration of implementations of symbol signatures of used functionality in your code. In your case this involves gsl/gsl.h. If the file cannot be found in the search directories, which you can expand by specifying C_INCLUDE_PATH and or CPLUS_INCLUDE_PATH. If you omit #include <gsl/gsl_math.h>, your code will not compile as there are signatures, which cannot be found for GSL functions, which you use.
LINKING
Once you have compiled all cpp/cc files you need to link the binary, which can be executed. The linking process consists of a search through all symbols in your .o/.obj... files and a matching of the same to what it can find in your object files and the libraries, which you have specified using for example -lgsl. If all goes well, every lookup finds an according binary implementation for your machine's hardware model (i.e. 64bit/32bit ..., Arm, Intel, ... etc). If some are not found you will find linkage errors.
What you are asking is, is there a way that C++ does not work as above? No!
If you leave out #include <gsl/gsl.h> or if said file is not found in your search paths, compilation will not work or. If you omit -lgsl, linking will fail. If you find it annoying to write all the above stuff in the command line, write a Makefile to reduce the building process to ideally a simple command: make.
Don't forget, that if you are linking against the shared library version of GSL, you might need specifying LD_LIBARAY_PATH on Linux and DYLD_LIBRARY_PATH on Macs as well.
TLDR: you cannot ask a c++ compiler / linker to work differently as designed.

undefined reference to `JNI_CreateJavaVM' in voce.h

I am trying to make a program that can detect speech so I downloaded voce to help with it. After I have included all packages I get the error undefined reference to 'JNI_CreateJavaVM'. I searched on it and and I found no solution that worked.
I use Code::Blocks IDE and GNU GCC as compiler.
It sounds like you have not compiled it using the required linker information.
To do this after the other compiler options you need to add something like :
gcc -o myapp -I<path-to-jni-include-files> myapp.c -L <path-to-libjvm.so> -ljvm
The -L tells the linker ( the compiler passes these options to the linker for you ) where to find the shared libraries it needs, and the -ljvm tells the linker to actually expect references the libjvm.so shared library ( as it would be called on Linux ).
Note that current gcc versions require the linker options at the end of the command line. Once upon a time you could place them in any order you like. Now they must be at the end.

Linking errors when trying to compile Fubi

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.

Problems trying to compile a program with external header

I'm learning c++ and I'm trying to use a library that I've downloaded from internet in my program ( from here https://mattmccutchen.net/bigint/).
Because I want everything to be quite tidy, I put all the .hh files in a subfolder named "BI".
However when I try to compile my .cpp file with g++ (It's MinGW on Windows XP SP3), the compiler outputs the following error:
J:\comp proj\FS>J:\Programmi\MinGW\bin\g++.exe "J:\comp proj\FS\test.cpp" -o "J:\comp proj\FS\test.exe" -I "J:\comp proj\FS\BI"
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text+0x2c): undefined reference to BigInteger::BigInteger(int)'
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text+0x11b): undefined reference tooperator<<(std::ostream&, BigInteger const&)'
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text$ZNK10BigIntegermlERKS[BigInteger::operator*(BigInteger const&) const]+0x29): undefined reference
to `BigInteger::multiply(BigInteger const&, BigInteger const&)'
collect2: ld returned 1 exit status
I've tried using the -I, -l and -L switches to fix the problem but with no success.
Moreover I've tried in the cpp to put #include "BI/BigIntegerLibrary.hh" but that didn't work.
Is there something I'm doing wrong?
Thanks in advance.
You need to use both -L and -l switches. -L to point to the directory containing the library binary, -l to name that binary
e.g. -L/home/ed/libs -lmath
There's two keywords to keep in mind. Undeclared means the compiler has never heard of it. Undefined means the compiler has heard of it, but doesn't know exactly how to use it. For those errors you need to tell it to link with the BigInteger library that should have come with the headers (A *.lib file) I'm hot sure exactly how gcc includes link libraries (Ed Heal says -L and -l, I'd do that).
Your problem is that you didn't link with the library code.
Read the "README", then follow its advice to adapt the enclosed Makefile.
Ok, so after some messing around I figured out that I needed to do a couple of things
add the -L switch with the dir of the header files
add to the g++ command line all the .cc files (e.g. g++ test.cpp BigInteger.cc etc.)
put everything in a batch file for semplicity
wow, now it seems quite easy!

g++ relative paths

I'm attempting to design a shared library of shared libraries using g++ with hopes of simplifying my compile scripts and easing my update process in the future, but I'm still novice at best with GNU tools and writing libraries, at that. Can anyone provide advice on whether the following idea is possible with g++?
For convenience, consider the following file system layout:
main.cpp
libraryX/
libraryX/libX.so
libraryX/libraryY/
libraryX/libraryY/libY.so
libraryX/libraryZ/
libraryX/libraryZ/libZ.so
My goal is to be able to link indirectly using cascading relative paths. For instance, main.cpp links to libraryX/libX.so, which links to libraryY/libY.so and libraryZ/libZ.so. Is it possible to only link main.cpp to libX.so and use functions defined in libY.so and libZ.so?
If so, could you provide an example of the flags one would need to do so? I've been trying variations of the following command using various sources from Google to no avail:
g++ -shared -fPIC -Wl-rpath=libraryX -LlibraryX -lX.so main.o -o executable
Any guidance or references are greatly appreciated.
Don't do this (even if you can figure out how).
When you link against -lX, the static linker must know all other shared libraries that are "part of this link". Since -lY is not on the link line, the static linker will either give you an error, or it must somehow figure out where libY.so is coming from. For the latter, it has to replicate the RPATH search that the runtime loader will perform. This replication is error prone (the static linker may not use the exact same algorithm) and best avoided.
Finally, your command line is totally wrong: -shared means you ask the linker for a shared library, but you are clearly trying to link an executable. You generally should not use -fPIC when linking an executable. Also, -Wl-rpath=... should be -Wl,-rpath=... (the comma is important).