如何加速使用CMake编译的C++项目的编译时间?

24

最近我遇到了一些关于改善使用CMake的C ++项目周转时间的具体方面的stackoverflow问题(例如“在什么级别上应该分发我的构建过程?”“cmake重建缓存是否只适用于子目录?”),我想知道是否有更一般的指导,利用CMake提供的特定可能性。如果可能没有跨平台编译时间优化,我主要对基于Visual Studio或GNU toochain的方法感兴趣。

而且我已经了解并投资于通常推荐的加速C ++构建的领域:

  1. 更改/优化/微调工具链

  2. 优化代码库/软件架构(例如通过减少依赖项和使用明确定义的子项目-单元测试)

  3. 投资更好的硬件(SSD,CPU,内存)

如此推荐这里这里这里。因此,我的重点在于第一点。

此外,我知道可以在CMake的Wiki中找到建议:

前者只处理基础知识(并行制作),后者主要处理如何加速解析CMake文件。

为了使这更具体些,如果我以这里的CMake示例为例,使用100个库使用MSYS/GNU,我得到了以下time测量结果:

$ cmake --version
cmake version 3.5.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ time -p cmake -G "MSYS Makefiles" ..
-- The CXX compiler identification is GNU 4.8.1
...
-- Configuring done
-- Generating done
-- Build files have been written to: [...]
real 27.03
user 0.01
sys 0.03        

$ time -p make -j8
...
[100%] Built target CMakeTest
real 113.11
user 8.82
sys 33.08

所以我总共有大约140秒的时间,我的目标——针对这个非常简单的例子——是将它缩短到使用标准设置/工具时的10-20%左右。

2个回答

20

下面是我使用CMake和Visual Studio或GNU工具链获得好结果的方法:

  1. Ninja替代GNU make。它更快,自动利用所有可用的CPU核心,并具有良好的依赖关系管理。只需注意:

    a.) 您需要在CMake中正确设置目标依赖项。如果您到达一个点,其中构建依赖于另一个artifact,则必须等待这些内容被编译(同步点)。

$ 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.) 链接总是一个同步点。因此,您可以更多地利用CMake的对象库来减少这些同步点,但这会使您的CMake代码有点丑陋。

$ time -p ninja
...
[102/102] Linking CXX executable CMakeTest.exe
real 27.62
user 0.00
sys 0.04
  • 将不经常更改或稳定的代码部分拆分为单独的CMake项目,并使用CMake的ExternalProject_Add()或-如果您切换到某些库的二进制交付-find_library()

  • 想想在日常工作中是否需要一组不同的编译器/链接器选项(但前提是您还有一些关于最终发布版本构建选项的测试时间/经验)。

    a)跳过优化部分

    b)尝试增量链接

  • 如果您经常对CMake代码进行更改,请考虑从针对计算机体系结构进行优化的源代码重新构建CMake。 CMake的官方分发二进制文件只是为了适用于每种可能的CPU架构而做出的妥协。

    当我使用MinGW64 / MSYS重新构建CMake 3.5.2时,例如

  • 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" .. 
    

    我可以加速第一部分:

    $ time -p [...]/MSYS64/bin/cmake.exe -G "Ninja" ..
    real 6.46
    user 0.03
    sys 0.01
    
  • 如果你的文件输入/输出很慢,由于CMake可以处理专用的二进制输出目录,请使用RAM磁盘。如果你仍在使用硬盘,请考虑切换到固态硬盘。

  • 根据最终的输出文件,用GNU标准链接器替换Gold链接器。比Gold链接器更快的是来自LLVM项目的lld。你必须检查它是否已经支持了你平台上需要的功能。

  • 使用Clang/c2代替Visual C++编译器。对于Visual C++编译器的性能建议由Visual C++团队提供,请参见https://blogs.msdn.microsoft.com/vcblog/2016/10/26/recommendations-to-speed-c-builds-in-visual-studio/

  • Increadibuild可以提高编译时间。

  • 参考文献


    另外,使用ccache。它可以使重新编译变得非常快速。 - csl
    1
    如果您的构建系统能够正确地执行增量重建,则ccache应该没有什么帮助。在编写良好且正确执行增量构建的cmake构建中,ccache实际上会因其开销而减慢速度。然而,在过去的一些项目中,我曾经成功地使用ccache,这些项目具有糟糕的构建系统,无法进行增量编译(例如firefox,多年前)。 - Chris Kitching

    0

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接