0

I just converted an Objective-C(++) project to plain C++. While moving more and more code over, I noticed the build time increase quite a lot.

My project is currently split up into several frameworks/dylibs and a main project which uses these frameworks.

I did some research and found that there are basically three things recommended to reduce the build time:

  • reducing header dependencies
  • using unity builds
  • using a tool like ccache to not redo unneeded work all the time

I implemented ccache and it works great and I was able to decrease the build time quite a bit.

I'm a bit unsure though about reducing the header dependencies and the unity builds. I read that a big downside of the unity builds is that you need to recompile everything if you make changes in one source file which makes sense. That however would not be a problem for the frameworks as they will need to be recompiled anyways if they change.

I read that it's bad practice to use "umbrella headers" such as "MyFramework.h" which will include all the public headers of a given framework although you may only need a few of them.

Cocoa uses umbrella headers everywhere and it's of course much easier than to pick the exact headers needed for each source file. However, when using unity builds I will only have one header per framework, correct?

Does it still make sense to pick the individual headers or will using "umbrella headers" be ok with unity builds?

Tapping a bit in the dark here and don't want to spend time implementing a technique which doesn't help in the end.

Thanks for your help!

guitarflow
  • 2,930
  • 25
  • 38
  • Unity build is a "quick and dirty" variant of single compilation unit build. And the thing with single compilation unit build is that recompiling everything on each build is no longer a problem. It also completely eliminates need for dependency tracking / caching tools. – user7860670 Sep 20 '18 at 11:18
  • But unity build prevents you from running compilation in parallel. – Anty Sep 20 '18 at 11:20
  • @Anty SCU build makes parallel compilation on module (binary artifact) level not applicable since there is only a single item to compile while still working drastically faster. But it does not prevent parallel compilation of multiple modules. – user7860670 Sep 20 '18 at 11:27
  • related [What are the drawbacks of single source project structures](https://stackoverflow.com/questions/46319579/what-are-the-drawbacks-of-single-source-project-structures/46321758#46321758) – user7860670 Sep 20 '18 at 12:40

1 Answers1

-1

It feels like question for opinionated answers. Mine are such:

Always reduce header dependencies. Reduced dependencies make overall architecture cleaner. Independent little individual modules with clear responsibilities loosely coupled are always better to work with than spaghetti.

Use precompiled headers for compiling rarely changing headers. The third party, library and framework umbrella headers change rarely and so need to be rarely parsed and recompiled too.

Work most of the time with separate units (few cpp files) and unit tests for those. Otherwise you build whole program, then navigate in it to situation of interest then step with debugger there and so on. May be you like it but I'm too lazy, it is boring repetitive and wastes my time. Only linking of whole C++ program (worth anything) takes usually ten minutes or more and I don't need so many coffee-breaks.

Do not use unity builds, better use continuous integration that when you push automatically builds and runs all the unit tests of whole program and prepares binaries on other computer (or farm). You will be notified when it is done (or did fail) and then you can take the binaries and debug whole program too if you want to.

Öö Tiib
  • 10,809
  • 25
  • 44
  • This is rather misleading. First of all this is not opinion based matter because technically one can try implementing different approaches for the same project and measure build times (spoiler: SCU will be drastically faster). Stated contradistinction between continuous integration and SCU build makes no sense because continuous integration seems to be the primary driver for SCU builds because it allows to cut rebuild time. Basically with SCU you will never have to waste ten minutes or more for linking. – user7860670 Sep 20 '18 at 13:13
  • Note that there are serious reasons for avoiding SKU (especially for existing large codebases with little tests) and I would not recommend to use unity builds (because it is a half-measure) either. However compilation speed is not one of them. – user7860670 Sep 20 '18 at 13:17
  • @VTT I did not say that the unity builds make rebuild slower but that these make all work slower continuous integration or not. Just pure pain. Running all unit tests of decent code base takes half an hour in my experience. What did actually reduce compilation in my experience: reduce dependencies, have little independent modules and use precompiled headers. As of link time, it will take several minutes anyway with any decent code base. Just download chromium and build it. How long it links? Now do SCU of chromium. How lot of man-weeks it takes? Will it link way quicker? – Öö Tiib Sep 20 '18 at 16:03
  • @VTT also tone of your comments indicates how deeply opinionated the topic is. – Öö Tiib Sep 20 '18 at 16:05
  • How can they make work slower if building process becomes faster then? Also you now state that use of precompiled headers actually did reduce compilation time, but in your answer you suggest to use precompiled headers rarely. As for chromium, it already has [Unity build support which *"compiles significantly faster"* and *"Linking is faster because there is less redundant data (debug information, inline functions) to merge."*](https://chromium.googlesource.com/chromium/src/+/master/docs/jumbo.md#jumbo-unity-builds) – user7860670 Sep 20 '18 at 16:49
  • @VTT my bad English. I meant precompiled headers make most of the include cascade (sometimes millions lines of code) compiled rarely. Tried to edit it into more precise. – Öö Tiib Sep 20 '18 at 16:58
  • @VTT because I explained: rebuilding whole program is not part of my work process. I mostly work on few tightly connected files in separation, when it seems to be implemented by my tests then I push my changes and take to work on other ticket in other branch. When the pushed branch is reported good by continuous integration then I can try and run whole program and if it looks good put up as pull request. Merging cpp files of project into fewer (or even just one) file is pointless work that you yourself said there are serious reasons to avoid. Well ... avoiding dealing with these saves time. – Öö Tiib Sep 20 '18 at 17:16
  • @VTT other people may have different work processes and experiences and code bases to deal with and so it is obviously opinionated topic. – Öö Tiib Sep 20 '18 at 17:27
  • I guess your workflow is pretty common. And this is the exact workflow that can benefit from the use of SKU build. Basically you've described the pitfalls the SKU allows to avoid: you have to wait while project build at least twice with at least one full rebuild (which takes a lot of time for large product), you have to work with few tightly connected files in separation (and probably trying to avoid frequent modification of common header files, especially those that are used by other devs, so they won't get mad at you after being forced to recompile their stuff). – user7860670 Sep 20 '18 at 18:06
  • The question of whether it is worth the effort to convert particular project into header only or to make it utilize unity build may be opinionated topic, however the question of whether SKU offers build speed up is not, because it is about measurable time. – user7860670 Sep 20 '18 at 18:11
  • @VTT No, I can compile and run the unit tests for the few files I work with after every line of code I type because these build and run a second or two. Full set of unit tests builds and runs half an hour. Not running these before full product build each time will therefore save half an hour of build time (of continuous integration system), but can cause several hours of time of several people wasted. – Öö Tiib Sep 20 '18 at 19:59