Run C++ executable on Linux - c++

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.

Related

Clang compilation : "Cannot execute binary file"

I am new to the clang++ compiler flags. I have an issue regarding compilation. Here is my cmd:
clang++ -I ../llvm-project/llvm/include -I ../llvm-project/clang/include
-I ../llvm-project/build/tools/clang/include -I ../llvm-project/build/include
-O3 -c $(llvm-config-7 --cxxflags)
projectToTestHeadersBuilding.cpp -o projectToTestHeadersBuilding
I am getting error:
./projectToTestHeadersBuilding: cannot execute binary file: Exec format error
After execution I have projectToTestHeadersBuilding file. But I can not run executable. Can you please help me to understand how to get executable, so I can run it using ./projectToTestHeadersBuilding ?
In your initial command you use the -c flag which makes clang output an object file. This is part of a compiled program but not a complete executable, in order to get the final executable you must perform a linking step, usually with other object files.
A simple compilation can be done as so:
clang++ projectToTestHeadersBuilding.cpp -c -o projectToTestHeadersBuilding.o
clang++ projectToTestHeadersBuilding.o -o projectToTestHeadersBuilding
./projectToTestHeadersBuilding
Generally we do not need to explicitly pass all those -I flags you have passed. If they are needed with your setup, add them to the commands I've included above.

how can I not create precompiled header when compile object file?

I use g++ 10.2.0 and try to create a static library, but when I create object file for archiving a static library, object file format always shows precompiled header, it makes the final static library cannot work:
//file static_test.cpp
void fn(){
int temp;
++temp;
}
//file static_test.h
void fn();
build them but not link
g++ -c static_test.h static_test.cpp -o static_test.o
use file to show static_test.o format
file static_test.o
static_test.o:GCC precompiled header (version 014) for C++
and I archive it
ar rsv libstatic_test.a static_test.o
use file to show libstatic_test.a format:
current ar archive
use a main.cpp to test this static library
#include "static_test.h"
int main(){
fn();
return 0;
}
compile them and link
g++ main.cpp libstatic_test.a
libstatic_test.a: cannot add symbol: archive has no index;run ranlib to add one
collect2: error:ld return 1
why and how to solve this problem, tks~
-c is only for a single file, the second static_test.cpp is ignored. You should get the compiler warning about multiple files set to -c. g++ -c static_test.h results the precompiled header in static_test.o and static_test.cpp is ignored. The proper command should be
g++ -c static_test.cpp -o static_test.o
Do not pass header files to the compiler when you compile object files. All other commands you are using look ok.
if you would like to create a static library with gcc, you have to say it to the linker/wrapper programm "gcc" like:
gcc -static -o libyourlibname(.lib/.so) obj1.o obj2.o -s
legende:
-static: tells the linker to build a static lib
-o : output file
-s : strip all debug/linking stuff, including debug informations
note:
may be you need the option -fPIC at .c compile time like:
gcc -O2 -fPIC -c file1.c -o file1.o
legende:
-O2 : tells the c compiler to optimize
-fPIC : create program independet code (internal for the output code)
-c : compile C file to object file:
-o : tell the linker how the object file should be named
By the way:
Pre-compiled header files are only created by compiling C/C++ files only.
You have require huge memory, and mostly pre-compiled header files are not needed in small projects of small student homework tasks.
And each time you change the header file, you (the compiler) have to create a new copy of the .pch file.
Of course, .pch files are good for end-products which does not change it in the form for the developer. But they are mostly depend on the compiler.
So, you can't use .pch files from Windows MinGW64 Project under Linux (with the near) same compiler in different versions.

Prevent temporary object files hitting disk in MSVC

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.

Is object file generated during single step compilation?

According to How does the compilation/linking process work?
During compilation, the compiler takes the pre-processor's output and
produces an object file from it.
Additionally,
Compilation refers to the processing of source code files (.c, .cc,
or .cpp) and the creation of an 'object' file.
So for example:
If I have 2 files test1.cpp and test2.cpp. I can do modular compilation with g++ -c test1.cpp test2.cpp which generates 2 object files test1.o and test.o.
But what about during single step compilation? Where I have 1 file test1.cpp. With the command g++ test1.cpp, no object file appears to be generated in the directory. So what happens during single step compilation?
This has to do with g++ command line. If you just run it with
g++ file.cpp
It will compile the code to intermediate object file, and than invoke linker and create a.out executable file, removing the intermediate object file after this.

Why I cannot run an object file?

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