The output of GCC - c

I have GCC running on my Ubuntu operating system. I wrote a small program in C and tried compiling it. Its output was an a.out file like it would do on Windows. How can I make it put out a Linux executable?

a.out is the executable (assuming you've done full compilation rather than just generation of object files but that's the most likely case). To run it, use (from a shell):
./a.out
If you want to give it a different name, simply rename it, or better:
gcc -o actualname myprog.c
to get an executable called actualname which is then run (of course) with:
./actualname
See the following transcript:
pax> cat testprog.c
#include <stdio.h>
int main (void) { printf("Hi.\n\n"); return 0; }
pax> gcc testprog.c ; ./a.out
Hi.
pax> gcc -o xyzzy testprog.c ; ./xyzzy
Hi.

Suppose your C file is f.c.
gcc f.c gives the a.out executable, and you can run it in a terminal as ./a.out.
gcc f.c -o myprog gives myprog as the executable, and you can run it in a terminal as ./myprog.

It is a Linux executable. a.out files (actual a.out format, not files named a.out by default) cannot be executed on Windows.
In both cases, most likely you get a standard executable usable in the local system, but named a.out. On Linux it's an ELF file.

Related

What I get after I compile the c file?

I use gcc compiled the hello.c:
dele-MBP:temp ldl$ ls
a.out hello.c
now, when I cat a.out:
$ cat a.out
??????? H__PAGEZERO?__TEXT__text__TEXTP1P?__stubs__TEXT??__stub_helper__TEXT???__cstring__TEXT??__unwind_info__TEXT?H??__DATA__nl_symbol_ptr__DATA__la_symbol_ptr__DATH__LINKEDIT ?"? 0 0h ? 8
P?
/usr/lib/dyldס??;K????t22
?*(?P
8??/usr/lib/libSystem.B.dylib&`)h UH??H?? ?E??}?H?u?H?=5??1ɉE??H?? ]Ð?%?L?yAS?%i?h?????Hello
P44?4
there shows the messy code.
I want to know what type of the a.out? is it assembly language? if is why there have so many ??? or %%%?
There are several intermediate file formats, depending on the compiler system you use. Most systems use the following steps, here shown with GCC as example:
Preprocessed C source (gcc -E test.c -o test.i), but this is before compilation, strictly speaking
Assembly source (gcc -S test.c -o test.s)
Object file containing machine code, not executable because calls to external functions are not resolved (gcc -c test.c -o test.o)
Executable file containing machine code (gcc test.c -o test)
Only the first two steps generate text files that you could read by cat or in a text editor. This is BTW a valuable source for insight. However, you can use objdump to see most informations contained in the other formats. Please read its documentation.
Each step does also all steps before it. So (gcc test.c -o test) generates assembly source and object file in temporary files that are removed automatically. You can watch that process by giving GCC the option -v.
Use gcc --help to see some entry points for further investigations.
There is at lot more to say about this process but it would fill a book.

How to compile C program

I am learning C and I have a simple hello world program that I am trying to run on Windows 10. Here is the code:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
I have installed GCC compiler and I tried the following in order to run it in the command prompt:
gcc hello.c
a
I also tried:
gcc hello.c
./a.exe
and:
gcc hello.c
./a
and:
gcc hello.c -o hello
./hello
The program does not run displaying hello, world and it gives the following error:
bash: a.exe: command not found
What am I doing wrong and how can I run the program after the compilation?
It appears that your compilation succeeded successfully.
See if there is an a.out or a.exe file present, as you didn't indicate a non-default executable name.
Note that running a alone typically won't do anything, because it is highly unlikely that your executable is on the bash PATH. This means you need to run ./a.out or ./a (depending on base operating system).
Binary executables under windows typically must have .exe extension to be recognized as such.
I am not sure if gcc under windows adds the right extension automaticaly when outputting executables.
I would try:
gcc hello.c -o hello.exe
./hello.exe

Use of -g and -o options in gcc command in c programming

Suppose there are 2 c program named abc.c and xyz.c . Now we want to work with the 2 executables at a time. So we change the name of the ./a.out using
gcc -g abc.c -o abc
gcc -g xyz.c -o xyz
Even gcc -o abc abc.c works.
What does the -g and -o in the above commands specify or describe?
What is the significance of -g and -o in the command for renaming ./a.out file.
Thanks in advance.
-g means to leave debugging information in the output file, it's unrelated to renaming.
-o means to put the result in the specified file instead of the default filename (abc.o for object files, a.out for linked executable files).
From https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html:
-g
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
-g starts becoming useful once you use debuggers such as gdb and lldb. When you attach to a running program and advancing one line at a time printing/altering the state as it changes.
if we specify -g option while compiling, debugging symbols will be available in the output file which will be useful when you try to debug using GDB.
If we won't specify -o option, the output will be placed in default a.out file. So if we run
gcc a.c - output will be in a.out
gcc b.c - output is a.out which is replacing old a.out file
If you want the output not to be a.out file, you can give -o option while compiling
gcc abc.c -o a
-o and -g options are not related.

Why do I keep getting "Killed: 9" when I run this very basic SQLite3 based C file?

I have this super basic C file:
#include <sqlite3.h>
#include <stdio.h>
int main(void) {
printf("%s\n", sqlite3_libversion());
return 0;
}
And in the same directory I have sqlite3.h, sqlite3.c and sqlite3ext.h downloaded from the downloads page on sqlite.org.
I then run gcc -c main.c. Then chmod +x main.o. Then ./main.o. And every time I get:
Killed: 9
What am I doing wrong?
You cannot execute a relocatable object file directly like that. Try this:
gcc main.c -o main -lsqlite3
This works on Ubuntu with libsqlite3-dev package installed. Running main results in:
3.8.2
The -o flag specifies the name of the executable file. If you ommit -o main, you'll get a file called a.out with gcc on most platforms (maybe a.exe on windows+cygwin?). Either way, this file will already be executable, so you can skip the chmod +x.
The -lsqlite3 flag tells the compiler to link in the sqlite3 library too.
If you've built sqlite3 from scratch, you may also need -I and -L flags to tell the compiler where to look for libraries and headers.
In your command, the "-c" flag skips the linking stage and produces a relocatable object, where otherwise, gcc will produce an executable file.
You can use readelf -h main.o using output of your original command and readelf -h main using output of my suggested command, or alternatively just file main.o and file main to see differences in file types.

edit bash command gcc to compile and execute in one line

I want to know if this is possible:
if you put gcc filename.c you will compile filename.c in a.out file
and if you put ./a.out you will execute the file.
The composite version it's
gcc filename.c && ./a.out
I want edit this command in bash_profile to do this in one short command line.
gcc filename.c do this gcc filename.c && ./a.out
You can declare a function:
gccrun () {
gcc "$1" && ./a.out
}
Be careful, though: what if someone uses full path to the C file as a parameter?
Makefiles are usually used for this kind of stuff.
a.out: file.c
gcc $<
run: a.out
./a.out
make run would run a.out recompiling it if its source has changed since the last compilation or doesn't exist.

Resources