Как использовать CCache с CMake?
Я хотел бы сделать следующее: Если в PATH присутствует CCache, используйте "ccache g++" для компиляции, иначе используйте g++. Я попытался написать небольшой скрипт my-cmake, содержащий
CC="ccache gcc" CXX="ccache g++" cmake $*
но, похоже, это не работает (при запуске make все еще не используется ccache; я проверил это с помощью CMAKE_VERBOSE_MAKEFILE on).
Обновить:
По этой ссылке я пытался изменить свой скрипт на
cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
но cmake выручает, жалуясь на то, что тесту не удалось использовать компилятор ccache (что и следовало ожидать).
10 ответов
Лично я /usr/lib/ccache
в моем $PATH
, Этот каталог содержит множество символических ссылок для каждого возможного имени, из которого может быть вызван компилятор (например, gcc
а также gcc-4.3
), все указывает на ccache.
И я даже не создал символические ссылки. Этот каталог предварительно заполняется, когда я устанавливаю ccache на Debian.
Начиная с CMAKE 3.4 вы можете делать:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
Теперь можно указать ccache в качестве средства запуска для команд компиляции и команд линковки (начиная с cmake 2.8.0). Это работает для генераторов Makefile и Ninja. Для этого просто установите следующие свойства:
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
Также возможно установить эти свойства только для определенных каталогов или целей.
Для ниндзя это возможно начиная с версии 3.4. Для XCode Крейг Скотт предлагает обходной путь в своем ответе.
Изменить: Благодаря uprego и комментарию Лекенштейна, я отредактировал ответ, чтобы проверить, доступен ли ccache, прежде чем использовать его в качестве средства запуска и для каких генераторов можно использовать средство запуска компиляции.
Начиная с CMake 3.1, можно использовать ccache с генератором Xcode, а Ninja поддерживается начиная с CMake 3.4 и далее. Ниндзя почтит RULE_LAUNCH_COMPILE
точно так же, как генератор Unix Makefiles (поэтому ответ @Babcool поможет вам и для Ninja), но работа ccache для генератора Xcode требует немного больше работы. В следующей статье подробно описывается метод, основное внимание уделяется общей реализации, которая работает для всех трех генераторов CMake, и не делается никаких предположений о настройке символических ссылок ccache или используемого базового компилятора (он все еще позволяет CMake выбирать компилятор):
https://crascit.com/2016/04/09/using-ccache-with-cmake/
Общая суть статьи заключается в следующем. Начало вашего CMakeLists.txt
файл должен быть настроен примерно так:
cmake_minimum_required(VERSION 2.8)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Support Unix Makefiles and Ninja
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()
project(SomeProject)
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE AND CMAKE_GENERATOR STREQUAL "Xcode")
# Set up wrapper scripts
configure_file(launch-c.in launch-c)
configure_file(launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx")
# Set Xcode project attributes to route compilation through our scripts
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
Два файла шаблона скрипта launch-c.in
а также launch-cxx.in
выглядеть так (они должны быть в том же каталоге, что и CMakeLists.txt
файл):
launch-c.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"
launch-cxx.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$@"
Вышеуказанное использует RULE_LAUNCH_COMPILE
только для Unix Makefiles и Ninja, но для генератора Xcode он опирается на помощь от CMake CMAKE_XCODE_ATTRIBUTE_...
поддержка переменных. Настройка CC
а также CXX
определяемые пользователем атрибуты XCode для управления командой компилятора и LD
а также LDPLUSPLUS
поскольку команда линкера, насколько я могу судить, не является документированной функцией проектов XCode, но, похоже, она работает. Если кто-нибудь может подтвердить, что Apple официально поддерживает его, я обновлю связанную статью и этот ответ соответственно.
Я не хотел устанавливать символическую ссылку из g++
в ccache
, А также CXX="ccache g++"
у меня не получилось, так как в каком-то тестовом примере cmake захотелось иметь только программу компилятора без атрибутов.
Поэтому вместо этого я использовал небольшой скрипт bash:
#!/bin/bash
ccache g++ "$@"
и сохранил его как исполняемый файл в /usr/bin/ccache-g++
,
Затем C настроил cmake для использования /usr/bin/ccache-g++
как компилятор C++. Таким образом, он проходит тестовые сценарии cmake, и я чувствую себя более комфортно, чем наличие символических ссылок, о которых я могу забыть через 2 или 3 недели, а потом, возможно, задаться вопросом, не работает ли что-то...
Позвольте мне добавить один важный пункт, который не был упомянут здесь ранее.
При загрузке минималистичной системы сборки из образа докера ubunutu:18.04 я обнаружил, что порядок установки имеет значение.
В моем случае ccache работал нормально при звонке gcc
, но не смог отловить вызовы того же компилятора под другими именами: cc
а также c++
, Чтобы полностью установить ccache, вы должны убедиться, что сначала установлены все компиляторы, или добавить безопасные вызовы символических ссылок update-ccache.
sudo apt-get install ccache build-essential # and everyhting ...
sudo /usr/sbin/update-ccache-symlinks
export PATH="/usr/lib/ccache/:$PATH"
... а затем (из-за обновленных символических ссылок) также обращаются к cc и C++!
Я проверил следующие работы (источник: эта ссылка):
CC="gcc" CXX="g++" cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
Обновление: позже я понял, что даже это не работает. Странно это работает каждый раз (в другой раз cmake жалуется).
На мой взгляд, лучший способ - использовать символическую ссылку gcc,g++ на ccache, но если вы хотите использовать в cmake, попробуйте это:
export CC="ccache gcc" CXX="ccache g++" cmake ...
Вот 2 метода, которые я считаю чистыми/надежными, а также не загрязняющими ваш код CMake.
1.) Установите переменные среды
Этот метод удобен тем, что вам не нужно настраивать его индивидуально для каждого проекта CMake. Минус в том, что вам может не понадобиться ccache для каждого проекта CMake.
# Requires CMake 3.17 (https://cmake.org/cmake/help/latest/envvar/CMAKE_LANG_COMPILER_LAUNCHER.html)
export CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache
export CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
2.) Передача переменных кеша во время настройки проекта
Con немного раздражает делать для каждого проекта. Однако это может быть сведено на нет вашей IDE.
# Requires CMake 3.4
$ cmake ... -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache \
-D CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
ПРИМЕЧАНИЕ. На самом деле нет необходимости указывать полный путь.
Если на вашем пути, вы можете просто указатьccache
вместо.
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export CMAKE_C_COMPILER_LAUNCHER=ccache
Он расширяет ответ @Nicolas.
Добавьте следующую строку в ваш файл:
list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)
Или добавьте его в качестве аргумента
cmake
шаг настройки:
cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache