GCC starts

xiaoxiao2021-03-06  73

When developing applications for Linux, most of the cases use C language, so how is almost every Linux programmer faced?

Flexible uses C compiler. The most commonly used C language compiler under Linux is GNU Compiler Collection, which is a GNU project in accordance with ANSI C.

The standard compilation system can compile the program written in language such as C, C and Object C. GCC is not only very powerful, but the structure is very flexible. Most worthy

One point is that it can support various languages ​​through different front-end modules, such as Java, Fortran, Pascal, Modula-3, and ADA, etc.

Open, freedom and flexible are the charm of Linux, and this is the embodiment of the GCC is that the programmer can better control the entire compilation process by it.

When using the GCC compiler, the compilation process can be subdivided into four stages:

◆ Pre-processing

◆ Compilan

◆ Assembling

◆ Link (Linking)

Linux programmers can end according to their needs, to end any phases compiled, in order to check or use the compiler to output information in this phase, or

Finally generated binary files to control to prepare for future debugging by adding different quantities and types of debugging code. And other commonly used

Like the compiler, GCC also provides flexible and powerful code optimization functions, using it to generate higher code of execution efficiency.

GCC provides more than 30 warning information and three warning levels, using them helps to enhance the stability and portability of the program. In addition, GCC also pairs standard C and

The C language has been extended to improve the performance efficiency of the program, which helps the compiler to optimize the code to reduce the workload of the programming.

GCC starts

Before learning to use GCC, the following example can help users quickly understand the GCC's working principle and use them to actually use the actual project development.

First enter the code shown in Listing 1 with a familiar editor:

Listing 1: Hello.c

#include int main (void) {Printf ("Hello World, Linux Programming! / N"); Return 0;}

Then perform the following command to compile and run this program:

# gcc hello.c -o hello # ./hellohello world, linux programming!

From a programmer's perspective, just simply execute a GCC command, but from the perspective of the compiler, it is necessary to complete a series of very complicated work.

First, the GCC needs to call the preprocessor CPP, which is responsible for expanding the macro defined in the source file and inserts the "#include" statement in the "#include" statement.

Content; then, GCC will call CCL and AS to compile the process-after source code into a target code; Finally, the GCC calls the link LD to generate the target code.

Link into an executable program.

In order to better understand the working process of GCC, the above-described compilation process can be divided into several steps separately, and the results of each step are observed. The first step is to

Pre-transder, using the -e parameter allows GCC to stop compilation process after the pre-processing:

# Gcc -e hello.c -o hello.i

If you look at the content in the Hello.cpp file, you will find that the content of stdio.h is indeed in the file, and the macro definition that should be pre-processed is also

They have made the corresponding processing. The next step is to build Hello.i as a target code, which can be done by using the -c parameter:

# Gcc -c hello.i -o hello.o

The GCC will be viewed by default .i file as a pre-processed C language source code, so the above command will automatically skip the pre-processes and start executing the compilation process, or

Use the -X parameter to make GCC to start compiling from the specified steps. The last step is to link the generated target file into an executable:

# GCC Hello.o -o Hello

When using modular design ideas for software development, usually the entire program consists of multiple source files, and a plurality of compilers are formed accordingly.

These compilers can be managed well with GCC. Suppose there is a program consisting of two source files from foo1.c and foo2.c, in order to compile them, and

Finally generate the executable FOO, you can use the following command:

# GCC foo1.c foo2.c -o foo

If there is more than one file at the same time, the GCC will still be done in accordance with the process of pre-processing, compile and link. If it is deep, the above command is approximately equivalent to the following three commands:

# gcc -c foo1.c -o foo1.o # gcc -c foo2.c -o foo2.o # gcc foo1.o foo2.o -o foo

When compiling a project containing many source files, if only one gcc command is used to complete compilation is very wasteful. Suppose there are 100 source files in the project

Need to be compiled, and each source file contains a 100,000 line code. If only one GCC command is used as above, then the GCC needs

Each source file is recompiled, and then all connect it to it. It is clear that this is quite a lot of time, especially when the user is only modified.

When a file is, it is not necessary to recompile each file because many of the target files that have been generated will not change. To solve this

Question, the key is to use GCC flexible, while also use tools like Make.

Warning prompt function

GCC contains a complete error check and warning prompt, which can help Linux programmers write more professional and beautiful code. First read Listing 2

The program, this code is written very bad, carefully check it is not difficult to pick out a lot of problems:

◆ The return value of the main function is declared as Void, but it should actually be int;

◆ Use the GNU syntax extension, even if you use long long to declare 64-bit integers, do not comply with ANSI / ISO C language standards;

◆ The main function does not call the Return statement before termination.

Listing 2: Illcode.c

#include void main (void) {long long int var = 1; Printf ("IT IS Not Standard C C code! / N");}

Let's take a look at how GCC helps programmers to discover these errors. When GCC is compiled, if you do not meet the source code of ANSI / ISO C language standards, if you add

The -pedantic option, where the extension syntax will generate corresponding warning information:

# gcc -pedantic illmode.c: in function` Main ': Illcode.c: 9: ISO C89 Does Not Support `long'illcode.c: 8: Return Type of` main' is not `int '

It should be noted that the -pedant Compilation option does not guarantee that the compiled program is fully compatible with the ANSI / ISO C standard, it can only be used to help Linux

The programmer is getting closer and closer to this goal. Or in other words, the -pedantic option helps programmers find some code that does not conform to the ANSI / ISO C standard.

But not all, in fact there are only those situations requiring compiler diagnosis in the ANSI / ISO C language standard, it is possible to be discovered and warned by GCC.

In addition to -pedantic, some other compilation options can also produce useful warning messages. These options start with -w, where the most valuable

When you use -wall, use it enable GCC to generate as much warning message:

# gcc -wall illde.c: 8: Warning: Return Type of `main 'is not` int'illcode.c: in function `main': unlcode.c: 9: Warning: unused variable` Var '

Although the warning message given by GCC can't be considered a mistake, it is likely that it is a wrong habitual. A excellent Linux programmer

Try to avoid warning information, so that your code is always concise, beautiful and robust.

In terms of processing warning, another commonly used compilation option is -werror, which requires GCC to handle all warnings as an error, which is using automatic compiling workers

It is very useful when it is (such as Make, etc.) If you compile the -werror option, the GCC will stop compiling all where the warning is generated, forcing the programmer to

The code is modified. Only when the corresponding warning information is eliminated, the compilation process may continue to advance forward. The implementation is as follows: # gcc -wall -wrror illmode.c-iliccodecc1: warnings being treated as errorsillcode.c: 8: Warning: Return Type of `main 'is not` int'illcode.c: in function `main': Illcode.c: 9: Warning: unused variable` var.

For Linux programmers, the warning information given by GCC is valuable, but they can not only help programmers write more robust programs, but also track

And the powerful tool for debugging procedures. It is recommended to bring the -wall option when you compile the source code with GCC, and gradually cultivate it into a habit, which is a common

Implicit programming error is very helpful.

Library dependence

When developing software under Linux, it is relatively few cases that do not use third-party function libraries. Generally, it is necessary to support support with one or more functions libraries.

Can be able to complete the corresponding function. From the programmer's point of view, the library is actually a collection of some header files (.h) and library files (.so or .a). Although

Most functions under Linux default to put the header file in the / usr / include / directory, and the library file is placed in / usr / lib / directory, but not all

This is the case. For this reason, GCC must have its own way to find the header files and library files when compiling.

GCC uses a search directory to find the required file, the -i option to add a new directory to the GCC's header search path. For example, if

In the / home / xiaowp / include / directory, you can use the -i option to make GCC to find them smoothly:

# GCC foo.c -i / home / xiaowp / include -o foo

Similarly, if you use the library files that are not in the standard location, you can add a new directory to the GCC's library file search path via the -l option. For example, if

The library file libfoo.so required when there is a link when there is a link in the / home / xiaowp / lib / directory, in order to let the GCC can find it smoothly, you can use the following command:

# GCC foo.c -l / home / xiaowp / lib --lfoo -o foo

It is worth explaining that the -l option, it indicates that the library file under libfoo.so.linux will agree in the name of the GCC. That is

The beginning of the three letters of libs, because all library files follow the same specification, so you can save libs when using the -l option to specify a library name name.

Three letters, that is, GCC automatically connects files named libfoo.so when processing -LFOO is processed.

Library wording under Linux is divided into two categories: dynamic link library (usually .so end) and static link library (usually at the end of .a), the difference is only in the program

The code required for execution is dynamically loaded during runtime, or is static at compile time. By default, GCC prioritizes dynamic link libraries when linking.

The static link library is only considered when the dynamic link is not present, and if needed, you can add -static options when compiling, forcibly use the static link.

Library. For example, if there is a library file libfoo.so and libfoo.a required when there is a link in the / home / xiaowp / lib / directory, in order to make GCCs only in the link

To a static link library, you can use the following command:

# GCC foo.c -l / home / xiaowp / lib -static -lfoo -o foo code optimization

The code optimization refers to the compiler by analyzing the source code, finds the part thereof, and then combines it, the purpose is to improve the procedure

Row performance. The code optimization function provided by the GCC is very powerful. It controls the generation of optimized code by compiling option -on, where N is a representative optimization level.

Integer. For different versions of GCC, n's value range and its corresponding optimization effect may not be exactly the same, and the typical range is from 0 to 2 or

3.

When compiling, use the option -o can tell the GCC to reduce the length and execution time of the code, and its effect is equivalent to the -O1. Optimized class capable of this level

Although the type depends on the target processor, it will generally include both thread jump and deforered stack pops. Option -o2 tells GCC to complete all-O1 level optimization, To make some additional adjustments, such as processor instruction scheduling, etc. Option -o3

In addition to the optimization of all -O2 levels, it also includes loop deployment and other optimizations related to processor characteristics. Generally, the more digital

The higher the level, and it means that the faster the program is running. Many Linux programmers like to use the -O2 option because it is optimized, compile

The time and code size have achieved a relatively ideal balance point.

By following the specific examples, feel the GCC's code optimization function, and the procedures are shown in Listing 3.

Listing 3: Optimize.c

#include int main (void) {Double Counter; Double Result; Double Temp; for (counter = 0; counter <2000.0 * 2000.0 * 2000.0 / 20.0 2020; Counter = (5 - 1) / 4 ) {TEMP = Counter / 1979; result = counter;} Printf ("Result IS% LF / N", Result; Return 0;}

First do not add any optimization options:

# gcc -wall Optimize.c -o Optimize

With the Time command provided by Linux, it can be substantially statistics to the time required for the program at runtime:

# Time ./optimizeresult IS 400002019.000000Real 0M14.942SUSER 0M14.940ssys 0m0.000s

Next use Optimization options to optimize the code:

# gcc -wall -o Optimize.c -o Optimize

Test the runtime again under the same conditions:

# Time ./optimizeresult is 400002019.000000Real 0M3.256SUSER 0M3.240ssys 0m0.000s

It is not difficult to say that the output of the two execution is not difficult to see, the performance of the program has been greatly improved, which is shortened by the original 14 seconds to 3 seconds. This example is

It is designed for GCC optimization functions, so the execution speed of the program before and after the optimization has changed very much. Although GCC's code optimization is very strong

Big, but as an excellent Linux programmer, first, you should still strive to write high quality code manually. If the code written is short, and logical

Strong, the compiler will not do more work, even at all, not optimal.

Optimization can bring better execution performance to the procedure, but to avoid optimization code in some occasions:

◆ The higher the optimization level when the program is developed, the longer the time consumption, so it is best not to use the optimization option when developing, only to soft

The final generated code is optimized when the item is issued or developed.

◆ Some optimization options increase the volume of the executable code when the resource is limited, and if the program can apply in the run, the memory resources can be applied very nervous (eg

Some real-time embedded devices), do not optimize the code because the negative impacts caused by this may produce very serious consequences.

◆ When tracking debugging, some code may be deleted or overwritten, or reorganize for better performance.

This makes tracking and commissioning become extremely difficult.

debugging

A powerful debugger not only provides a means of tracking programs, but also helps programmers find ways to solve the problem. For

For Linux programmers, GDB (GNU Debugger) provides a perfect debugging environment for Linux-based software development with GCC.

By default, GCC does not insert debug symbols in the generated binary code when compiling, because this will increase the size of the executable file.

Generate debug symbol information when compiling, you can use the GCC-G or -GGDB option. When generates debug symbols, the development of grading is also adopted.

The member can specify how much adding debug information in the code after the -g option. The default level is 2 (-g2), and the debug information generated at this time includes the extended symbol table, the line number , Partial or external variable information. Level 3 (-g3) contains all debug information in level 2, and defined in source code

Macro. Level 1 (-g1) does not include local variables and debug information related to the line number, so it can only be used for backtracking tracking and stack dumps. Back tracking

The monitor program calls history during the running process, and the stack dump is a method of saving the program execution environment in the original hex format.

It is often used in debugging means.

The debug symbols generated by GCC have universal adaptability, which can be used by many debuses, but if you are using GDB, then you can also pass the -ggdb option.

In the generated binary code contains GDB dedicated debugging information. The advantage of this approach is that it can be convenient for GDB debugging, but the disadvantage is that other

The debugger (such as DBX) cannot perform normal debugging. The debug level and -GDB acceptable debug level and -g are exactly the same, and they have the output debug symbols.

The same impact.

It should be noted that using any of the debug options will increase the size of the final generated binaries, while adding the programs in execution,

So the debug options are usually only used in the development and commissioning phase of the software. Debug options can be seen from the following comparison process

:

# GCC Optimize.c -o Optimize # ls Optimize -l-rwxrwxr-x 1 xiaowp xiaowp 11649 NOV 20 08:53 Optimize # gcc -g Optimize.c-iptimize # ls Optimize -l-rwxrwxR -x 1 xiaowp xiaowp 15889 NOV 20 08:54 Optimize (joining debugging options)

Although the debug option increases the size of the file, in fact, many software in Linux still use debug options in the test version or even final release.

To compile, the purpose of doing this is to encourage users to solve their own problems when they find problems. It is a significant feature of Linux.

To debug code for debugging, in order to make GDB work normally, you must make your program contain debugging information when compiling. Debug information contains the type of each variable in your program and

Execute the address mapping in the file and the line number of the source code. GDB uses this information to associate the source code and the machine code. ◆ Open the debug option with the -g option when compiling.

GDB basic command GDB supports a lot of commands to enable you to achieve different features. These commands are loaded from simple files to allow you to check the contents of the stack content called.

Mysterite, Table 27.1 lists some of your commands you use when using GDB debugging. Want to know the details of GDB, please refer to the GDB guide page. Table 27.1. Basic GDB command. Command description File to put you want Debugged executable. Kill terminates the program being debugging. List lists a part of the source code that generates the execution file. Next executes a row source code but does not enter the function inside. STEP executes a row source code and enters the function inside. RUN execution Debugging program Quit Termination GDB Watch allows you to monitor the value of a variable regardless of whether it is changed. Break sets breakpoints in the code, which will cause the program to be hanged here. Make makes you free to quit GDB You can re-generate the executable. Shell allows you to execute the UNIX shell command without leaving GDB.

GDB supports a lot of command editing features like UNIX shell programs. You can press the Tab button like it in Bash or TCSH, let GDB help you make up

A unique command, if the GDB will list all the matching commands will be listed. You can also flip history commands with cursor keys.

Below below, how to use the debug symbol to analyze errors, and the program is shown in Listing 4.

Listing 4: Crash.c

#include int main (void) {INT INPUT = 0; Printf ("INPUT AN INTEGER:"); Scanf ("% D", INPUT); Printf ("THE INTEGER YOUT IS% D / N ", INPUT); RETURN 0;} Compiling and runs the above code, a segmentation fault is as follows:

# gcc -g crash.c -o crash # ./crashinput an integer: 10SEGMentation Fault

In order to find an error faster, you can use GDB to track debugging, the method is as follows:

# GDB Crashgnu GDB Red Hat Linux (5.3POST-0.20021129.18RH) ... (GDB)

When the GDB prompt appears, it indicates that the GDB is ready to debug, and now you can start running under the GDB monitoring through the run command:

(GDB) Runstarting Program: / Home / XIaowp / Thesis / GCC / CODE / CRASHINPUT AN INTEGER: 10

Program received signal sigsegv, segmentation fault.0x4008576b in _io_vfscanf_internal () from /lib/libc.so.6

Taking a closer analysis of the output results given by GDB is not difficult to see, the program is due to the abnormal suspension, indicating that the memory operation has problems, and the specific occurrence

The location of the problem is when calling _io_vfscanf_internal (). In order to get more valuable information, you can use the backtracks that GDBs.

Let Backtrace, the execution results are as follows:

(GDB) Backtrace # 0 0x4008576b in _io_vfscanf_internal () from /Lib/libc.so.6#1 0xBfff0c0 in ?? () # 2 0x4008e0ba in scanf () from /lib/libc.so.6#3 0x08048393 in main ) AT CRASH.C: 11 # 4 0x40042917 in __libc_start_main () from /lib/libc.so.6

The front three lines in the output result, it is not difficult to see from the fourth line of the output results, GDB has locked the error to the 11th line in Crash.c. Now carefully

check:

(GDB) Frame 3 # 3 0x08048393 in main () AT Crash.c: 1111 scanf ("% d", input);

The frame command provided with GDB can be positioned to the code segment that has occurred, and the value followed by the command can be in the output of the backtrace command.

The lead is found. Now I have found the error, it should be

Scanf ("% D", INPUT); changed to scanf ("% d", & input);

You can exit GDB after completion, the command is as follows:

(GDB) quit

The function of GDB is far more than that, it can also check the program, check the memory variable and set breakpoints.

In debugging, you may need to use the intermediate result generated by the compiler. You can use the -save-temps option, let GCC will prepare code, assemble code, and purpose.

The label code is saved as a file. If you want to check if the generated code can improve the performance performance by manual adjustment, during the compilation process

The middle document will be helpful, the specific situation is as follows:

# GCC -SAVE-TEMPS foo.c -o foo # ls foo * foo foo.c foo.i foo.s

Other debug options supported by GCC also include -p and -pg, which adds profiling information to the finalized binary code. Assection information pair

The performance bottleneck to find out the program is very helpful. It is a powerful tool to assist Linux programmers to develop high-performance programs. Join the -p option when compiling will be generated

Add a common profiling tool (PROF) to identify statistics, while the -pg option generates only GNU profiling tool (GPROF) to identify statistics.

Finally, remind it, although GCC allows the addition of debug symbol information while optimization, the optimized code will be a big challenge for commissioning itself.

After optimization, the code is probably not used in the source program, and the control flow may suddenly jump to unexpected places.

The statement is likely to become everywhere due to the loop deployment, all of these will be a nightmare. It is recommended that it is best not to use anything when debugging.

Optimization options are only optimized when the program is considered when the program is finalized.

The last training garden is introduced to the GCC's compilation process, warning prompt function, library dependence, code optimization, and program calls. This is the most

The following part of the content.

accelerate

During the process of turning the source code into an executable file, there is a need to pass through many intermediate steps, including pre-processing, compile, assembly, and connection. These processes are actually

Different procedures are responsible for it. Most cases GCC can complete all background work for Linux programmers, automatically call the appropriate program for processing.

This has a significant shortcoming, that is, the GCC will eventually generate several temporary files to complete the corresponding work when processing each source file.

Thus invisible results in slowing the processing speed. For example, when the GCC is processed, a temporary file may need a temporary file to save the pre-processed output, one

Time files to save the output of the compiler, a temporary file to save the output of the assembler, and read and write these temporary documents clearly take a certain time. When

When the software project becomes very large, it will be very heavy.

The solution is to use a more efficient communication method for Linux. It can be used to connect two programs at the same time, one of the programs

This will be used as an input to another program, so you can avoid using temporary files, but it needs to consume more memory when compiling.

The use of the pipe is determined by the -pipe option during the compilation process. The following command is to improve compilation speed by means of the GCC pipe function:

# GCC -PIPE foo.c -o foo

The difference in compilation time is not very obvious when compiling small works, but it will become very good in large projects in the source code.

obvious.

File extension

In the process of using GCC, users must be familiar with some commonly used extensions and know their meaning. In order to facilitate everyone to learn to use GCC, they will expand these

The name of the name is as follows:

.c C original procedure;

.C C original program;

.cc C original program;

.cxx C original program;

.m Objective-c original program;

.i has been pre-treated C original procedure;

.ii has been pre-processed C original procedure;

.S combined language original program;

.S combined language original program;

H. Pre-processing file (header file);

Target file;

.a archive file.

GCC common option

As the important compilation environment of C / C under Linux, the GCC is powerful, the compiled options are more compiled. In order to facilitate everyone to compile, it will always use the options and say

Minglu is listed as follows:

-c Notification GCC Cancellation Link step, that is, compile the source code and finally generate the target file;

-Dmacro defines the specified macro, allowing it to be inspected through #ifdef in the source code;

-E is delivered to standard output without the output of the compiled pre-processing program;

-g3 gets detailed information about the debugger, it cannot be used in combination with the -O option;

-Idirectory adds a specified directory at the beginning of the included file search path;

-llibrary prompts the link to include the specified library when creating the final executable file;

-O, -O2, and -O3 open the optimized state, this option cannot be combined with the -g option;

-S requires the compiler to generate assembler output from source code;

-v starts all alerts;

-Wall cancels compile operations when an alarm is happened, and the alert will be regarded as an error;

-Wrror cancels the compilation operation when an alert occurs, ie the alarm is used as an error;

-W prohibits all alarms. Small knot

GCC is one of the tools that must be mastered when developing programs under Linux. This article has made a brief introduction to GCC, mainly telling how to use GCC compiler

Generate warning information, debugging procedures, and speeding up GCC compilation speed. GCC is a one that hopes to enter Linux developers soon.

Excellent linux programmer's starting line.

转载请注明原文地址:https://www.9cbs.com/read-121099.html

New Post(0)