"loading shared libraries" error using VLFeat in C - c

I am trying to use VLFeat library in C, as given on the website
http://www.vlfeat.org/gcc.html.
I downloaded and installed the library. I use the glnxa64 architecture. The library is located at /A/B/C/vlfeat-0.9.18
My code is as follows:
extern "C" {
#include <vl/generic.h>
#include <vl/sift.h>
}
int main (int argc, const char * argv[])
{
VL_PRINT ("Hello world!") ;
return 0;
}
I compile my code using the following statement,
g++ main.cpp -o vlfeat-test -I/A/B/C/vlfeat-0.9.18 -L/A/B/C/vlfeat-0.9.18/bin/glnxa64/ -lvl
But when I run it, I get the following error
./vlfeat-test: error while loading shared libraries: libvl.so: cannot open shared object file: No such file or directory

When your program is loaded, linux loads the necessary libraries.
You need to create a symbolic link in /usr/lib/ to your libvl.so file
sudo ln -s /home/[YourPATH]/vlfeat-0.9.20/bin/[YourArchitecture]/libvl.so /usr/lib/libvl.so

Before running your test, in the same console:
export LD_LIBRARY_PATH=/A/B/C/vlfeat-0.9.18/bin/glnxa64:$LD_LIBRARY_PATH
then
./vlfeat-test

I think the problem is when your program load. Linux doesn't know where your vl library is.
copy libvl.so to /usr/lib
sudo cp [VLFEAT_PATH]/bin/[YOUR_ARCHITECTURE]/libvl.so /usr/lib

[This worked for same problem when using the .mex files through MATLAB in Ubuntu].
You may need to update the links and cache to the recent shared libraries by running
sudo ldconfig
You can permanently add the library path /A/B/C/vlfeat-0.9.18/bin/glnxa64 or a custom directory with your (links to) shared libraries, e.g., /home/username/lib in the ldconfig files:
sudo vim /etc/ld.so.conf
to add the line(s)
/A/B/C/vlfeat-0.9.18/bin/glnxa64
Verify by running
ldconfig -v | grep libvl.so

Related

How can I set an executable's rpath and check its value after building it?

I'm building the following file:
int main()
{
return 0;
}
with the following flags:
g++ -o main -Wl,-rpath,'$ORIGIN' main.cpp
but the rpath flag is doing nothing. When I execute the following commands:
objdump -x main | grep -i rpath
readelf -a main | grep -i rpath
I obtain nothing (RPATH is not defined).
What I'm doing wrong?
EDIT
I have tried to do the above with a different binary using the following cmake flags:
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "\$ORIGIN")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
I have moved the executable to a different machine, and placed a dynamic library that it needs to 'dlopen' in the same folder. It has worked (and I'm 100% sure this is because rpath, since before applying the above cmake flags the executable didn't worked).
Still, using the above two commands to check rpath (objdump and readelf) I still don't see anything.
If I didnt miss something here, you are not linking any libs in your build command.
Lets say you want to link libusb.so shared library, which is located in libusb sub-folder of your current folder where is main.cpp.
I will not take any details here, about soname, linkname of lib etc, just to make clear about rpath.
rpath will provide runtime linker path to library, not for linktime, cause even shared library need to be present(accessible) in compile/link time. So, to provide your application loader with possibility to look for needed library in start time, relatively to your app folder, there is $ORIGIN variable, you can see it with readelf but only if you link some library with $ORIGIN in rpath.
Here is example based on your question:
g++ main.cpp -o main -L./libusb -Wl,-rpath,'$ORIGIN/libusb' -lusb
As you see, you need to provide -L directory for compile/link time search, and rpath for runtime linker. Now you will be able to examin all needed libs for your app using readelf and location for search.

How to run c program with .so file

I have gone through all the solutions on StackOverflow as well as Ask Ubuntu.
I have a Go program:
package main
import "C"
//export Getint
func Getint() int {
return 2
}
func main() {}
and I have generated .so file for the same with name t.so and header filet.h`
Now I would like to use this function in my C program.
I have written the code but I don't know how to execute it.
#include <stdio.h>
#include <t.h>
int main()
{
int a;
a=Getint();
printf("number : %d",a);
return 0;
}
When I execute it with
gcc c.c t.so
it generates a.out file
but at the time of running a.out with ./a.out it gives an error:
./a.out
Error while loading shared libraries: t.so: can not open shared object file: no such file or directory exists.
then I tried with:
gcc -c c.c -l t.so
So it generates c.o file and it is not executable.
You should use the linker option -rpath, which tells the linker to add information in the executable program where to find runtime libraries like your .so file.
This can be done using the GCC option -Wl which instructs the GCC frontend program to pass an option to the linker:
$ gcc c.c t.so -Wl,-rpath=$(pwd)
This will pass -rpath=$(pwd) to the linker, and $(pwd) causes the shell to call the pwd command to return the current directory.
As long as you don't move the library the program should work.
You can use the environment variable LD_LIBRARY_PATH too, but it's not recommended.
Most probably your loader cannot find the library. Try to put the path to the directory where the libarry is located to LD_LIBRARY_PATH prior to run your binary.
export LD_LIBRARY_PATH=/path/to/my/library
./a.out
.so files are shared object, meaning object that are available to all applications that need them.. that is, shared. Due to this characteristics, they need to be stored in a well known place. Also, they need to be indexed by the dynamic linker.
In linux for instance you typically have a file /etc/ld.so.conf where all directories where shared object are automatically read from are stored
So your options are:
Put your shared object file in a well known place
Put your shared object file in a place of your choice and let the dynamic linker know about it: in linux you can modify ld.so.conf and run ldconfig to update ld indexes
As other suggested write the path of your .so in the env variable LD_LIBRARY_PATH (since dynamic linker reads it before running your application). This must be done at each environment creation
As other suggested use -rpath when compiling. Note that in this way you cannot move your .so file after the compilation
Personally I prefer installing the .so file in a system library path
You should use LD_LIBRARY_PATH to let the dynamic linker find your shared library in the list. Syntax is similar to PATH a list of directories separted by :.
On OSX this environment variable is called DYLD_LIBRARY_PATH.

Error loading shared library in C

I'm trying to use the command:
gcc -I${HOME}/usr/include -L${HOME}/usr/lib -lsodium test.c
but when I try and run a.out it gives the error:
./a.out: error while loading shared libraries: libsodium.so.4: cannot open shared object file: No such file or directory
but libsodium.so.4 is definitely in the ${HOME}/usr/lib directory. What's going on? test.c is just
#include <stdio.h>
#include "sodium.h"
int main(int argc, char** argv)
{ return (0); }
${HOME}/usr/lib is not in your runtime library path.
You can bake the path into your executable using the gcc option -Wl,-rpath,${HOME}/usr/lib or set the environment variable LD_LIBRARY_PATH=${HOME}/usr/lib before executing the program.
ldd a.out will tell you if libsodium can be found in your runtime library path, and if so, the location of the library.
You need to tell the runtime linker where to find the .so. Typically this is done with the LD_LIBRARY_PATH environment variable, so you would invoke a.out like so (assuming you're using a bash-like shell):
LD_LIBRARY_PATH=${HOME}/usr/lib ./a.out
Please
export LD_LIBRARY_PATH=${HOME}/usr/lib
first and try again.
That export ... will tell loader (ld-linux.so) also search ${HOME}/usr/lib for shared libraries.

How to compile C code using NDK for Android Device (ARM)?

I need to perform the following steps:
write a simple counter that keeps resetting itself after overflow in C/C++
compile and push that code into the phone via ADB
run it as a regular executable in background via ADB shell
how to compile the above C code using NDK toolchain? I found a couple of similar links but none of them give simple and complete steps to do so.
If there is a link with complete steps please do refer me to the same.
Compile Environment: Ubuntu, compile should be done via console not any IDE
You're right, I made a mistake, I had not even tested it and gave me the
same error, is due to the entry point of the "main", as this has not
changed but I hope this works for you. Anyway check the symbol table "nm",
the real-time execution "strace", you can even use gdbserver.
#include <stdio.h>
int main (int argc, char *argv[])
{
printf ("hello world");
return 0;
}
export NDK_ROOT=your_ndk_path
export PATH=$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin:$PATH
export CC=arm-linux-androideabi-gcc
export LD=arm-linux-androideabi-ld
arm-linux-androideabi-gcc -I$NDK_ROOT/platforms/android-18/arch-arm/usr/include -Wl,-rpath-link=$NDK_ROOT/platforms/android-18/arch-arm/usr/lib -Wl,-L$NDK_ROOT/platforms/android-18/arch-arm/usr/lib -Wl,-lc -o test test.c
If ld return with erros like "... ld: error: cannot open... : No such file or directory"
try this for your losed files:
ln -s $NDK_ROOT/platforms/android-18/arch-arm/usr/lib/crtend_android.o
ln -s $NDK_ROOT/platforms/android-18/arch-arm/usr/lib/crtbegin_dynamic.o
I use gcc4.8 and android API-level18
usin this you can try:
First way using command line.
export NDK_ROOT=your_ndk_path
export PATH=$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin:$PATH
export CC=arm-linux-androideabi-gcc
export LD=arm-linux-androideabi-ld
export CPPFLAGS=-I$NDK_ROOT/platforms/android-18/arch-arm/usr/include
export CFLAGS="-nostdlib" LDFLAGS="-Wl,-rpath-link=$NDK_ROOT/platforms/android-18/arch-arm/usr/lib/ -L$NDK_ROOT/platforms/android-18/arch-arm/usr/lib"
export LIBS="-lc"
arm-linux-androideabi-gcc -nostdlib -o test test.c
If run "file test" you should see this:
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
Second way using autotools.
export PATH=$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin:$PATH
./configure --host=arm-linux-androideabi CC=arm-linux-androideabi-gcc LD=arm-linux-androideabi-ld CPPFLAGS="-I$NDK_ROOT/platforms/android-18/arch-arm/usr/include" CFLAGS="-nostdlib" LDFLAGS="-Wl,-rpath-link=$NDK_ROOT/platforms/android-18/arch-arm/usr/lib/ -L$NDK_ROOT/platforms/android-18/arch-arm/usr/lib" LIBS="-lc"
make
http://embelinux.blogspot.com/2013/09/autotools1-hola-mundo-la-autotools.html
Third way using android developers ndk full feature.
Read Android.mk file syntax specification. This document describes the
syntax of Android.mk build file written to describe your C and C++ source
files to the Android NDK.
http://www.kandroid.org/ndk/docs/ANDROID-MK.html
gdbserver is to debug an application running on the Android device and can
control gdb from the PC using a TCP connection. gdb (The GNU Debugger)
need the debugging symbols.
When you compile an application the compiler puts all the symbols defined
in something called as symbol table, the problem was not link to rtbegin_dynamic.o,
crtend_android.o that if you specify -nostdlib option the program is created but no work (Table Simbol empty)
nm (list symbols from object files) eg: nm test
gcc is not a compiler, it is a driver that controls the execution
of other applications that are what make the job
for example try invoque the compiler using -### as unique option for see details
LDFLAGS: are the flags for the linker
CFLAGS: are the flags to the compiler (not links)
Anyway if you are new to the compilation, even in cross compiling strongly
recommend you use the Android.mk way
Sorry for my English ;)
#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#module name
LOCAL_MODULE := test
#src
LOCAL_SRC_FILES := test.c
#build executable
include $(BUILD_EXECUTABLE)
export PATH=path_to_ndk_root:$PATH
export NDK_PROJECT_PATH=.
ndk-build APP_BUILD_SCRIPT=Android.mk

How to solve "error while loading shared libraries" when trying to run an arm binary with qemu-arm?

I'm running Linux Mint 14 with qemu, qemu-user, and the gnueabi toolchain installed. I compiled test.c with arm-linux-gnueabi-gcc test.c -o test.
When I try and run qemu-arm /usr/arm-linux-gnueabi/lib/ld-linux.so.3 test
I get an error saying: test: error while loading shared libraries: test: cannot open shared object file: No such file or directory. Running qemu-arm test, as I've previously tried, gives /lib/ld-linux.so.3: No such file or directory
However, the file does exist and is reachable.
$ stat /usr/arm-linux-gnueabi/lib/ld-linux.so.3
File: `/usr/arm-linux-gnueabi/lib/ld-linux.so.3' -> `ld-2.15.so'
Size: 10 Blocks: 0 IO Block: 4096 symbolic link
Device: 801h/2049d Inode: 4083308 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2013-04-22 16:19:48.090613901 -0700
Modify: 2012-09-21 08:31:29.000000000 -0700
Change: 2013-04-22 15:58:41.042542851 -0700
Birth: -
Does anyone know how I can make qemu run an arm program without having to emulate an entire arm Linux kernel?
test.c is
#include <stdio.h>
int main() {
printf("this had better work\n");
}
and file test is
test: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0xf2e49db65394b77c77ee5b65b83c0cc9220cbfc0, not stripped
you can run the example by providing a path to the arm-linux-gnueabi shared libs using the -L flag.
qemu-arm -L /usr/arm-linux-gnueabi/
also make sure the LD_LIBRARY_PATH is not set.
unset LD_LIBRARY_PATH
$ export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi
This works for me.
It's basically the same thing as:
$ qemu-arm -L /usr/arm-linux-gnueabi/
You can add it to the ~/.bashrc file so you don't have to type it everytime you open the terminal.
I also met this problem when running a C program with assembly code. My solution is to build the executable with the option "-static", for instance
arm-linux-gnueabi-gcc -static -g main.c square.s
Then
qemu-arm a.out
will not report the error saying "can not find the /lib/ld-linux.so.3".
The only drawback is that the executable could be with a large size. But it's helpful when you just want to test your code.
Of course, you can go with the method from Balau(see artless noise's answer). But if you don't want to feel frustrated by something like "UART serial ports" in this step, which is only to run a simple "test" function, go for a try of my fix.
I solved the problem by copying the following libraries into /lib but I believe there should be a way better solution rather than this nasty solution I invented!
sudo cp /usr/arm-linux-gnueabi/lib/ld-linux.so.3 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libgcc_s.so.1 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libc.so.6 /lib
Please let me know if there are other better solutions as I am interested to know.
If you want to run ARM without Linux, then you need a different compiler (at least). arm-linux-gnueabi-gcc is a compiler for Linux. The compiler and libc are intimately linked. You will need a newlib compiler with a portability layer for qemu.porting newlib
See: Balau and Google newlib+qemu. A newlib port is hosted at Github and seems to the same as the Balau blog.
Typically a non-Linux gcc is called arm-none-eabi-gcc. The prefix arm-none-eabi- is recognized by some configure scripts.
A variant, which worked for me, was to pass the loader library directly and to specify the required library paths using the loader parameter --library-path. For example:
$ TOOLCHAIN_ROOT=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/arm-linux-gnueabihf
$ qemu-arm $TOOLCHAIN_ROOT/libc/lib/ld-linux-armhf.so.3 --library-path $TOOLCHAIN_ROOT/libc/lib/arm-linux-gnueabihf:/$TOOLCHAIN_ROOT/lib ./my_executable
Or equivalently export LD_LIBRARY_PATH instead of using --library-path.

Resources