Як використовувати CCache з CMake?


90

Я хотів би зробити наступне: Якщо CCache присутній у PATH, використовуйте "ccache g ++" для компіляції, інакше використовуйте g ++. Я спробував написати невеликий скрипт my-cmake, що містить

    CC="ccache gcc" CXX="ccache g++" cmake $*

але це, здається, не працює (запущений make все ще не використовує кеш; я перевірив це за допомогою CMAKE_VERBOSE_MAKEFILE увімкнено).

Оновлення:

За цим посиланням я спробував змінити свій сценарій на

     cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*

але cmake виручає скаргу на те, що тест не вдався при використанні кешу компілятора (чого можна очікувати).


4
Чому б вам просто не зв'язати gcc із кешем? І якщо ви поширюєте це, я думаю, що користувач сам зробив би символічне посилання, якби він встановив ccache і хотів, щоб його використовували ..
int3

1
@ int3 Так, напевно, це спрацювало б (я не знав, що ccache має компілятор як додатковий аргумент). Однак було б чистіше бути більш чітким.
Аміт

Відповіді:


67

Я особисто маю /usr/lib/ccacheв своєму $PATH. Цей каталог містить безліч символьних посилань для кожного можливого імені, з якого можна викликати компілятор (як gccі gcc-4.3), і все вказує на ccache.

І я навіть не створював символічні посилання. Цей каталог попередньо заповнюється, коли я встановлюю ccache на Debian.


11
Зверніть увагу, що цей шлях ccache повинен бути розміщений перед тим шляхом, де знаходиться ваш справжній компілятор, $PATHщоб він працював. Щось на зразокexport PATH = /usr/lib/ccache:$PATH
Gui13

6
@ Gui13: Краще, ніж оновлення PATH, було б явно вказати cmake, де знаходиться gcc, який він повинен використовувати, наприклад, cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib

3
Після brew install ccache, я маю /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001

96

Тепер можна вказати 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) # Less useful to do it for linking, see edit2
endif(CCACHE_FOUND)

Також можна встановити ці властивості лише для певних каталогів або цілей.

Для Ninja це можливо з версії 3.4. Щодо XCode, Крейг Скотт дає обхідний шлях у своїй відповіді.

Редагувати: Завдяки коментарю uprego та Лекенштейна, я відредагував відповідь, щоб перевірити, чи доступний ccache, перш ніж використовувати його як пускову установку та для яких генераторів можна використовувати запуск компіляції.

Edit2: @Emilio Cobos рекомендував уникати цього для частини зв’язування, оскільки ccache не покращує швидкість зв’язку і може возитися з іншими типами кешу, такими як sccache


Багато веб-сайтів явно радять використовувати подвійні лапки, як-от find_program(CCACHE_FOUND "ccache"), я не знаю, який з них є більш портативним, мій пробіг пройшов чудово, не потребуючи подвійних лапок.
1737973

5
Варто зазначити, що наразі це працює лише для генераторів Makefile (станом на cmake 3.3.2). Див. Сторінку керівництва cmake-properties.
Лекенштейн

1
Варто зазначити, що це суперечить налаштуванню CTEST_USE_LAUNCHERS. Ці властивості також встановлені тут: github.com/Kitware/CMake/blob/master/Modules/…
purpleKarrot

Я думаю, вам може знадобитися змінити код на цей (крім видалення тексту зсерединиendif() ) . Поліпшення: 1. Існує параметр конфігурації, щоб його вимкнути, і 2. Виявляється, кольори зникають з GCC / Clang у Make backend, коли використовується таким чином. ninjaБекенд працює навколо нього, додавши -fdiagnostics-colorопцію, так що бажано зробити це для makeвнутрішнього інтерфейсу теж.
Hi-Angel

94

Станом на CMAKE 3.4 ви можете:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

1
І -DCMAKE_CXX_COMPILER_LAUNCHER=ccache. Вони працюють чудово! Я не знаю, чому cmake наполягає на пошуку clangз /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(тому трюк із символічним посиланням не працює), а не з $PATH, але ваша відповідь все одно працює.
cdunn2001,

2
Це повинна бути найкраща відповідь. Більше возитися із змінною шляху та символьними посиланнями компілятора!
ілля б.

1
Я спробував це, але це просто видає мені помилку "ccache: error: рекурсивне виклик (ім'я двійкового файлу ccache має бути" ccache ")". Дивлячись на багатослівний слід, він намагається запустити "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Кріс Додд

3
Як він взаємодіє з RULE_LAUNCH_COMPILE?
Trass3r

10

З CMake 3.1 можна використовувати кеш із генератором Xcode, а Ninja підтримується з CMake 3.4 і далі. Ninja буде вшановувати так RULE_LAUNCH_COMPILEсамо, як генератор Unix Makefiles (тому відповідь @ Babcool приведе вас до Ninja), але отримання кешу, що працює для генератора Xcode, вимагає трохи більше роботи. Наступна стаття детально пояснює метод, зосереджуючись на загальній реалізації, яка працює для всіх трьох генераторів CMake, і не робить жодних припущень щодо налаштування символічних посилань кешу або використовуваного базового компілятора (це все одно дозволяє 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_XCODE_ATTRIBUTE_...підтримки змінних CMake . Установка з CCі CXXвизначається користувача Xcode атрибутів для управління командою компілятора і LDі LDPLUSPLUSдля команди линкера немає, наскільки я можу сказати, документально особливість проектів Xcode, але це не схоже на роботу. Якщо хтось може підтвердити, що це офіційно підтримується Apple, я оновлю пов’язану статтю та цю відповідь відповідно.


Мені також знадобилася set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")згадана стаття.
Йорн Реймердес

Дякую за нагадування, я оновив відповідь, включивши налаштування LD та LDPLUSPLUS.
Крейг Скотт

ccache не підтримує компілятори VS, тому ви не можете використовувати його для цього. Існує проект під назвою clcache, який має на меті забезпечити однакову функціональність для VS, але я не можу коментувати, наскільки добре він працює.
Крейг Скотт,

9

Мені не подобалося встановлювати символічне посилання від 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 тижні, а потім, можливо, замислитись, чи щось не працює ...


5

На мою думку, найкращий спосіб - це посилання на gcc, g ++ на ccache, але якщо ви хочете використовувати в cmake, спробуйте наступне:

export CC="ccache gcc" CXX="ccache g++" cmake ...

5

Я перевірив такі роботи (джерело: це посилання ):

        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 скаржиться).


4

Дозвольте додати один важливий пункт, про який раніше тут не згадувалося.

Під час завантаження мінімалістичної системи збірки із образу докера 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 ++ потрапляють!


Дякую, про що я не знав update-ccache-symlinks, я створював c++посилання зі сценарієм для проекту, і він працював, але не для іншого проекту (все ще не знаю чому, посилання було нормальним), update-ccache-symlinksвирішено.
Олексій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.