user896326
user896326

Reputation:

How do compilers know when not to recompile?

How do compilers know when it is not necessary to recompile certain parts of code especially in larger projects?


For example, let's say in C++ we have two C++ files and two header files. The header files depend on one another. (They use the classes specified in each others files.)

Does a compiler always need to parse both header files, (and maybe C++ files for method implementation,) to obtain the class information in order to generate either of the two C++ files?


I always thought that when you run the compiler at the command prompt, it closes immediately after outputting the object files - so it would be impossible to cache the Abstract Syntax Trees or intermediate code. Do most C++ compilers know when a certain file doesn't need to output to an object file, and is therefore skipped?

Upvotes: 4

Views: 1591

Answers (3)

doron
doron

Reputation: 28892

As said above, compilers will compiler every file that it is asked to compile. It is up to tools like make to decide what needs to be compiled.

In make one sets up rules. Each rule has a target, list of dependencies followed by the commands to run if those dependencies are not met. For example

target.o : target.c
    gcc -c -o target.o target.c

On most file systems, each file has a timestamp. If target.o has a newer timestamp than target.c (the rule dependency) then make does not run the gcc command below. This is because one firsts edits a source file and then compiles the source file into an object file.

If however the dependent source file is newer than the target, then we know the source file was edited after the compile took place and another compile is in order. make will therefore execute the build command for the rule.

It gets a lot more complex when rules are dependent on other rules but the same principle applies.

Upvotes: 2

xanatos
xanatos

Reputation: 111890

I don't know how they (don't) implement it (because many don't... Don't ask me why) but I'm quite sure it would be VERY easy. You save in the intermediate (obj) file the name and the hash of the source file and of every dependent file you are compiling, together with the compilation options that are being used, the hash of the compiler (or its internal version) and the compilation result (ok/error). Next time the user tries to recompile the file, the compiler checks if there is already the intermediate file, checks if all the hashes are the same, if the compilation options are the same and if the compiler is the same... If everything is the same, it gives the pre-saved error message and exits without doing anything.

The intermediate files would be a little bigger (probably some kb each).

Upvotes: 0

James Kanze
James Kanze

Reputation: 153967

All of the compilers I know compile every source file they're told to. Always. And they generate a new version of the object file for every source file they compile.

Only compiling what is necessary is a job generally left to the build system (make or other). Knowing which objects need to be regenerated depend on what each source file includes, directly or indirectly; most compilers have options to output this information in some format, either on the fly or as a separate invocation, and the build systems (the usable ones, at least) use this information to determine dependencies.

Upvotes: 3

Related Questions