When running a compiled GCC file in the terminal, nothing happens - c

I have Ubuntu 64 bit installed, and when I compile C files using the flags:
gcc -g -m32 -ansi -Wall -c -o *.o *.c
it compiles the files, but when I try to run them in the terminal, nothing happens.
So I decided to try to compile and run just one simple file without a makefile, with the following code:
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
The compilation succeeds but when I try to run the file I get nothing...
Note: I already tried to install lib32gcc1, libc6-i386, and g++-multilib.
How can I fix this problem?

Replace -o *.o by -o programname. The -o parameter receives the executable name of the program you're generating. And here is gcc manual:
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Overall-Options.html#Overall-Options

For a simple test, leave every option out:
> cat test.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
> gcc test.c
> ./a.out
Hello World
and see if that works.

Let us assume you (already) have two object files a.o and b.o, their corresponding source file a.c and b.c and some common header ch.h; then your (incorrect) command line
gcc -g -m32 -ansi -Wall -c -o *.o *
might be expanded as:
gcc -g -m32 -ansi -Wall -c -o a.o b.o a.c b.c ch.h a.o b.o
(actually, that would be even worse, e.g. if you have some Makefile or some backup files from your editors like a.c~, as remarked by William Pursell)
which would compile but not link, the files b.o a.c b.c ch.h a.o b.o which does not means much.
You should understand that the shell is expanding first the arguments before executing any gcc program (in a new process). To understand what is expanded, consider replacing gcc by echo (or by gcc -v which would show what is really happening)
Then, you should read the GCC documentation about invoking GCC
Actually, you need to spend several hours in reading, e.g. Advanced Bash Scripting Guide (which does have some mistakes perhaps) and Advanced Linux Programming. Several wikipedia pages could also be useful to read.

Related

Unable to identify issue GNU archiver. Compiling with *.o works but libname.a dosen't

I'm trying to make a static library (.a) but facing issues that I'm unable to understand. So in brief compiling with *.o succeeds but archiving them using ar and then using the .a file to compile gives me an undefined reference to 'symbol' error.
So here is a simple code.
test.c
#include <stdio.h>
#include <string.h>
int main()
{
hello_world();
return 0;
}
hello_world.c
#include<stdio.h>
void hello_world (void) {
printf("Hello World\n");
}
Compile.
gcc -c -o hello_world.o hello_world.c
ar crs libhello.a hello_world.o
gcc libhello.a -o test test.c
gives me the error
/tmp/ccsO7AJl.o: In function `main':
test.c:(.text+0xa): undefined reference to `hello_world'
Instead doing this works(Compiles and runs fine)
gcc -c -o hello_world.o hello_world.c
gcc hello_world.o -o test test.c
I have no idea what I have done wrong so any help is appreciated.
This is an almost duplicate of Why does the order of '-l' option in gcc matter? - but the behaviour can be replicated without the -l switch by specifying the archive name on command line.
The GNU linker as executed by GCC will, by default, link from left to right, and only use those .o files from the library archive that are needed to satisfy undefined references so far. Since your library precedes the main translation unit on the command line, hello_world is not required at the time the linker is processing it.
The solution is to mention the library after the translation units/object files that depend on it:
gcc -o test test.c libhello.a

Cannot find -lCommunication collect2: error: ld returned 1 exit status

I do not know gcc and c well. In my /home/pi/Desktop/intern/adis16227_generic directory I have following 5 files.
ADIS16227.c
ADIS16227.h
Communication.c
Communication.h
main.c
main.c
#include<stdio.h>
#include "Communication.h" // Communication definitions.
int main() {
printf("hello!!\n");
unsigned char status = 0;
status = SPI_Init(0, 1000000, 1, 1);
printf("%u", status);
return 0;
}
Run command:
$ sudo gcc -L /home/pi/Desktop/intern/adis16227_generic main.c -lCommunication
Error:
/usr/bin/ld: cannot find -lCommunication
collect2: error: ld returned 1 exit status
Question:
What I am missing here?
What do I need to run the code?
-l is for libraries, and you never built a library from your Communication.c. The simplest solution is just add Communication.c to your compiler command line.
For larger projects, compile each translation unit separately with the -c switch like this:
gcc -c -Wall -Wextra -pedantic -omain.o main.c
gcc -c -Wall -Wextra -pedantic -oCommunication.o Communication.c
and so on ... (as a suggestion, I added some common warning options here, they help you spot errors)
The resulting .o files are object code. That's already compiled machine code, but with meta-information needed for a linker to link it with other object code into a complete executable.
Then link them all with one command:
gcc -oprogram main.o Communication.o
If you actually want a library from -- say -- Communication.c and ADIS16227.c, you could compile both to object code:
gcc -c -Wall -Wextra -pedantic -oCommunication.o Communication.c
gcc -c -Wall -Wextra -pedantic --oADIS16227.o ADIS16227.c
and then use ar to create a static library from them:
ar rcs libCommunication.a Communication.o ADIS16227.o
Then your initial compiler command would work (with the -lCommunication switch).
Final piece of advice: Never compile as root. This is completely unnecessary. So remove your sudo here.
those options:
-L /home/pi/Desktop/intern/adis16227_generic -lCommunication
suggest that the linker should find libCommunication.a (or .so) in the /home/pi/Desktop/intern/adis16227_generic directory.
But there are only sources in this directory. The linker won't build the sources of your "Communication" library for you.
So you could build the library and link with it:
gcc -c ADIS16227.c Communication.c
ar r libCommunication.a ADIS16227.o Communication.o
but maybe the fastest & quickest way to achieve a successful build would be:
sudo gcc -o main *.c
so it compiles all the files of the directory into the executable called main
Of course, it makes compilation times longer, but maybe it's not noticeable.
First move into the /home/pi/Desktop/intern/adis16227_generic directory:
cd /home/pi/Desktop/intern/adis16227_generic
Then, compile the source:
gcc ADIS16227.c Communication.c main.c -I .
You can now run your compiled program (called by default a.out):
./a.out
You have to compile separatedly files and then compile main with related obj file.
gcc -c Communication.c Communication.h
gcc main.c Communication.o -o main

I cannot run a ELF-format program .The shell tells me no such file or directory

My environment is Ubuntu 14 32bits.
I write three c files called main.c,foo.c,and bar.c respectively.
the codes are very simple.
The first source code is main.c
#include<stdio.h>
extern void foo();
int main(){
foo();
return 0;
}
the second source code is foo.c
#include<stdio.h>
void foo(){
printf("Hi,I am foo.");
bar();
}
the last one is bar.c
#include<stdio.h>
void bar(){
printf("Hi,I am bar.");
}
All the files above are be put into the same folder called test.
(its absolute path is /home/jack/Desktop/test)
then I issue the commands :
$ gcc -fPIC -shared -Wl,-soname,libbar.so.1 -o libbar.so.1.0.0 bar.c
$ ln -s libbar.so.1.0.0 libbar.so
$ gcc -fPIC -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.0 foo.c -lbar -L.
$ ln -s libfoo.so.1.0.0 libfoo.so
$ gcc -c main.c
$ ld -rpath /home/jack/Desktop/test -e main -o main main.o -L. -lfoo -lbar
then I run the executable file called main.
$./main
but the shell return the string below
bash: ./main: no such file or directory.
But the main file really exists in the current directory.
Why?
Normally you should not invoke ld directly. Instead you should use gcc to do the link. gcc passes some special options to the linker.
If I modify your script to use the correct sonames and to use gcc to link, it works. I did this:
gcc -fPIC -shared -Wl,-soname,libbar.so.1.0.0 -o libbar.so.1.0.0 bar.c
ln -s libbar.so.1.0.0 libbar.so
gcc -fPIC -shared -Wl,-soname,libfoo.so.1.0.0 -o libfoo.so.1.0.0 foo.c -lbar -L.
ln -s libfoo.so.1.0.0 libfoo.so
gcc -c main.c
gcc -Wl,-rpath,$(pwd) -o main main.o -L$(pwd) -lfoo -lbar
Using ld directly is for unusual situations. Don't do it. That said, offhand I do not know what as wrong with your approach. I think -e is wrong here -- you don't want to invoke main directly, _start does some other things. Looking at the output of ldd shows some important differences between the two approaches. Invoking the link using gcc -v will show you a bit of what is happening behind the scenes, in case you want to understand some more.
bash: ./main: no such file or directory.
But the main file really exists in the current directory.
Why?
The executable needs a suitable program interpreter to be able to perform dynamic linking. The no such file or directory message is printed because the default interpreter, which is wrong, can't be found.
Set it with the ld option -dynamic-linker /lib/ld-linux.so.2 (for 32 bit).
64 bit dynamic linker is /lib64/ld-linux-x86-64.so.2.
As your entry is directly main you must call exit(0) at the end of main. It can't be returned from main because noone has called it. The instruction pointer was directly set to the address of main by the kernel. Returning from main would probably result in a segfault and since you did not add a \n to the printf's the messages could not be seen.

gcc makefile won't compile

My final executable (this is in unix though) will be proj07.
proj07: /user/cse320/Projects/project07.driver.o proj07.support.o
gcc -Wall /user/cse320/Projects/project07.driver.o proj07.support.o
proj07.support.o: proj07.support.c
gcc -c proj07.support.c
This creates proj07.support.o but no proj07 exists after compilation. I don't get an error so my mistake must be simple but I can't seem to figure it out.
Here's the output:
gcc -c proj07.support.c
gcc -Wall /user/cse320/Projects/project07.driver.o proj07.support.o
Also I am to use a static driver to test my file which is why the path is like that
You probably do have an a.out executable. Add -o $# to your first gcc occurrence and you should be fine.

Build .so file from .c file using gcc command line

I'm trying to create a hello world project for Linux dynamic libraries (.so files). So I have a file hello.c:
#include <stdio.h>
void hello()
{
printf("Hello world!\n");
}
How do I create a .so file that exports hello(), using gcc from the command line?
To generate a shared library you need first to compile your C code with the -fPIC (position independent code) flag.
gcc -c -fPIC hello.c -o hello.o
This will generate an object file (.o), now you take it and create the .so file:
gcc hello.o -shared -o libhello.so
EDIT: Suggestions from the comments:
You can use
gcc -shared -o libhello.so -fPIC hello.c
to do it in one step. – Jonathan Leffler
I also suggest to add -Wall to get all warnings, and -g to get debugging information, to your gcc commands. – Basile Starynkevitch

Resources