How to speed up Compile Time of my CMake enabled C++ Project?

Solution 1:

Here's what I had good results with using CMake and Visual Studio or GNU toolchains:

  1. Exchange GNU make with Ninja. It's faster, makes use of all available CPU cores automatically and has a good dependency management. Just be aware of

    a.) You need to setup the target dependencies in CMake correctly. If you get to a point where the build has a dependency to another artifact, it has to wait until those are compiled (synchronization points).

    $ time -p cmake -G "Ninja" ..
    -- The CXX compiler identification is GNU 4.8.1
    ...
    real 11.06
    user 0.00
    sys 0.00
    
    $ time -p ninja
    ...
    [202/202] Linking CXX executable CMakeTest.exe
    real 40.31
    user 0.01
    sys 0.01
    

    b.) Linking is always such a synchronization point. So you can make more use of CMake's Object Libraries to reduce those, but it makes your CMake code a little bit uglier.

    $ time -p ninja
    ...
    [102/102] Linking CXX executable CMakeTest.exe
    real 27.62
    user 0.00
    sys 0.04
    
  2. Split less frequently changed or stable code parts into separate CMake projects and use CMake's ExternalProject_Add() or - if you e.g. switch to binary delivery of some libraries - find_library().

  3. Think of a different set of compiler/linker options for your daily work (but only if you also have some test time/experience with the final release build options).

    a.) Skip the optimization parts

    b.) Try incremental linking

  4. If you often do changes to the CMake code itself, think about rebuilding CMake from sources optimized for your machine's architecture. CMake's officially distributed binaries are just a compromise to work on every possible CPU architecture.

    When I use MinGW64/MSYS to rebuild CMake 3.5.2 with e.g.

    cmake -DCMAKE_BUILD_TYPE:STRING="Release"
          -DCMAKE_CXX_FLAGS:STRING="-march=native -m64 -Ofast -flto" 
          -DCMAKE_EXE_LINKER_FLAGS:STRING="-Wl,--allow-multiple-definition"
          -G "MSYS Makefiles" .. 
    

    I can accelerate the first part:

    $ time -p [...]/MSYS64/bin/cmake.exe -G "Ninja" ..
    real 6.46
    user 0.03
    sys 0.01
    
  5. If your file I/O is very slow and since CMake works with dedicated binary output directories, make use of a RAM disk. If you still use a hard drive, consider switching to a solid state disk.

  6. Depending of your final output file, exchange the GNU standard linker with the Gold Linker. Even faster than Gold Linker is lld from the LLVM project. You have to check whether it supports already the needed features on your platform.

  7. Use Clang/c2 instead of Visual C++ compiler. For the Visual C++ compiler performance recommendations are provided from the Visual C++ team, see https://blogs.msdn.microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in-visual-studio/

  8. Increadibuild can boost the compilation time.

References

  • CMake: How to setup Source, Library and CMakeLists.txt dependencies?
  • Replacing ld with gold - any experience?
  • Is the lld linker a drop-in replacement for ld and gold?