When I want to run a source code why this works :
gcc test.c -o test.o
then
./test.o
but this does not work :
gcc -c test.c
then
./test.o
and get this message
bash: ./test.o: Permission denied
First of all, you are not creating an object file but an executable file. Object files are an intermediate file used as input file for the linker to create the executable file. That you name it with an .o suffix doesn't matter.
Secondly, due to tradition if you do not specify an output filename with the -o option the compiler frontend program and linker will create an executable named a.out.
But that's not all, because with the second example you are actually creating a real object file, and those are not executable. Like mentioned above, those needs to be passed to a separate linking step to create the executable file.
You either need to create an executable file:
gcc test.c
./a.out
Or you should link the object file into an executable file:
gcc -c test.c # Create object file
gcc test.o -o test # Use object file to create executable file
./test # Run the executable file
You get that message because the compiler doesn't set the executable bit on object files, because - well, because they are not executable. If you set the executable bit manually and try to run it, you'll get something like "unknown executable format".
Now, it's not just a format problem - the point is that an object file is just half of the work to get something that can actually be executed. In particular, it's missing the linking step, where the linker finds unresolved references and patches them with the addresses from other object files - including the ones you don't specify explicitly, like the standard library - and generates a proper executable file, that the kernel knows how to load and execute.
In the first case you just name the resulting file test.o by using -o, it has been compiled assembled and linked.
In the second case you merely compiled and assemble, it can't run without being linked. See gcc --h or Overall options for gcc for -c:
-c
Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
By default, the object file name for a source file is made by replacing the suffix ‘.c’, ‘.i’, ‘.s’, etc., with ‘.o’.
Unrecognized input files, not requiring compilation or assembly, are ignored.
(Emphasis mine)
You need to link it and then execute it:
gcc -o a.out test.o
You cannot run an object file. This is not executable and need to be linked to become executable.
Try
gcc -o test test.c and run using ./test.out
This is a fundamental question in gcc. Note that never using parameter -c when you want to get an executable file in single command such as
gcc -c xx.c yy.c -o new
.But you can get an executable file with -c in following commands
gcc -c xx.c yy.c
gcc xx.o yy.o -o new
It's equivalent to
gcc xx.c yy.c -o new
Related
Say I have a CPP file called test.cpp. On Ubuntu using gcc 9.3.0 I can use these commands:
gcc -c test.cpp (creates object file test.o)
gcc test.o -o test.out (creates executable test.out from object file test.o)
gcc test.cpp -o test.out (creates only the final executable test.out)
The last option is great since no intermediate object files remain after compilation. (I'm unsure whether gcc is doing everything in-memory, or whether object files are temporarily hitting disk before being cleaned up during linking).
On Windows, cl test.cpp /link /out:test.exe creates the executable test.exe, but also the object file test.obj.
Is there a way to prevent MSVC from creating the intermediate object files? Alternatively, is there a link option to ask MSVC to clean up?
No. The best you can do is use the /Fo flag to dump the .obj file under %TMPDIR% or so.
Don't do this for large builds, as foo/Bar.cpp and qux/Bar.cpp will map to Bar.obj and give you very interesting compilation/linking errors.
I am trying to compile an execute a C++ program in Linux using OpenCV.
When I type
g++ -c facedetection.cpp -std=c++11 -o facedetection
The facedetection file is correctly generated. Please note that I use -std=c++11 because I had an error advising to do so.
After doing chmod o+x facedetection I try to execute it with ./facedetection but I get error:
bash: ./facedetection: cannot execute binary file: Exec format error
What is wrong?
When you compile with -c, it generates an object (.o) file, not an executable. You need to compile it without -c in order to make an executable file.
Larger C++ programs will have more than one .cpp file; for each .cpp file, you would compile using -c to generate their respective .o file. Then you would link these .o files (running g++ without -c) to generate the final executable.
Ok, so this might not be a great question, but I'm a bit stuck.
I have 3 programs:
pegio.c/pegio.h - Does hardware initialization and functions for my device
PegIOHandler.cpp/PegIOHandler.h - Handles I/O for device
PegRTU.cpp - Main function
My project implements the opendnp3 (which allows one to transmit data using the DNP3 protocol) library.
Now, to compile it I first compile the pegio.c file
gcc -c pegio.c -o pegio.o
Easy, up to here I understand.
Secondly I compile the IOHandler and reference pegio.c as it uses it.
g++ -c PegIOHandler.cpp pegio.c -o PegIOHandler.o -std=c++0x
Now it gives me the following output.
g++: warning: pegio.o: linker input file unused because linking not done
But, it still creates the object file. HOWEVER, PegIOHandler implements opendnp3 header files, which is included in PegIOHandler.cpp and PegIOHandler.h. When I attempt to compile these files without using the '-c', it tells me that there are undefined references to the opendnp3 files. I know I have to link them to my project, but how do I do that?
Then compililing my third and final file:
g++ PegRTU.cpp pegio.o PegIOHandler.o -o pegrtu -std=c++0x
This now tells me that there are undefined references to the opendnp3 files.
So: How do I link the opendnp3 library to my project / code files???
Thanks!
Ouch. So many misunderstandings. You don't need the previously compiled object files to compile further source files to object code. However, you do need to link them together at the end of the compilation process, including any libraries required. All in all:
gcc -c pegio.c -o pegio.o
g++ -c PegIOHandler.cpp -o PegIOHandler.o -std=c++0x
g++ -c PegRTU.cpp -o PegRTU.o -std=c++0x
g++ -o executable_name *.o -lopendnp3 # or whatever linker flag is needed for OpenDNP3
And pretty please, read this.
I have a very small c++ program that consists of two files: main.cpp and something.cpp. I'd like to compile my program using g++ in the OS X Terminal. Here's what I've tried:
> g++ main.cpp something.cpp
> ./a.out
Is this correct? I've come across examples that use the -o flag. I'm not sure if that's necessary.
Does it work? That's a pretty good indication of correctness! The -o flag allows you to specify a file name so the executable is not named a.out
-o option is not required. If not specified, the default behavior is to put an executable file in "a.out":
-o file
Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable
file, an object file, an assembler
file or preprocessed C code.
If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its
assembler file in source.s, a
precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.
So yes, this is correct.
I am very aware of compiling C++ programs with g++ in linux environment. But, may be I am missing something, I am getting this strange output/behaviour.
I have source file in test.cpp.
To compile this, I did
(1)
g++ -c test.cpp
g++ -o test test.o
./test
Everything works fine.
But when I did compling and linking in same stage, like this
(2)
g++ test.cpp -o test
./test => Works fine
(3)
g++ -c test.cpp -o test => Doesn't work
In my last case, test is generated but is no more executable; but in my guess it should work fine.
So, what is wrong or do I need to change some settings/configuration ??
I am using g++ 4.3.3
Thanks.
When you say:
g++ -c test.cpp -o test
The -c flag inhibits linking, so no executable is produced - you are renaming the .o file.
Basically, don't do that.
You are forcing compiler to produce an object file and name it like an executable.
Essentially your last line tells: compile this to an object file, but name it test, instead of test.obj.
-c flag means Compile Only
Try
g++ -o test test.cpp
Specifying -o in the g++ command line tells the compiler what name to give the output file. When you tried to do it all in one line, you just told the compiler to compile test.cpp as an object file named test, and no linking was done.
Have a look at the fabulous online manual for GCC for more details.
from the gcc manual:
-c Compile or assemble the source files, but do not link. The linking
stage simply is not done. The ultimate output is in the form of an
object file for each source file.
You must link the compiled object files to get the executable file.
More info about compiling and linking and stuff is here.
Read man g++. The switch -c is to compile only but not to link.
g++ -c test.cpp -o test
does what
g++ -c test.cpp
does but the object file will be test istead of the default name test.o. An object file cannot be executed.