วิธีใช้ CCache กับ CMake


92

ฉันต้องการทำสิ่งต่อไปนี้: หากมี CCache อยู่ใน PATH ให้ใช้ "ccache g ++" สำหรับการคอมไพล์มิฉะนั้นให้ใช้ g ++ ฉันพยายามเขียนสคริปต์ my-cmake ขนาดเล็กที่มีไฟล์

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

แต่ดูเหมือนจะไม่ทำงาน (การรัน make ยังไม่ใช้ ccache ฉันตรวจสอบสิ่งนี้โดยใช้ 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 บ่นว่าการทดสอบล้มเหลวในการใช้ ccache คอมไพเลอร์ (ซึ่งสามารถคาดหวังได้)


4
ทำไมคุณไม่เพียงแค่ symlink gcc กับ ccache? และถ้าคุณกำลังแจกจ่ายสิ่งนี้ฉันคิดว่าผู้ใช้เองคงจะทำ symlink แล้วถ้าเขาติดตั้ง ccache ไว้และต้องการให้ใช้ ..
int3

1
@ int3 ใช่อาจจะใช้ได้ (ฉันไม่ทราบว่า ccache มีคอมไพเลอร์เป็นอาร์กิวเมนต์ที่เป็นทางเลือก) อย่างไรก็ตามมันจะสะอาดกว่าที่จะชัดเจนกว่านี้
Amit

คำตอบ:


68

ฉันเองมี/usr/lib/ccacheใน$PATHไฟล์. ไดเร็กทอรีนี้มี symlinks มากมายสำหรับทุกชื่อที่เป็นไปได้ที่คอมไพเลอร์สามารถเรียกได้จาก (like gccand 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

98

ใน 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(ดังนั้นเคล็ดลับ symlink จึงไม่ทำงาน) แทนที่จะเป็นจาก$PATHแต่คำตอบของคุณก็ใช้ได้
cdunn2001

3
นี่น่าจะเป็นคำตอบที่ดีที่สุด ไม่ต้องวุ่นวายกับตัวแปรพา ธ และลิงก์คอมไพเลอร์อีกต่อไป!
ข.

1
ฉันลองแล้ว แต่มันให้ข้อผิดพลาด "ccache: error: Recursive invocation (ชื่อของไบนารี ccache ต้องเป็น" ccache ")" เมื่อมองไปที่การติดตาม verbose มันกำลังพยายามเรียกใช้ "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Chris Dodd

3
มันโต้ตอบกับ RULE_LAUNCH_COMPILE อย่างไร?
Trass3r

98

ขณะนี้สามารถระบุ ccache เป็นตัวเรียกใช้งานสำหรับคำสั่งคอมไพล์และคำสั่งลิงก์ (ตั้งแต่ cmake 2.8.0) ใช้งานได้กับ Makefile และ Ninja generator ในการดำเนินการนี้ให้ตั้งค่าคุณสมบัติต่อไปนี้:

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 Craig Scott ให้วิธีแก้ปัญหาในคำตอบของเขา

แก้ไข: ขอบคุณความคิดเห็นของ uprego และ Lekensteyn ฉันแก้ไขคำตอบเพื่อตรวจสอบว่า ccache พร้อมใช้งานหรือไม่ก่อนที่จะใช้เป็นตัวเรียกใช้งานและเครื่องกำเนิดไฟฟ้าใดที่สามารถใช้ตัวเรียกใช้งานคอมไพล์ได้

Edit2: @Emilio Cobos แนะนำให้หลีกเลี่ยงการทำเช่นนั้นสำหรับส่วนการเชื่อมโยงเนื่องจาก ccache ไม่ได้ปรับปรุงความเร็วในการเชื่อมโยงและอาจยุ่งกับแคชประเภทอื่น ๆ เช่น sccache


เว็บไซต์หลายแห่งแนะนำโดยปริยายโดยใช้ doublequotes เช่น in find_program(CCACHE_FOUND "ccache")ฉันไม่รู้ว่าอันไหนพกพาได้มากกว่าระยะทางของฉันทำได้ดีอย่างสมบูรณ์โดยไม่ต้องใช้ doublequotes
1737973

5
เป็นที่น่าสังเกตว่าขณะนี้ใช้งานได้กับเครื่องกำเนิด Makefile เท่านั้น (ณ cmake 3.3.2) ดูหน้าคู่มือของcmake-properties.
Lekensteyn

1
เป็นที่น่าสังเกตว่าสิ่งนี้ขัดแย้งกับการตั้งค่า CTEST_USE_LAUNCHERS คุณสมบัติเหล่านี้ถูกตั้งค่าไว้ที่นี่ด้วย: github.com/Kitware/CMake/blob/master/Modules/…
purpleKarrot

ฉันคิดว่าคุณอาจต้องการที่จะเปลี่ยนรหัสไปนี้ (ยกเว้นข้อความลบจากภายในendif() ) การปรับปรุง ได้แก่ 1. มีตัวเลือกการกำหนดค่าเพื่อปิดใช้งานและ 2. ปรากฎว่าสีหายไปจาก GCC / Clang ใน Make แบ็กเอนด์เมื่อใช้วิธีนี้ ninjaแบ็กเอนด์ทำงานรอบ ๆ ได้โดยการเพิ่ม-fdiagnostics-colorตัวเลือกดังนั้นจึงแนะนำให้ทำเช่นนั้นสำหรับmakeแบ็กเอนด์มากเกินไป
Hi-Angel

9

จาก CMake 3.1 สามารถใช้ ccache กับเครื่องกำเนิด Xcode ได้และ Ninja รองรับตั้งแต่ CMake 3.4 เป็นต้นไป Ninja จะให้เกียรติ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_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}")จากบทความดังกล่าวด้วย
Jörn Reimerdes

ขอบคุณสำหรับการแจ้งเตือนเราได้อัปเดตคำตอบเพื่อรวมการตั้งค่า LD และ LDPLUSPLUS
Craig Scott

ccache ไม่รองรับคอมไพเลอร์ VS ดังนั้นคุณจึงไม่สามารถใช้มันได้ มีโครงการที่เรียกว่าclcacheซึ่งมีจุดมุ่งหมายเพื่อให้ฟังก์ชันการทำงานเดียวกันสำหรับ VS แต่ฉันไม่สามารถแสดงความคิดเห็นได้ว่ามันทำงานได้ดีเพียงใด
Craig Scott

8

ฉันไม่ชอบที่จะตั้ง symlink จากไปg++ ccacheและCXX="ccache g++"ไม่ได้ผลสำหรับฉันเนื่องจากบางกรณีทดสอบ cmake ต้องการให้มีเพียงโปรแกรมคอมไพเลอร์ที่ไม่มีแอตทริบิวต์

ดังนั้นฉันจึงใช้สคริปต์ทุบตีเล็ก ๆ แทน:

#!/bin/bash
ccache g++ "$@"

และบันทึกเป็นไฟล์ปฏิบัติการใน/usr/bin/ccache-g++.

จากนั้น C กำหนดค่า cmake เพื่อใช้/usr/bin/ccache-g++เป็นคอมไพเลอร์ C ++ วิธีนี้จะผ่านกรณีทดสอบ cmake และฉันรู้สึกสบายใจกว่ามี symlink ที่ฉันอาจลืมไปใน 2 หรือ 3 สัปดาห์แล้วอาจสงสัยว่ามีบางอย่างไม่ได้ผล ...


6

ฉันตรวจสอบงานต่อไปนี้แล้ว (ที่มา: ลิงค์นี้ ):

        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 บ่น)


5

ในความคิดของฉันวิธีที่ดีที่สุดคือ symlink gcc, g ++ ถึง ccache แต่ถ้าคุณต้องการใช้ภายใน cmake ลองสิ่งนี้:

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

4

ให้ฉันเพิ่มรายการสำคัญหนึ่งรายการที่ไม่ได้กล่าวถึงมาก่อน

ในขณะที่บูตระบบสร้างแบบเรียบง่ายจาก ubunutu: 18.04 อิมเมจนักเทียบท่าฉันพบว่าลำดับการติดตั้งสร้างความแตกต่าง

ในกรณีของฉัน ccache ทำงานได้ดีเมื่อโทรgccแต่ไม่สามารถตรวจจับการเรียกใช้คอมไพเลอร์เดียวกันโดยใช้ชื่ออื่น: ccและc++. ในการติดตั้ง ccache อย่างสมบูรณ์คุณต้องตรวจสอบให้แน่ใจว่าได้ติดตั้งคอมไพเลอร์ทั้งหมดก่อนหรือเพิ่มการเรียกเพื่อ update-ccache symlinks เพื่อความปลอดภัย

sudo apt-get install ccache build-essential # and everyhting ... sudo /usr/sbin/update-ccache-symlinks export PATH="/usr/lib/ccache/:$PATH"

... จากนั้น (เนื่องจาก symlinks ที่อัปเดต) ยังโทรไป cc และ c ++ ถูกจับ!


ขอบคุณที่ฉันไม่รู้update-ccache-symlinksฉันกำลังสร้างc++ลิงก์พร้อมสคริปต์สำหรับโปรเจ็กต์และมันใช้งานได้ แต่ไม่ใช่สำหรับโปรเจ็กต์อื่น (ยังไม่รู้ว่าทำไมลิงค์ถึงใช้ได้) update-ccache-symlinksแก้ไขแล้ว
Alex
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.