Build a Linux executable using GCC - c++

I'm using Ubuntu 8.10 (Intrepid Ibex) and compiling C++ files with GCC, but when I compile, gcc makes an a.out file that is the executable. How can I make Linux executables?

That executable is a "Linux executable" - that is, it's executable on any recent Linux system. You can rename the file to what you want using
rename a.out your-executable-name
or better yet, tell GCC where to put its output file using
gcc -o your-executable-name your-source-file.c
Keep in mind that before Linux systems will let you run the file, you may need to set its "executable bit":
chmod +x your-executable-name
Also remember that on Linux, the extension of the file has very little to do with what it actually is - your executable can be named something, something.out, or even something.exe, and as long as it's produced by GCC and you do chmod +x on the file, you can run it as a Linux executable.

To create an executable called myprog, you can call gcc like this:
gcc -c -o myprog something.c
You could also just rename the *.out file gcc generates to the desired name.

That is the executable. If you don't like a.out, you can pass an -o flag to the compiler. If the executable isn't marked with an executable bit, you need to do so yourself:
chmod u+x ./a.out
./a.out

Related

Compile C++ on Windows

I'm trying to compile C++ on Windows.
The command needed to compile on Linux is:
g++ -O3 -Wall -shared -std=c++11 -fPIC `python -m pybind11 --includes` EO_functions_bipartite.cpp -o extremal_bi.so
I installed MinGW but when I try to compile I get the following error:
g++.exe: error: python: No such file or directory
g++.exe: error: pybind11: No such file or directory
g++.exe: error: unrecognized command line option '-m'
g++.exe: error: unrecognized command line option '--includes EO_functions_bipartite.cpp'
g++.exe: fatal error: no input files
compilation terminated.
Assuming you have python in your path.
The backtick escape thing that embeds the python -m pybind11 --includes command within the g++ doesn't work on cmd.exe in Windows.
Run the python -m pybind11 --includes command on its own line in the cmd shell. Take the output of that command and substitute in into the g++ command. It should be a bunch of -I include params.
So if the output of the python command is this:
-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include
Expand your g++ command to be this:
g++ -O3 -Wall -shared -std=c++11 -fPIC "-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include" -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include EO_functions_bipartite.cpp -o extremal_bi.so
Notice the quotes I put around the first include directory because it has a space in its path.
The easiest way to start on native Windows if you have a Linux background is to install MSYS2 shell with MinGW-w64. This will provide an actual bash that allows you to run commands almost exactly the same way as on Linux, including support for backticks like in the case of your issue.
Though I would always recommend using $( ... ) instead of backticks, as this allows nesting.
Note that MinGW-w64 also exists on Windows to allow cross-building for Windows from Linux, but that may be a bit more difficult if you have never done any cross-building before.
Also -shared ... -o extremal_bi.so in your command should be replaced with -shared ... -o extremal_bi.dll -Wl,--out-implib,libextremal_bi.dll.a as .so files don't exist on Windows as Windows uses .dll files for shared libraries and the compiler uses .dll.a files as library objects for them.
Finally on Windows you need to tell the compiler or linker which symbols you will be exporting by either writing a libextremal_bi.def starting with the line EXPORTS followed all the symbols you want to be exported and include -def libextremal_bi.def in the link command, or using __declspec(dllexport)/__declspec(dllimport) when defining those symbols, which may be a bit complexer as it requires some conditional defines to determine if the code is being compiled for Windows and if it's during the actual build process of the shared library (__declspec(dllexport)) or code that uses it (__declspec(dllimport)). There is also another method to export all symbols, but that's a dirty method that may more easily cause symbol conflicts.

Compiling multiple C++ files. Calling a binary to run a code

I have 2 cpp files(with one main function) in /home/misha/proga/c++again folder. I built C/C++: g++ build active task and modified it to compile all files in the folder above. Now, I need to add one more task to call a binary. I think I should add one more entry in "tasks" to finally be able to run a code. Where can I read about how to write this second task? I am new to programming. Is my approach correct to run this code contained in two files? I also do not know where this binary lies. Is it tasks file in .vscode folder ?
I use Ubuntu 19.10 and VSC 1.46.1
In Terminal,
cd /home/misha/proga/c++again
Let's suppose your two cpp files are mainFile.cpp and file2.cpp
If g++ (so GCC) was not installed in your system, you can install it by running this command on the Terminal:
sudo apt-get install gcc g++
and, to compile the program (read about invoking GCC, you want warnings and debug information), write this command into the Terminal:
g++ -Wall -g mainFile.cpp file2.cpp -o yourprog
Then, you can run the program by typing:
./yourprog
It should work now. You could need to use the GDB debugger and GNU make (to be installed with sudo apt-get install gdb make)
Read also some C++ programming book and this C++ reference.
I do not understand your approach usualy your create a makefile and compile your cpp files
g++ -g -c -fpic -o name.o
at the end you link them
g++ name.o 2name.o and so on
If you create binarys you should store them in /usr/lib
and the name should libname.so you can acces them by using the -l argument

Why in my Linux, when current work directory is owned by root (e.g /usr/bin), then I cannot link any library while compiling c++?

If I write this code and saved as a.cpp at ~/Desktop
#include <memory>
int main(){}
then input to bash:
cd /usr/bin
g++ -g ~/Desktop/a.cpp -o ~/Desktop/a
then the g++ will output plenty of messy code of errors.
I have found the reason is because it don't have authority to link XX.so library.
But if I add a 'sudo' , or set CWD to the path owned by user, g++ will work properly, as follows:
sudo g++ -g ~/Desktop/a.cpp -o ~/Desktop/a
or
cd ~/Desktop
g++ -g ~/Desktop/a.cpp -o ~/Desktop/a
Why do this happen? or how can I fix this?
You don't want to generate code directly in /usr/bin.
You generate your code in your user folder, maybe create a sub-directory called cppwork or something like that.
cd
mkdir cppwork
cd cppwork
g++ -g a.cpp -o a
Once you compiled in your directory, then you copy the file using install which will also take care of stripping the debug if any (i.e. the -g says to keep debug info—stripping is not mandatory).
sudo install -s a /usr/bin/a
As you can see, the place where I use sudo is with the install command.
That being said, I never use those directly. Now a day, I use cmake which means everything works automatically. But that would be a different discussion.
Thanks for every one. I have found the reason. It's because there is an executable program named 'array' in /usr/bin. And when CWD is /usr/bin, the compiler regard this 'array' as the c++ header <array>, so compiling error.
Then I need to find out why the compiler includes /usr/bin by mistake.

C++ code compiles, but shows an error when running on Zorin OS

I'm learning C++ and trying to run a simple hello world program. It compiles but it won't execute. It worked on Windows, but it won't run on Zorin OS.
I read online that the command to run it is ./test or ./test.exe.
This is what is looks like on the terminal:
$ g++ test.cpp -o test.exe
$ ./test
bash: ./test: No such file or directory
I looked at the questions similar to this, but none have helped me.
You can not expect to be able to execute the same commands on both Windows and Linux. They use different shells with different syntax and different behaviors.
Here's a typical example of compiling a file on GNU/Linux:
dir$ g++ myfile.cpp -o myfile
dir$ ./myfile
Here's a typical example of compiling the same file on Windows:
dir> g++ myfile.cpp -o myfile.exe
dir> myfile
Note in particular:
Linux doesn't use .exe or other extensions on executables, but Windows does.
Windows doesn't require specifying directory to run files in the working directory, but Bash on GNU/Linux generally does.
The only reason why the compilation command is as similar as it is is that g++ is a Unix tool ported to both platforms. Windows normally uses / instead of - for flags like -o
As commands get more complex, they start diverging even further.

'.' is not recognized as an internal or external command

I just started learning C++, and I've been trying to run my program from the command line using:
g++ helloworld.cpp
which works, then I typed
./a.out
then it returns the error '.' is not recognized as an internal or external command.
I tried doing a.out, but it returns:
'a.out' is not recognized as an internal or external command.
I'm pretty new to the command line so it might be quite a novice problem. I'm using the gnu gcc compiler. My code is just a simple code for printing "helloworld", and it doesn't seem to be a problem with the code since the line g++ helloworld.cpp doesn't throw up any error. Just to add, I'm using windows 8.
My best guess would be that a.out is not in your directory. Usually, when compiling your program from the command line, add the -o flag and name your executable (like helloworld.exe). Then you'll be sure that an executable of that name is actually being created.
In your case, since you're most likely running Windows, without specifying a -o flag, the default is a.exe and not a.out, so when you used ./a.out that executable didn't exist. In this case, you can run your program by typing a or a.exe. You don't need the leading ./ on Windows.
./a.out
If you are in *NIX world, using linux or any other UNIX related platforms
.(dot) means current directory and a.out is an executable.
ls -l a.out
list its permissions and make sure it has executable permission. If it dont have use following command to give it permission; usually it should have when your generated the a.out file.
chmod 755 a.out
If your file is not in current directory use the absolute path to invoke the executable file
<absolute_path>/a.out
It should work if you have taken care all above criteria.
In the Windows world, "\" is used to separate files and directories:
C:\Windows\System32\Etc
However most other operating systems, and the web, use "/"
file:///c/windows/system32/etc
/etc/motd
In Unix "." refers to the current directory, and Windows/DOS mostly support this.
The Unix-based compilers expect you to specify an output file name for a compilation, and the default is "a.out". But you can override it with "-o"
g++ test.cpp -o test.exe
This creates a file called "test.exe" in the current directory. If you are using MinGW's "bash" command line, you should be able to run the above executable by typing:
./test.exe # note: no spaces!
at a "$" prompt
$ ./test.exe
However, if you are in a directory, say C:\Dev in the DOS command prompt, that won't work. DOS thinks '/' means "start of a parameter":
C:\Dev\> dir /w
outputs "wide" format dir
So, if you're using DOS, you just need to type:
test.exe
or
.\test.exe
e.g.
C:\Dev\> test.exe
C:\Dev\> .\test.exe
C:\Dev\> c:\dev\test.exe
or if you're relying on "a.out"
C:\Dev\> a.out
C:\Dev\> .\a.out