Как ускорить время компиляции моего проекта CMake enabled C++?

я столкнулся с несколькими вопросами SO относительно конкретных аспектов улучшения времени поворота проектов CMake enabled C++ в последнее время (например,"на каком уровне я должен распространять свой процесс сборки?" или " cmake rebuild_cache для просто поддиректорию?"), мне было интересно, есть ли более общее руководство, использующее конкретные возможности CMake. Если, вероятно, нет кросс-платформенной оптимизации времени компиляции, меня в основном интересует Подходы на основе Visual Studio или GNU toochain.

и я уже знаю и инвестирую в обычно рекомендуемые области для ускорения сборки C++:

  1. изменить / оптимизировать / настроить цепочку инструментов

  2. оптимизация базы кода / архитектуры программного обеспечения (e.g путем уменьшения зависимостей и использования четко определенных подпроектов-модульных тестов)

  3. инвестируйте в лучшее оборудование (SSD, CPU, память)

рекомендуемые здесь, здесь или здесь. Поэтому в этом вопросе я сосредоточусь на первом пункте.

плюс я знаю рекомендации, которые можно найти в Вики CMake:

первый просто обрабатывает основы (параллельный make), позже обрабатывает в основном, как ускорить разбор файлов 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 ответов


вот что я имел хорошие результаты с использованием CMake и Visual Studio или GNU toolchains:

  1. обмен GNU сделать с ниндзя. Это быстрее, использует все доступные ядра процессора автоматически и имеет хорошее управление зависимостями. Просто имейте в виду

    a.) Вам нужно правильно настроить целевые зависимости в CMake. Если Вы дойдете до точки, где сборка зависит от другого артефакта, ей придется подождать, пока они не будут скомпилированы (точки синхронизации).

    $ 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
    
  2. разделить менее часто изменяемые или стабильные части кода на отдельные проекты CMake и использовать CMake ExternalProject_Add() или - если вы, например, переключитесь на двоичную доставку некоторых библиотек - find_library().

  3. подумайте о другом наборе параметров компилятора / компоновщика для вашей повседневной работы (но только если у вас также есть некоторое время тестирования/опыт работы с параметрами сборки окончательного выпуска).

    a.) Пропустить части оптимизации

    b.) Попробуйте инкрементное связывание

  4. если вы часто делаете изменения в самом коде CMake, подумайте о перестройке CMake из источников, оптимизированных для архитектуры вашей машины. Тмаки по официально распределенные двоичные файлы - это просто компромисс для работы над любой возможной архитектурой процессора.

    когда я использую 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
    
  5. если ваш файл ввода / вывода очень медленный и так как CMake работает с выделенными двоичными выходными каталогами, используйте RAM-диск. Если вы все еще используете жесткий диск, подумайте о переходе в твердое состояние диск.

  6. в зависимости от вашего конечного выходного файла замените стандартный компоновщик GNU на Золото Линкер. Еще быстрее, чем Gold Linker, является lld из проекта LLVM. Вы должны проверить, поддерживает ли он уже необходимые функции на вашей платформе.

  7. использовать 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/

  8. Increadibuild может увеличить время компиляции.

ссылки


для ускорения времени настройки CMake см.:https://github.com/cristianadam/cmake-checks-cache

LLVM + Clang получил ускорение ~3x.