📜 ⬆️ ⬇️

GNU Compiler Collection, first steps

This note is intended to use simple examples to introduce the novice nix developer to the GNU tools, in particular the GCC compiler.


With it, we will create a simple program. By and large everything is as usual. We create a special folder in which the project will be placed.
Create a file in it with the name: hello.c
Open the file in any text editor and write the simplest code:

#include <stdio.h>
int main(void)
{
printf("Hello world!");
return(0);
}


Save the file and execute the command: gcc hello.c
')
A new file, a.out, has appeared in the folder we have created; this name is assigned by default, unless otherwise specified.

This is the executable file. Let's try to start it, for this we type in the console: ./a.out

And we rejoice in connection with the first written program in Linux!

We go further. When launching an executable file, if we specify only its name, the system will search for it in the / usr / bin and / usr / local / bin directories, and, naturally, will not find it. The first one is designed to host stable versions of programs, usually included in the Linux distribution. The second is for programs installed by the user (for the stability of which no one guarantees). By default, when building a program, they are installed in the / usr / local / bin directory.

Flags used during compilation

The -o flag is used to specify the specific name of the executable file being received: gcc hello.c -o say_hello

The -E flag is used to see what happens after the preprocessor operation. This flag stops the execution of the program, just at the stage of processing by the preprocessor. The result is a source file with the contents of the header files included in it.
Lifting / looking: gcc -E hello.c -o hello.cpp

The -c flag is used to create object files (similar to * .obj): gcc -c kalkul.c

The name of the file is the same, but the compiler changes the extension .c to .o (but you can also specify it manually).

The -x flag is used if an object file is created from the source already processed by the preprocessor (for example, the one we got above), we must definitely indicate that the compiled file is a source code file processed by the preprocessor and having preprocessor tags. Otherwise, it will be processed as a normal C ++ file, without taking into account preprocessor tags, which means that communication with the declared functions will not be established.

The C ++ file processed by the preprocessor is denoted cpp-output:
gcc -x cpp-output -c hello.cpp

The project is going as follows: gcc hello.o -o say_hello
Run: ./say_hello

Why do we need all this fuss with intermediate stages?
Programs rarely consist of a single file. Typically, there are several source files, and they are combined into a project. And in some exceptional cases, the program has to be assembled from several parts, written, perhaps in different languages. In this case, it is necessary to run compilers of different languages ​​so that each gets an object file from its source code, and then to assemble these received object files into an executable program.

Source: https://habr.com/ru/post/107831/


All Articles