Gch file: GCC pre-compiled header technology favorites

Source: Internet
Author: User
Tags what header

When I started programming, I did not pay much attention to compilation speed and other issues. The reason was very simple, because I used basica at that time. Later, I used C ++ builder. Even though Borland's advertisements boast about its compilation speed all the time, I never worried about this problem, because there is no such concept as "Slow compilation" in mind. No bad. Why? The so-called unity of opposites. The first slow compiler may be javac, but it is tolerated because of the special nature of Java. It's the first time GCC was used ...... Specifically, mingw. The open-source world has given me many surprises. One is that the compiler can be so slow. At that time, I could not help but admire the open-source community. They used such compilers to create a colorful world! At that time, I realized that Borland was really amazing.

Today, I am not very familiar with how Borland does it. For a long time, I have no idea where GCC is. However ...... Once upon a whim, I suddenly wanted to see all the header files loaded during mingw compilation. The-H parameter is used. The results are satisfactory. There are so many header files loaded. Next ...... Start to feel something else. Dare to say, most of the compilation time is wasted here? -- The concept of "pre-compiled headers" is as powerful as a whale.

The pre-compiled header technology is first known in VC. Its Improvement in Compilation speed is definitely impressive. When I used mingw, I forgot this old spell. Is it exactly what I need? The results were disappointing in a few hundred times, and the literature on this aspect was rare. what's even more frustrating is that many people believe that GCC has no pre-compiled header technology. I open the GCC official document to find the precompiled headers. Slow, so smooth! -- The official document is not long, but it is enough for me to shout Long live ~ No more. One sentence is enough. How can this problem be solved? Simply compile it!

The so-called pre-compilation header is to compile the header file into a binary intermediate format for later compilation. Do not match the intermediate format. O /. OBJ /. a /. lib format obfuscation, they are completely different, so the features of the pre-compiled header file and the target file are also different (although they all belong to some intermediate file ). -- But there are some similarities. For example, they are all incompatible with compilers, which means you cannot take the pre-compilation headers generated by VC to GCC for use. Even the extension names are different. VC is familiar to all. PCH, while GCC is the main character of. gch today.

Why use the pre-compiled header? This makes it clearer and increases the compilation speed. Why does the compilation speed increase? To put it this way, you have two files a. cpp and B. cpp, both of which contain the same header file C. H. The normal process is to change C. H and. merge CPP and compile it into. o. H and B. merge CPP and compile it into B. o; finally, set. O and B. OSS is linked to an executable file. The process is simple and time-consuming. The header file C. H is actually parsed twice. You may want to say that it will take two times, because the header file almost does not generate any code. It makes sense only when it is attached to a specific. cpp file. Correct, but it is only in the code execution process. But what about code compilation? The compiler first parses the source code into an internal representation. This process is associated with it. the CPP file does not matter. The compiler can then read it. the CPP file is also parsed into an internal representation, and the internal representation of the two segments is spliced, and then the following operations are performed. Since two. for CPP files. h. h. After parsing and saving it as a temporary file, will it save a parsing time when it is read? -- The time-saving principle of the pre-compiled header technology is here, especially in the fact that "Parsing" the source code, it is indeed a considerable part of the compilation time.

I saw your suspicious face: preprocessing, processing before compilation, and merging. H and. the CPP file is clearly a preprocessing step, while the parsing of source code is a compilation step. After parsing, merge? Why does the "pre-" process go to the compilation step instead? Is this also called "pre? -- We decided not to go further into this issue. After all, the current compiler has long confused the boundaries between preprocessing and compilation ...... After all, this is a matter of use, right?

Let's take a look at the results. Write a C ++ Hello world and use cout to output a line of words. What header files are contained? Of course, it is iostream. This header file is absolutely invisible to people. However, when using it, do you notice the "crimes" behind the compiler? Yes. Use the-H parameter to compile the Hello world! How many header files are loaded? There are 103 in total on my machine!

Yes, you should make them into a. gch file. How to do it? As mentioned above, it's easy: just compile it:

G ++ XXX. h

In a word, the. h file is compiled like A. cpp file. This is the simplest. If you need to control compilation details, such as constant definitions, you can add other options. After running, you will find that a file named XXX. H. gch is generated in the same directory. This is what we want. Maybe you can't wait to try G ++ iostream like me? Haha, the result must be the same as that of me-in the compilation. during gch, GCC does not use environment variables or-I options to find the compiled header file. The compiled header file must be in the current directory. However, the other header files further included in the compiled header files can be found through the above methods. Simply put, the header file compiled directly is processed in a similar way to the. cpp file. Do you know how to compile iostream now? Yes. Create a header file in the current directory and name it as you like, such as Foo. h, write: # include <iostream> in it, and compile it: G ++ Foo. h. The generated Foo. H. gch is what we want. Iostream is required for other files. do not include iostream, but include Foo. h. Remember not to include Foo. H. gch!

If you have used VC, then Foo. h may make you feel familiar? By the way, it is equivalent to the stdafx. H! You should also remember that every file containing the foo. H should be at the beginning of the file; otherwise, an error will occur. Really, I finally found stdafx. h in GCC. This feeling is almost tearful.

Next, copy some stdafx. h. They also apply. gch files: Put the header files that are not often modified (first, of course, the system) in the pre-compilation header, and the header files that are part of your program, it is generally not placed in the pre-compilation header, because they may be modified at any time. The pre-compilation header will be re-generated every time it is modified. There is no speed advantage, and the meaning of the pre-compilation header is lost. Another important note is: If you use some options when generating the pre-compilation header, such as macro definition, use other source code files in the pre-compilation header, these options must also be used during compilation. Otherwise, compilation fails because of mismatch.

By the way, I have never talked about how to use the pre-compiled headers. However, you should understand it here. Yes, it's very simple. You just need to include the. h file corresponding to it! For example, you have a header file named Foo. h. There are a lot of other files that contain the foo. h. I didn't use the pre-compiled header technology. Now I suddenly want to use it, so I put Foo. h compiled into Foo. h. gch. What are the changes to other files? -- No need for anything. Everything is the same! The clever GCC compiler is searching for. before the H file, it will automatically find whether there is a corresponding in its directory. gch files, if available and available, are used. h header file. -- Slow down. What is "available" if "available "? -- This indicates that the. gch format must be correct and the version must be compatible. As mentioned above, the two must use the same option for compiling. If. gch is unavailable, the compiler will give a warning that this pre-compilation header is not available! I have to use the original. h header file! What? You said you couldn't see this warning? -- Of course, you must first enable the-winvalid-PCH option, which is disabled by default.

Use the-H option to check whether the pre-compiled header is refreshing! There is no endless header file to be rolled back. The improved speed will definitely give you a feeling of turning over and liberation. The original mingw can also say goodbye to the snail like speed.

Note: A colleague accidentally generated. gch, but the compilation options were inconsistent, which made it impossible to compile later. Be careful with mines

///////////////////////////////////////

 

Since version 3.4.x and version 4.x, gnu cc also supports this mechanism to improve compilation efficiency. The reason is that the using precompiled headers section in the gnu cc Manual does not provide much information about this, and there is no simple automatic project management tool to support this function, therefore, many netizens do not know the gnu cc function.

In the gnu cc manual, we recommend that you use make to manage pre-compiled header files. It is also pointed out that the pre-compiled header files in C language are different from the pre-compiled header files in C ++ language. Here, we will first describe the situation that the project only has the C language source file or only the C ++ language source file, and then describe the situation that the source files in both languages exist simultaneously in the project.

Only one pre-compiled header file needs to be created when the project only contains source files in C or C ++.

  1. Create a header file, for example, Inc. h. This file is used by all C/C ++ source files in the project. List the header files required by the entire project:

    /* $FreeBSD$ */#ifndef_INC_H_#define_INC_H_#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <sys/types.h>#include <sys/uio.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif /* ! _INC_H_ *
  2. Create makefile to maintain the pre-compiled header file. On the one hand, we need to establish a pre-compiled header file Inc. h. gch rules; on the other hand, check Inc. h. gch, that is, let all. O files depend on Inc. h. gch.
    # $FreeBSD$CC=gccCFLAGS=-g -WallCXX=gccCXXFLAGS=-g -WallLD=gccLDFLAGS=-g -WallEXE=testappPCH_H=inc.hPCH=inc.h.gchSRCS=testapp.cOBJS=testapp.oLIBS=# System LibrariesECHO=echoCP=cp -vRM=rm -f.SUFFIXES:.SUFFIXES: .o .c .cxx# The meaning of "$<":#     BSD Pmake: the implied source#     GNU make: the first prerequisite.c.o:$(CC) $(CFLAGS) -c $<.cxx.o:$(CXX) $(CXXFLAGS) -c $<all:$(EXE)#                  $>                    $^# BSD Pmake    all sources        not defined# GNU make     not defined        all prerequisites# Both interpret "$@" as target$(EXE):$(OBJS) $(LIBBDD)$(LD) $(LDFLAGS) -o $@ $> $^ $(LIBS)# Pre-compiled header$(OBJS): $(PCH)$(PCH): $(PCH_H)$(CC) $(CFLAGS) $> $^clean:$(RM) $(PCH) $(OBJS)# For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin)$(RM) $(EXE) $(EXE).exe

If the project contains both the C and C ++ source files, you need to maintain a pre-compiled header file for both languages.

  1. Create a header file, for example, Inc. HPP. Inc. h is used by the C language source file, while Inc. HPP is used by the C ++ language file. If the content of Inc. HPP is the same as that of Inc. H, simply write:

    /* $FreeBSD$ */#ifndef_INC_HPP_#define_INC_HPP_#include "inc.h"#endif /* ! _INC_HPP_ */
  2. The maintenance of Inc. HPP should also be added in makefile. First, increase the generation of Inc. HPP. gch rules. When running gnu cc, add the parameter "-x C ++-header". Second, delete the pre-compiled header file in the clean section.
    # $FreeBSD$CC=gccCFLAGS=-g -WallCXX=gccCXXFLAGS=-g -WallLD=gccLDFLAGS=-g -WallEXE=testappPCH_H=inc.hPCH=inc.h.gchPCH_X_H=inc.hppPCH_X=inc.hpp.gchSRCS=testapp.cOBJS=testapp.oLIBS=# System LibrariesECHO=echoCP=cp -vRM=rm -f.SUFFIXES:.SUFFIXES: .o .c .cxx# The meaning of "$<":#     BSD Pmake: the implied source#     GNU make: the first prerequisite.c.o:$(CC) $(CFLAGS) -c $<.cxx.o:$(CXX) $(CXXFLAGS) -c $<all:$(EXE)#                  $>                    $^# BSD Pmake    all sources        not defined# GNU make     not defined        all prerequisites# Both interpret "$@" as target$(EXE):$(OBJS) $(LIBBDD)$(LD) $(LDFLAGS) -o $@ $> $^ $(LIBS)# Pre-compiled header$(OBJS): $(PCH)$(PCH): $(PCH_H)$(CC) $(CFLAGS) $> $^$(PCH_X): $(PCH_X_H)$(CXX) $(CXXFLAGS) -x c++-header $> $^clean:$(RM) $(PCH) $(PCH_X) $(OBJS)# For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin)$(RM) $(EXE) $(EXE).exe

This is a comparison of the above two makefiles:

@@ -12,6 +12,8 @@ EXE=testapp PCH_H=inc.h PCH=inc.h.gch+PCH_X_H=inc.hpp+PCH_X=inc.hpp.gch SRCS=testapp.c OBJS=testapp.o LIBS=# System Libraries@@ -48,7 +50,10 @@ $(PCH): $(PCH_H) $(CC) $(CFLAGS) $> $^ +$(PCH_X): $(PCH_X_H)+$(CXX) $(CXXFLAGS) -x c++-header $> $^+ clean:-$(RM) $(PCH) $(OBJS)+$(RM) $(PCH) $(PCH_X) $(OBJS) # For Both UNIX-like OS and Microsoft Windows (MinGW/Cygwin) $(RM) $(EXE) $(EXE).exe

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.