Here is a Hello World code in C:
// a.c
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
I compile it as gcc a.c
, which produces a.out
as expected and ./a.out
prints Hello world
... as expected.
Now if I do the compile and link separately:
gcc -c a.c; ld -lc a.o
, it run the a.out
produced as ./a.out
I get the message:
bash: ./a.out: No such file or directory
I Googled that error and it seems that happens when the executable produced is a 32-bit ELF and the machine architecture is 64-bit.
I'm running a 64-bit machine and running file a.out
gives:
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Why does this happen?
EDIT:
Output of uname -m
$ uname -m
x86_64
Output of ldd a.out
$ ldd a.out
linux-vdso.so.1 => (0x00007ffeeedfb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa13a7b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa13abab000)
gcc a.c
produces a.out
which runs correctly.
First, make sure you execute the program with the correct path. If you make a typo on the directory or file name, you will get this error or give the wrong path. If you are executing the file with a relative path ( ../../file ), try executing with the absolute path ( /path/to/file ) instead.
The error "FileNotFoundError: [Errno 2] No such file or directory" is telling you that there is no file of that name in the working directory. So, try using the exact, or absolute path. In the above code, all of the information needed to locate the file is contained in the path string - absolute path.
You can resolve this issue in three ways: First, use the full path of the executable file to launch the program. Second, add the program path to Windows environment variables. Finally, move the files to the System32 folder.
ld -lc a.o
There are several things wrong with this command line:
In general, user-level code should never use ld
directly, and always use appropriate compiler front end (gcc
here) to perform the link.
As you have discovered, the link command line that gcc
constructs is quite complicated, and the command line that you've accepted in Joan Esteban's answer is wrong.
If you want to see the actual link command, examine output from gcc -v a.o
.
Also note that link command changes significantly when you change gcc
command only slightly (e.g. some OSes require different crt1.o
depending on whether you are linking multi-threaded executable or not), and the command line is always OS-specific (which is one more reason to never use ld
directly).
Libraries should follow object files on command line. So ld -lc a.o
is never correct, and should always be (a variant of) ld a.o -lc
. Explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With