if not gcc -static then shell says 'no such file' - linux

I do not know why, but the (Android ADB) shell says no such file or directory when I compile with arm-linux-gnueabi-gcc without the -static option, and then attempt to execute the native executable. This is the no such file or directory you get when the shell knows the file exists at that path, but doesn't want to give the user permission to know the file exists. (e.g. you can check with chmod 4755 which returns no error message).
If I compile with the -static option then the program executes normally.
Why does this happen when compiling without the static option?

if you link statically everything the program needs will be built in. There are no
dependencies to libraries on your device, so it will run perfectly. Bad is the size
of this programming style (huge)!
If you leave out the -static your compiler assumes dynamic linking, but without some
magic you link against (Linux)-glibc: crash!
Search for "native C on Android" tutorial on the net, please. They explain all
the (horrible) linker-stuff you nee to link against Android)-glibc aka "Bionic".
Good luck
may the sources be with you
Martin

Related

Linux randomly deleted my file while compiling what do I do?

gcc -L/root/Desktop - Wall -o prog3.c -pthread -lcopy
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.0: In function '_start': (.text+0x20): undefined reference to 'main'
collect2: error: ld returned 1 exit status
This is my error code. prog3.c is nowhere to be found, what on earth happened is there any way to get my file back?? The bold is the command I ran and the rest is the resultant console output
Your problem is here: -o prog3.c. gcc’s -o option is used to tell gcc which name it should give to the executable it generates. So here, you’re basically asking your compiler to replace your prog3.c source file by an executable. Sadly your code is gone...
Little addendum of your options in such scenario:
It was Git (or any other version control) repository. In such case, you can simply bring it from previous commit
Your editor/IDE has some back-up system. Sometimes I need to bring back a file I've thought was needless. For such case, my favourite text editor should have create already back-up file in appropriate location (e.g. $XDG_DATA_HOME/vim/backup in my case).
If none of above, but you still have previously correctly compiled binary file
You can try to decompile, but this process - even if successful - isn't lossless (e.g. code is basically spaghetti).
Had you compiled with -g flag, you could possibly retrieve the code from debug info.
You can at least de-assemble to Assembly code.

Bash command: export BLAS_LIBS="-L$LAPACKHOME/lib -lblas"

Can any body explain to me what does the whole sentence mean?
I know this is to set Macro BLAS_LIBS as another string.
But I'm not sure what's the "-lblas" mean and I don't know how to use it.
Similar as the following code. "-llapack"
export LAPACK_LIBS="-L$LAPACKHOME/lib -llapack"
How can the program find out the BLAS and LAPACK libraries just by "-lblas" and "-llapack" ?
Thanks for advance.
I'm not sure why you say "just by -llapack" because that's not what is happening here. Specifically, the -L option just before it specifies a directory path to add to the library resolution path. This works roughly like PATH in the shell.
For example, with the command line fragment gcc -Lfoodir -Lbardir -lfoo -lbar, you basically instruct the linker to search the directories foodir and bardir for the library files libfoo.a and libbar.a.
The -l option is described in GCC: Options for Linking and -L and friends in the following section GCC: Options for Directory Search.
This build arrangement -- configure the build to show where the required files are before compiling -- is common for libraries, where if a user has already downloaded and compiled a required library for some other project, they don't need to rebuild it; they can just point the compiler to wherever they already have the stuff needed for this project.
Building your own libraries is becoming increasingly unnecessary anyway, as prepackaged binaries of most common libraries are available for most systems these days. But of course, if you are on an unusual platform, or have specialized needs which dictate recompilation with different options than any available prebuilt binary, you will still need to understand how to do this.

dlopen failed: cannot open shared object file: No such file or directory

The problem is I use dlopen to load a library (the .so is written by me, it's not a system library), but I got the error shown in the title.
I have included dlfcn.h
in compiler, I used the -ldl command
What I want to load is just the source code folder, I tried to add -L., but it did not work.
The most brutal and effective way to find out where your code goes wrong is the following command which will activate the debugging mode for shared libraries and is documented here:
export LD_DEBUG=libs
Then, you will be surprised that so much information pops up. Don't worry, these information tells you which shared libraries the command you just typed needs and where to locate these needed libraries. For example, if you type reset, the screen will be reseted and then information about the shared libraries reset command needs will be printed.
Then, execute your "problematic" executable to see what's going wrong.
PS.1 : According to your accepted mythagal's solution :
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
It seemed that even though you use absolute or relative path in the dlopen function, the directory not found error will still show up. I am using CentOS, and my Debian is also having this problem. So I think the first solution mythagal provide is wrong. You can verify that in the "debugging" mode I mentioned above.
PS.2: If you "install" or "compile" a shared library rather than install it through package manager, you MUST run sudo ldconfig /path/where/not/found/shared/library/reside to notify the system of the newly added shared library. For example :
cp /etc/ld.so.cache ~/ld.so.cache.backup
#cp -r /etc/ld.so.conf.d ~/ld.so.conf.d.backup #sometimes this backup is unnecessary.
#cp /etc/ld.so.conf ~/ld.so.conf.backup #sometimes this backup is unnecessary.
sudo ldconfig /PATH/WHERE/NOT/FOUND/SHARED/LIBRARY/RESIDE
###I am omitting the cp commands to roll back.
###For example, sudo cp -f ld.so.cache /etc/ld.so.cache
To understand what's going on here, please carefully read all the contents in the link above.
PS.3 : You can always use the command export LD_DEBUG=help,export LD_DEBUG=libs to figure out how -rpath or LD_LIBRARY_PATH solve your problem. You will love this debugging mode.
PS.4: A less brutal way to figure out what's going wrong:
ldd ./YOURproblematicEXECUTABLE
This command can tell you whether your shared library to be opened is located or not. Besides, there are so many ways to fix your problem and each way has its limitation and application. So I strongly suggested you read the link I provide you above and understand how to choose the way to solve your problem. After reading that, if you actually feel like being very "OK", you can also read this Better understanding Linux secondary dependencies solving with examples for deeper understanding.
If the library you want to dlopen is not in the standard search path you have a number of options:
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
Add the path to the library via LD_LIBRARY_PATH
LD_LIBRARY_PATH=/path/to/library/ ./executable
use the ld -rpath option to add a library path to the application.
g++ -link stuff- -Wl,-rpath=/path/to/library/
Note that options 1 & 3 hardcode the library path into your application. -rpath does have an option to specify a relative path, i.e.
-Wl,-rpath=$ORIGIN/../lib/
Will embed a relative path into the application.
the dlopen's declaration look like,
void *dlopen(const char *filename, int flag);
if you set the para 'filename' as shared library's name , you should add you current path into the 'LD_LIBRARY_PATH'.for instance,
1, dlopen("libtest.so" , RTLD_LAZY)
2, in shell , export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
For my case, the solution was very simple:
The path is expected to be absolute unless clearly specified as relative
So I replaced
dlopen("mylib.so", RTLD_NOW)
with
dlopen("./mylib.so", RTLD_NOW)
And the problem solved.
I would recommed dlerror to get the reason
void* handle = dlopen(SO_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if(handle == NULL)
{
printf(LOG_ERROR, "Error: %s\n", dlerror());
assert(0);
}
this will report detailed reason for the error

How to run a *.o file in Android

I currently compiled a set of source code in C in Linux and the output is a *.o file which is a object file. This supposedly does image compression. Now I want to use/test this in Android.
Is this possible? I have only tried NDK examples from the Android NDK developer side. Have not came across any reference on how this can be done.
Thanks In Advance,
Perumal
You don't run object code files (*.o). You would need to turn it into an executable. To do this, assuming you are using GCC you would run gcc file1.o file2.o -o executable which would convert a two file program with file1.o and file2.o into an executable called executable.
Object files (ending in .o) usually contain code that is incomplete. For example, if your program uses some library to print something on screen, to produce an executable, you must link your compiled code (the .o file) with the library, so that when the operating system loads the executable knows all the code that will be used. You do this linking with a linker (such as ld in Linux, or /system/bin/linker in Android). In your case, it's easier to let gcc call the linker for you, as Jalfor notes.
The answer is Yes. But you have to do some fair amount of work to see it running on Android.
1) If you are compiling on Linux, it means the object file or the final executable is being built for the x86 or AMD processor(Mostly). But mostly all the mobile devices have ARM processors running on their phones. So, though you have an executable you will not be able to execute it in ANdroid if it is not built for ARM Cpu. This is what android NDK does exactly.
2) So, we have to build the same code again for Android(ARM), for which we need a cross-compiler and the source code of the object files you are talking about.
3) If you have source code avilable, you can do 2 things again.
To include it in JNI folder, build the shared library and then do the
stuff of calling and all.
Build the code into an executable(Note you need to have main
inside the code) using the android NDK and then push the executable inside Android using
adb.
Now finally you can login and then check the result. In case anything is not clear, please do let me know. I wont mind explaining. Thanks..

passing library argument to gcc

I've a shell on a system without root privileges. I am trying to use a custom library for my new project and it cannot be installed onto the system because I don't have the root privilege. I'm building the library from source. Making the '.o' from the sources has been done. I've tried passing the '.o' file, generated after building the source, as the library argument (-l) to gcc , but gcc says file not found. Any possible workarounds for this?
Just pass the .o as an extra bit just like the rest of your program.
gcc <library.o> <yourprogram.o> -o <executable>
gcc -L/path/to/library/directory
LD_LIBRARY_PATH=/path/to/library/directory:$LD_LIBRARY_PATH ./a.out

Resources