Creating shared object files from existing libraries - java-native-interface

I'm using linux (Ubuntu) and trying to create a shared library (.so) from C code for use with the Java Native Interface (JNI). When using simple C code I can do this with the command:
gcc -shared -fpic -o Wrapper.so -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -I/usr/lib/jvm/java-7-openjdk-i386/include Wrapper.c
However, when I try to incorporate existing libraries into the C code such as:
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_debug.h>
I get an undefined reference error for the methods from these libraries. I've tried giving a path the directory with the shared object files for the library are located using the -I flag with no success.
Should I be trying to link with the header files or the shared object files (.so) and which directory should these files be in?
What tool/command should I be using to generate the required shared library for use with JNI?

I've tried giving a path the directory with the shared object files for the library are located using the -I flag with no success.
Naturally: the -I flag isn't about any libraries. Please read the GCC man page.
Should I be trying to link with the header files or the shared object files (.so) and which directory should these files be in?
You can't link with header files. You can only link with object files, and archive or shared libraries.
Assuming your DPDK is installed into /home/user/DPDK/{include,lib} your command line should look something like:
gcc -I /home/user/DPDK/include ... -shared -fPIC -o Wrapper.so \
Wrapper.c -L /home/user/DPDK/lib -lrte_eal
If the librte_eal is built as a shared library, you will likely need -Wl,-rpath=/home/user/DPDK/lib as well.

Related

g++ trying (failing) to link statically to libstdc++ for shared object

I'm trying to create a shared object using a number of .O files created with the -fPIC command. When I run g++ with the -shared argument it appears to be trying to statically link to the libstdc++.a library, which of course fails. I'm trying to figure out why it's automatically trying to link statically when I'm not using the -static-stdc++ argument.
when I try creating the shared object I get the error ...libstdc++.a(ios) relocate R_x86_64_325 against 'vtable for std::ios_base': cannot be used when making a shared object
I ran G++ with the -V argument and received and can see LD receives the argument -lstdc++.
When linking together a single shared object, you need to do this from existing .o files. You can not do this from existing .so files; this would link those .so files to your .so file, but not into your .so file. So gcc seeks out and finds an archive of .o files (.a) and tries to link them. But since those are not compiled for relocation (no -fPIC), these can not be used to create .so files.
Your options are:
dynamically link your .so to the libstdc++ (and thus make it depending on the .so file that is installed in the system)
build .o files for libstdc++ and compile them with -fPIC then compile from those your .so file (here it does not matter if you use the .o files directly or an ar archive)
For the first (that I would recommend) option the following will suffice (it is from a makefile that I use for creating malloc/free intercepting .so files)
gcc -shared -lstdc++ -o your.so yourfiles.o
I'll bet it's finding the static library first in its library search path, or ONLY finding the static library. Make sure that the appropriate version of the shared version is installed and can be found. You can probably truss your g++ run to hunt down the order in which it's opening libraries.

Making a shared library from existing object files

I have a project in my IDE. I need to make a shared library of it to use in extensions. I don't want to make a copy of this project with shared-library settings. Is there any way to build a shared library using the object files (.o) from my already existing project? As I understand, I can write a makefile for this.
I assume you're on some sort of Unix and are probably using the GNU toolchain. In that case, to create a proper shared library, you'd need to compile your code using the position-independent code flags (-fpic or -fPIC) before you can create a shared library. Unless your .o files are already compiled with those flags, chances are you won't end up with a working shared lib.
If they already are compiled for position independent code, the usual g++ -shared ... should do the trick.
g++ -shared -fPIC -o myshared.so *.o

How to install and use libtool shared library (.lo files)?

So after I ran libtool and got out a libfoo.lo and foo.o file from my library source, how do I convert the libfoo.lo file into a normal Linux shared library, like libfoo.so.1.0.0 so I can install and link to it on my target system?
From the outputs mentioned in the question, it looks like you ran libtool with --mode=compile mode. You will need to run libtool again with --mode=link to produce .a and .so libraries.
libtool is just a simple wrapper for gcc, ln ar and ranlib which is needed to produce libraries. All it does is run gcc adding the necessary options to ensure that your static and shared libraries are created correctly.
When compiling libtool inserts the -fPIC tag to ensure the necessary generation of position independent code needed for shared libraries. The .o files are normal object files that can be archived into a static .a file. The .lo files are object files with position independent code which can now be linked into a .so file.
When linking libtool will run ar to create a static library or ln to link the objects files into a .so shared library.
libtool also can install the library when desired using the --mode=install.
See http://www.gnu.org/software/libtool/manual/libtool.html for more info.
Please remember that when building an executable there are always two stages, compiling and linking.

xerces-c 2.8 : error while loading shared libraries

I'm trying to compile a program running on an HP UX server on a Red Hat Linux.
It uses xerces-c library to parse xml files. Compilation is ok, but when i try to run it, I get the following message
./a.out: error while loading shared
libraries: libxerces-c.so.28: cannot
open shared object file: No such file
or directory
I wrote a very simple program to try and understand whats going on:
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/TransService.hpp>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
int main(int argc, char* argv[])
{
return 0;
}
And compiled it like this:
g++ test.cpp
-L./xml/xerces-c_2_8_0/lib -lxerces-c -I./xml/xerces-c_2_8_0/include
Surprisingly the file is actually there:
lib]$ ls
libxerces-c.a libxerces-c.so.28 libxerces-depdom.a libxerces-depdom.so.28
libxerces-c.so libxerces-c.so.28.0 libxerces-depdom.so libxerces-depdom.so.28.0
Any thoughts ? I feel i'm missing something, but don't know what.
Thanks in advance.
run ldd a.out and see if the linker can resolve the right .so file
export LD_LIBRARY_PATH to include the current folder (in the same manner as the PATH variable) and check ldd again
the good way to do what you want is the following one:
g++ test.cpp -Xlinker -R ./xml/xerces-c_2_8_0/lib -lxerces-c -I./xml/xerces-c_2_8_0/include
or
g++ test.cpp -Wl,-rpath ./xml/xerces-c_2_8_0/lib -lxerces-c -I./xml/xerces-c_2_8_0/include
Xlinker or Wl options allow you to use specific linking options, you do not need to modifiy
LD_LIBRARY_PATH
You need to tell the runtime c library where to find the various symbols that arent compiled statically in your code and arent in the usualy /lib and /usr/lib locations.
You do this by adding the path to your shared library to LD_LIBRARY_PATH. In this case, this will be what you have been putting for the -L argument to the compiler.

How to link using GCC without -l nor hardcoding path for a library that does not follow the libNAME.so naming convention?

I have a shared library that I wish to link an executable against using GCC. The shared library has a nonstandard name not of the form libNAME.so, so I can not use the usual -l option. (It happens to also be a Python extension, and so has no 'lib' prefix.)
I am able to pass the path to the library file directly to the link command line, but this causes the library path to be hardcoded into the executable.
For example:
g++ -o build/bin/myapp build/bin/_mylib.so
Is there a way to link to this library without causing the path to be hardcoded into the executable?
There is the ":" prefix that allows you to give different names to your libraries.
If you use
g++ -o build/bin/myapp -l:_mylib.so other_source_files
should search your path for the _mylib.so.
If you can copy the shared library to the working directory when g++ is invoked then this should work:
g++ -o build/bin/myapp _mylib.so other_source_files
If you are on Unix or Linux I think you can create a symbolic link to the library in the directory you want the library.
For example:
ln -s build/bin/_mylib.so build/bin/lib_mylib.so
You could then use -l_mylib
http://en.wikipedia.org/wiki/Symbolic_link