You are not logged in.
Pages: 1
For whatever resason, I am currently able to compile C applications(as It executes with errors if any), just like so -> gcc -c test.c -o test.o… of course making sure it is executable, however I believe my mistake is trying to run the output(./test gives me a format error, perhaps I need to build&compile my kernel with certain modules that I forgot to add)? Im not sure what I am doing wrong as I am simply looking to jumpstart on learning linux however program won’t even properly produce desired output.
Last edited by reggieArchExpert (Today 13:01:14)
Offline
gcc -c test.c -o test.o…
Did you link executable after compilation? "gcc -c test.c test.o" produces object file, not executable. See https://man.archlinux.org/man/gcc.1#c
If your program consits of single source file, you can either compile and link it with one command:
$ gcc -o test test.cor compile to object file and link object file to executable:
$ gcc -c test.c
$ gcc -o test test.o of course making sure it is executable
Gcc already sets executable bit for produced executables.
./test gives me a format error
Please show exact commands you execute and error message.
Online
That is the exact command I execute(.test.o). Sorry full filename wasnt in output though im sure that doesnt matter. I did try executing this set pf commands afterwards however, which that last job was what gave me no output. The first gave me, again, ‘format error’
Offline
That is the exact command I execute(.test.o).
Please don't paraphrase, https://bbs.archlinux.org/viewtopic.php?id=57855
@dimich told you that what you originally suggested will NOT produce an executable and then explained how to do that.
Post your interaction w/ gcc verbatim (all input and output), the source file you're trying to compile and the resulting binary.
See the first link below for a bunch of upload options.
Online
reggieArchExpert wrote:gcc -c test.c -o test.o…
Did you link executable after compilation? "gcc -c test.c test.o" produces object file, not executable. See https://man.archlinux.org/man/gcc.1#c
If your program consits of single source file, you can either compile and link it with one command:$ gcc -o test test.cor compile to object file and link object file to executable:
$ gcc -c test.c $ gcc -o test test.oreggieArchExpert wrote:of course making sure it is executable
Gcc already sets executable bit for produced executables.
Thanks man, above example was what I needed to finally gain desirable outputreggieArchExpert wrote:./test gives me a format error
Please show exact commands you execute and error message.
Problem solved, so doubt output will be necessary. Though further on to this problem, why would simply giving desired '-o' flag be enough instead of doing all on one command(i.e again as you say "you can either compile and link it with one command"... in my mind, that would be like this no?
gcc -c test.c -o test.o
...
Your first example(though also works, appreciate the verbosity) simply just doesn't make sense in my mind. Don't we have to compile the code first, or perhaps simply order doesn't matter
Offline
Online
why would simply giving desired '-o' flag be enough instead of doing all on one command(i.e again as you say "you can either compile and link it with one command"... in my mind, that would be like this no?
gcc -c test.c -o test.o
I'm not sure I understand your question.
If no output file name given, with '-c' flag output name is created from source file name by replacing '.c' suffix with '.o'. So
gcc -c test.cis the same as
gcc -c test.c -o test.oIt compiles 'test.c' into 'test.o' object file.
Compilation stage expects only one source file. Order of '-c', '-o test.o' and 'test.c' arguments doesn't matter.
Without '-c' default name for output executable is 'a.out'. Using '-o' option you can override it to any desired name.
Linking stage assumes multiple input files. Gcc tries to recognize input file format by suffix, and if it's known source file, preprocesses/compiles it first (https://man.archlinux.org/man/gcc.1#Opt … _of_Output).
Edit: clarified gcc behavior.
Last edited by dimich (2026-09-18 17:30:30)
Online
Offline
reggieArchExpert wrote:gcc -c test.c -o test.o…
Did you link executable after compilation? "gcc -c test.c test.o" produces object file, not executable. See https://man.archlinux.org/man/gcc.1#c
If your program consits of single source file, you can either compile and link it with one command:$ gcc -o test test.cor compile to object file and link object file to executable:
$ gcc -c test.c $ gcc -o test test.oreggieArchExpert wrote:of course making sure it is executable
Gcc already sets executable bit for produced executables.
reggieArchExpert wrote:./test gives me a format error
Please show exact commands you execute and error message.
Here are the exact commands I used to receive below error. *Note(again it seems that for whatever reason
$ gcc -o test test.c # gave me no problem and returned desired output )
:
$ gcc -c test.c -o test.o #nothing returned as expected
$ ./test.o
$ zsh: permission denied: ./test.o # weird, why??
$ chmod +x test.o
$ ./test.o
$ zsh: exec format error: ./test.oHope above helps. I am sure I am compiling it the wrong way
Offline
https://bbs.archlinux.org/viewtopic.php … 6#p2309946
Did you read that?
file test.oDon't post the output, I know what it says.
gcc -o test test.o
Then
file testNow clear?
Online
gcc decides on what action to take based on the extensions of the inputs given to it unless overridden by an option such as -c. You pass gcc test.c as input and request test.o as ouput gcc recognizes those as the extensions for a C source file and an object file, so it generates an object file not an executable, you do not pass any options telling gcc to do anything else.
Offline
$ gcc -c test.c -o test.o #nothing returned as expected
$ ./test.o
$ zsh: permission denied: ./test.o # weird, why??
Because you are trying to execute non-executable file.
'-c' option says to GCC: compile test.c and create object file but do not create executable. As said multiple times above, object files are not executables you can run.
test.o is non-executable in both two senses:
1) it doesn't contain executable format.
2) it has no executable permission.
$ chmod +x test.o
$ ./test.o
Setting executable permission to a file doesn't change its content. File format and permission bits are absolutely unrelated to each other.
Online
reggieArchExpert, do you know and understand how compilation and linking of binaries works? I have a growing feeling this is the part you miss here.
An executable program is not merely a file that has the ‘x’ permission. Nor is it a file that just contains fragments with machine code. It’s a specific file format the system needs to know how to execute. That format contains not only your code, but also auxiliary data, sometimes library code, necessary metadata, and — most importantly for any program — the entry point. It’s a fully baked cake, ready to be fed to the kernel.
During compilation, the C compiler translates human-readable source files (.c) into machine code. That machine code is placed in a “box” called object files (.o). I underlined ‘s’ to bring your attention to plurals. In almost any serious program we have many of these. These are our cake ingredients after initial mixing and processing. But the cake is not ready yet.
To make the cake, we have to build a cake and bake it. This step is called linking. It collects multiple object files (.o) and packages them together into a proper executable program. That also involves filing in various placeholders, adjusting metadata, and generally making the needed links between elements like functions and their calls. Because in an object file (.o) a lot of things — like function calls, some jumps, and static data references — is still left as placeholders. A holes which linking patches to make things work together.
$ ls *.c
main.c module.c
$ file main.c module.c
main.c: C source, ASCII text
module.c: C source, ASCII text
$ cat main.c
void printHello(void);
void printWorld(void);
int main(void) {
printHello();
printWorld();
return 0;
}
$ cat module.c
#include <stdio.h>
void printHello(void) {
puts("Hello");
}
void printWorld(void) {
puts("world");
}
$ gcc -c -o main.o main.c
$ gcc -c -o module.o module.c
$ ls *.o
main.o module.o
$ file main.o module.o
main.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
module.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ gcc -o hello main.o module.o
$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=40f344048af3355c486644ed9c3b99165ac688c9, for GNU/Linux 4.4.0, not stripped
$ ./hello
Hello
worldgcc may also do compiling and linking in a single step. Note that no `-c` option is used!
gcc -o hello main.c module.cBonus #1:
You may also see word “linking” and “linker” used beyond the binary building process. That’s because dynamic libraries may also be used. They’re linked by the system linker at the moment the program is executed, or even on-demand during its operation. In fact even our trivial program pulls in some libraries, most notably the C library:
$ ldd ./hello
linux-vdso.so.1 (0x00007f9159735000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f9159400000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f9159737000)These are linked at start, by the system linker.
Bonus #2:
If you ask, why bother with so many steps and intermediate files: modularity. Above, that was clearly not necessary and I only did it for the sake of example. In your first attempts you’re also not going to use separate modules. But in practice applications consists of dozens if not hundreds separate modules, and they also make use of external libraries. An additional advantage is that compilation times are greatly reduced on rebuilds: only the modified code has to be recompiled, not the entire program. With some applications taking a dozen minutes to build, I believe even as a novice you can see the benefit of rebuilding just a bunch of modules after modifying your code.
Last edited by mpan (2026-09-22 21:34:21)
Offline
Compile flags may also only apply to a particular source file which is why in general build systems compile source files singularly with their own flags then combine at the link stage.
Offline
reggieArchExpert, do you know and understand how compilation and linking of binaries works? I have a growing feeling this is the part you miss here.
Yup! After reading the entirety of your response and understanding example given, this was definitely the problem.
Bonus #1:
You may also see word “linking” and “linker” used beyond the binary building process. That’s because dynamic libraries may also be used. They’re linked by the system linker at the moment the program is executed, or even on-demand during its operation. In fact even our trivial program pulls in some libraries, most notably the C library:$ ldd ./hello linux-vdso.so.1 (0x00007f9159735000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f9159400000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f9159737000)These are linked at start, by the system linker.
I am guessing that this C library is of course standard across all C programs, not just this one "trivial program" in particular.
Bonus #2:
If you ask, why bother with so many steps and intermediate files: modularity. Above, that was clearly not necessary and I only did it for the sake of example.
Example or Examples? It looks like above is trying to reference one of the examples, though not sure which one in particular if that's the case. Please explain further
Example In your first attempts you’re also not going to use separate modules. But in practice applications consists of dozens if not hundreds separate modules, and they also make use of external libraries. An additional advantage is that compilation times are greatly reduced on rebuilds: only the modified code has to be recompiled, not the entire program. With some applications taking a dozen minutes to build, I believe even as a novice you can see the benefit of rebuilding just a bunch of modules after modifying your code.
Awesome! Exactly what I was looking for, as though the gcc#c manual is appreciated, it fails to give a verbose in-depth explanation as you just did(as intended with linux manuals currently). Alongside above "bonuses", I think I can finally mark this thread as Solved for this particular problem.
Last edited by reggieArchExpert (Today 10:24:40)
Offline
for the last paragraoh: WRONG!
man pages are sorted into several categories for they explain (commands, tools, libs, syscalls, files, etc ...)
the (g)cc man page is NOT to explain the 4-step compilation lifecycle from C source to binary executeable
the (g)cc man page is about to explain the interaction with the (g)cc binary and it's options - which it DOES
it's upon YOU to understand that if you want a single call you only have to give the input either without any parameter or with only -o to overwrite the output filename
it was YOU who failed to understand what -c does - NOT the man page
it was also YOU who either ignored my link or not understoid it but also don't asked any question
don't blsme a proven good man page for your own fail to ubderstand it!
Offline
Compile flags may also only apply to a particular source file which is why in general build systems compile source files singularly with their own flags then combine at the link stage.
Interesting just to be clear, when you say
"...with their own flags..."
this is not referring to their own built custom flags? Regardless, I would still like a little bit of an explanation(or a link besides the gcc#c manual would also be fine) as this fact was unknown to me prior to reading this
Last edited by reggieArchExpert (Today 10:56:28)
Offline
(or a link besides the gcc#c manual would also be fine)
Offline
for the last paragraoh: WRONG!
man pages are sorted into several categories for they explain (commands, tools, libs, syscalls, files, etc ...)
the (g)cc man page is NOT to explain the 4-step compilation lifecycle from C source to binary executeable
the (g)cc man page is about to explain the interaction with the (g)cc binary and it's options - which it DOESit's upon YOU to understand that if you want a single call you only have to give the input either without any parameter or with only -o to overwrite the output filename
it was YOU who failed to understand what -c does - NOT the man page
it was also YOU who either ignored my link or not understoid it but also don't asked any questiondon't blsme a proven good man page for your own fail to ubderstand it!
Haha, how is this not a violation of https://terms.archlinux.org/docs/code-o … irect%3Dno
Anyways you entirely missed the point. I wasn't even criticising the gcc manual for misunderstanding the "-c". This was more than clear in the very same response if you read my very first paragraph. Did you even read my response in its entirety or did you just skim it?
Also I am entirely unsure what exactly you are upset about, as all the sources you posted were from GeekstoGeeks, and nowhere in the guidelines does it say that I have to read every single source reference to me. Its even more weird that you would feel the need to make the assumption, as I could have simply just have not seen your response(or planned to refer to it later) as I never even referenced your response, so there's absolutely no need to even fight over this.
And again, I really do just simply believe that you didn't even read my response(at least entirely in good faith), as if you did, it would have been more than clear what I was referring to. Does mpan ever go over the "4 step compilation lifestyle from C source to binary executable"? Because on my very brief mention of my "criticism" with the referenced gcc manual(which barely was even a criticism as I as well talked how I appreciated reading the manual just directly before), it is more than clear that I am not even attacking the manual page.
Regardless, if you are going to attack me, please at the very least directly reference exactly what you are talking about(a direct quote would be nice) because you are all over the place my friend
Offline
reggieArchExpert wrote:(or a link besides the gcc#c manual would also be fine)
Please reference how given link even directly answers my question
Offline
your actual question: "How do I run C Applications?"
your actual issue: wrongly using -c by not understanding it
what my link provides: a goid explanation of how a source file turns into an executable - and why several others tried to get into your brain: "just get rid of '-c' and '.o' but only call 'gcc -o main main.c'"
also: please avoid uneccessary full quotes and double posts
to write it in my usual style: you are exactly that kind of student who just uses google to find the next best forum instead of an already existing answer - you lack basic skills of understanding yet you try to tell that magic black box what to do (programming)
with your current skill level: just DON'T!
first learn how to proper use that magic box called pc before trying to tell it what to do
Last edited by cryptearth (Today 14:17:56)
Offline
@dimich's immediate response was beyond clear about what's wrong with your approach.
The manual page is beyond clear how to use gcc in this regard.
What is still not clear is how you even came up w/ the original approach.
If you want some reply to your question to loqs, please clarify what you're actually seeking detailed information about.
Compile flags may also only apply to a particular source file which is why in general build systems compile source files singularly with their own flags then combine at the link stage.
What part of that is not clear?
Compile flags may also only apply to a particular source file
or
general build systems compile source files singularly with their own flags
or
combine at the link stage.
Those are simple factual statements about real-life compilation and linkage - the existing source code has different requirements for the compiler to turn that into a linkable binary.
If you're looking for examples, common scenarios from the top of my head are varying optimizations, C(++) standards and warning/error handling.
If you want to read a book about how gcc works in detail, I suggested to get some books about gcc. There're plenty.
But the official reference is https://gcc.gnu.org/onlinedocs/
Online
as though the gcc#c manual is appreciated, it fails to give a verbose in-depth explanation
Process of building executable from sources is not specific for GCC. MSVC, Turbo / Borland C, Watcom C and many other work the same way.
GCC manual page is not a tutorial. It doesn't and should not explain what to do, it explains how to perform one or another operation with gcc command.
Online
Pages: 1