Any recommended practices for cleaning up "header spaghetti" which is causing extremely slow compilation times (Linux/Unix)?
Is there any equvalent to "#pragma once" with GCC?
(found conflicting messages regarding this)
Thanks.
Any recommended practices for cleaning up "header spaghetti" which is causing extremely slow compilation times (Linux/Unix)?
Is there any equvalent to "#pragma once" with GCC?
(found conflicting messages regarding this)
Thanks.
Richard was somewhat right (Why his solution was noted down?).
Anyway, all C/C++ headers should use internal include guards.
This said, either:
1 - Your legacy code is not really maintained anymore, and you should use pre-compiled headers (which are a hack, but hey... Your need is to speed up your compilation, not refactor unmaintained code)
2 - Your legacy code is still living. Then, you either use the precompiled headers and/or the guards/external guards for a temporary solution, but in the end, you'll need to remove all your includes, one .C or .CPP at a time, and compile each .C or .CPP file one at a time, correcting their includes with forward-declarations or includes when necessary (or even breaking a large include into smaller ones to be sure each .C or .CPP file will get only the headers it needs). Anyway, testing and removing obsolete includes is part of maintenance of a project, so...
My own experience with precompiled headers was not exactly a good one, because half the time, the compiler could not find a symbol I had defined, and so I tried a full "clean/rebuild", to be sure it was not the precompiled header that was obsolete. So my guess is to use it for external libraries you won't even touch (like the STL, C API headers, Boost, whatever). Still, my own experience was with Visual C++ 6, so I guess (hope?) they got it right, now.
Now, one last thing: Headers should always be self-sufficient. That means that if the inclusion of headers depends on order of inclusion, then you have a problem. For example, if you can write:
But not:
because BBB depends on AAA, then all you have is a dependency you never acknowledged in the code. Not acknowledging it with a define will only make your compilation a nightmare. BBB should include AAA, too (even if it could be somewhat slower: in the end, forward-declarations will anyway clean useless includes, so you should have a faster compile timer).
As onebyone.livejournal.com commented in a response to your question, some compilers support include guard optimization, which the page I linked defines as follows:
Then again, you already answered that external include guards are not the answer to your question. For disentangling header files that must be included in a specific order, I would suggest the following:
.c
or.cpp
file should#include
the corresponding.h
file first, and the rest of its#include
directives should be sorted alphabetically. You will usually get build errors when this breaks unstated dependencies between header files.#define
directives that are used for most of the code, each.h
file should#include
that file first, and the rest of its#include
directives should be sorted alphabetically.#include
.It also sounds like part of the problem might be that incremental builds are much slower than they ought to be. This situation can be improved with forward declarations or a distributed build system, as others have pointed out.
Use one or more of those for speeding up the build time
As mentioned in the other answer, you should definitely use forward declarations whenever possible. To my knowledge, GCC doesn't have anything equivalent to #pragma once, which is why I stick to the old fashion style of include guards.
Thanks for the replies, but the question is regarding existing code which includes strict "include order" etc. The question is whether there are any tools/scripts to clarify what is actually going on.
Header guards arent the solution as they dont prevent the compiler from reading the whole file again and again and ...