Làm thế nào để sử dụng CCache với CMake?


90

Tôi muốn làm như sau: Nếu CCache có mặt trong PATH, hãy sử dụng "ccache g ++" để biên dịch, nếu không hãy sử dụng g ++. Tôi đã thử viết một tập lệnh my-cmake nhỏ chứa

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

nhưng nó dường như không hoạt động (chạy make vẫn không sử dụng ccache; tôi đã kiểm tra điều này bằng cách sử dụng CMAKE_VERBOSE_MAKEFILE trên).

Cập nhật:

Theo liên kết này, tôi đã thử thay đổi tập lệnh của mình thành

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

nhưng cmake từ chối phàn nàn rằng một thử nghiệm không thành công khi sử dụng ccache trình biên dịch (có thể được mong đợi).


4
Tại sao bạn không chỉ liên kết biểu tượng gcc với ccache? Và nếu bạn đang phân phối này, tôi nghĩ rằng người dùng mình đã có thể làm các liên kết tượng trưng nếu ông đã được cài đặt ccache và muốn nó được sử dụng ..
int3

1
@ int3 Có lẽ điều đó sẽ hoạt động (Tôi không biết rằng ccache có trình biên dịch như một đối số tùy chọn). Tuy nhiên, nó sẽ rõ ràng hơn nếu rõ ràng hơn.
amit

Câu trả lời:


67

Cá nhân tôi có /usr/lib/ccachetrong tôi $PATH. Thư mục này chứa vô số liên kết tượng trưng cho mọi tên có thể mà trình biên dịch có thể được gọi từ (như gccgcc-4.3), tất cả đều trỏ đến ccache.

Và tôi thậm chí còn không tạo các liên kết tượng trưng. Thư mục đó được điền sẵn khi tôi cài đặt ccache trên Debian.


11
Lưu ý rằng đường dẫn ccache này phải được đặt trước đường dẫn nơi có trình biên dịch thực của bạn $PATHđể nó hoạt động. Một cái gì đó giống nhưexport PATH = /usr/lib/ccache:$PATH
Gui 13

6
@ Gui13: Tốt hơn so với việc cập nhật PATH sẽ được nói rõ ràng cmake nơi gcc nó nên sử dụng là, ví dụ như cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
CIB

3
Sau khi brew install ccache, tôi có /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001

96

Bây giờ có thể chỉ định ccache làm trình khởi chạy cho các lệnh biên dịch và lệnh liên kết (kể từ cmake 2.8.0). Điều đó hoạt động cho Makefile và trình tạo Ninja. Để thực hiện việc này, chỉ cần đặt các thuộc tính sau:

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)

Cũng có thể đặt các thuộc tính này chỉ cho các thư mục hoặc mục tiêu cụ thể.

Đối với Ninja, điều này có thể thực hiện được kể từ phiên bản 3.4. Đối với XCode, Craig Scott đưa ra một cách giải quyết trong câu trả lời của mình.

Chỉnh sửa: Cảm ơn uprego và bình luận của Lekensteyn, tôi đã chỉnh sửa câu trả lời để kiểm tra xem ccache có sẵn hay không trước khi sử dụng nó làm trình khởi chạy và trình tạo nào có thể sử dụng trình khởi chạy biên dịch.

Edit2: @Emilio Cobos khuyên bạn nên tránh làm điều đó đối với phần liên kết vì ccache không cải thiện tốc độ liên kết và có thể gây rối với các loại bộ nhớ cache khác như sccache


Nhiều trang web ngầm tư vấn sử dụng dấu ngoặc kép như trong find_program(CCACHE_FOUND "ccache"), tôi không biết cái nào dễ di chuyển hơn, quãng đường của tôi đã hoàn toàn tốt mà không cần đến dấu ngoặc kép.
1737973

5
Cần lưu ý rằng điều này hiện chỉ hoạt động đối với trình tạo Makefile (kể từ cmake 3.3.2). Xem trang hướng dẫn sử dụng của cmake-properties.
Lekensteyn

1
Cần lưu ý rằng điều này xung đột với cài đặt CTEST_USE_LAUNCHERS. Các thuộc tính đó cũng được đặt ở đây: github.com/Kitware/CMake/blob/master/Modules/…
PurpleKarrot

Tôi nghĩ rằng bạn có thể muốn thay đổi mã thành mã này (ngoại trừ, xóa văn bản từ bên trong củaendif() ) . Các cải tiến là: 1. Có một tùy chọn cấu hình để vô hiệu hóa nó và 2. Hóa ra, màu sắc biến mất khỏi GCC / Clang trong Tạo phần phụ trợ khi được sử dụng theo cách này. Phần ninjaphụ trợ hoạt động xung quanh nó bằng cách thêm -fdiagnostics-colortùy chọn, vì vậy bạn cũng nên làm như vậy cho makephần phụ trợ.
Hi-Angel

94

Kể từ CMAKE 3.4, bạn có thể làm:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

1
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache. Những hoạt động tuyệt vời! Tôi không biết tại sao cmake nhấn mạnh vào việc tìm clangtừ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(vì vậy thủ thuật liên kết tượng trưng không hoạt động), thay vì từ $PATH, nhưng câu trả lời của bạn vẫn hoạt động.
cdunn2001

2
Đây nên là câu trả lời tốt nhất. Không còn rắc rối với các liên kết biểu tượng biến đường dẫn và trình biên dịch!
ilya b.

1
Tôi đã thử điều này, nhưng nó chỉ mang lại cho tôi lỗi "ccache: error: Lời gọi đệ quy (tên của nhị phân ccache phải là" ccache ")". Nhìn vào dấu vết chi tiết, nó đang cố gắng chạy "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Chris Dodd

3
Nó tương tác với RULE_LAUNCH_COMPILE như thế nào?
Trass3r

10

Từ CMake 3.1, có thể sử dụng ccache với trình tạo Xcode và Ninja được hỗ trợ từ CMake 3.4 trở đi. Ninja sẽ tôn vinh RULE_LAUNCH_COMPILEgiống như trình tạo Unix Makefiles (vì vậy câu trả lời của @ Babcool cũng giúp bạn đạt được điều đó cho Ninja), nhưng để ccache hoạt động cho trình tạo Xcode mất nhiều công hơn một chút. Bài viết sau giải thích chi tiết phương pháp này, tập trung vào triển khai chung hoạt động cho cả ba trình tạo CMake và không đưa ra giả định nào về việc thiết lập liên kết tượng trưng ccache hoặc trình biên dịch cơ bản được sử dụng (nó vẫn cho phép CMake quyết định trình biên dịch):

https://crascit.com/2016/04/09/using-ccache-with-cmake/

Ý chính chung của bài viết như sau. Phần bắt đầu của CMakeLists.txttệp của bạn nên được thiết lập như sau:

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()

Hai tệp mẫu tập lệnh launch-c.inlaunch-cxx.intrông giống như sau (chúng phải nằm trong cùng thư mục với CMakeLists.txttệp):

khởi chạy-c.in:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"

khởi chạy-cxx.in:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$@"

Ở trên chỉ sử dụng RULE_LAUNCH_COMPILEcho Unix Makefiles và Ninja, nhưng đối với trình tạo Xcode, nó dựa vào sự trợ giúp từ CMAKE_XCODE_ATTRIBUTE_...hỗ trợ các biến của CMake . Theo như tôi có thể nói, việc thiết lập các thuộc tính Xcode CCvà do CXXngười dùng xác định để điều khiển lệnh trình biên dịch LDLDPLUSPLUScho lệnh trình liên kết, theo như tôi có thể nói, không phải là một tính năng được ghi chép bằng tài liệu của các dự án Xcode, nhưng nó dường như hoạt động. Nếu ai đó có thể xác nhận nó được Apple hỗ trợ chính thức, tôi sẽ cập nhật bài viết được liên kết và câu trả lời này cho phù hợp.


Tôi cũng cần set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")từ bài báo đã đề cập.
Jörn Reimerdes

Cảm ơn lời nhắc, tôi đã cập nhật câu trả lời để bao gồm cài đặt LD và LDPLUSPLUS.
Craig Scott

ccache không hỗ trợ trình biên dịch VS, vì vậy bạn không thể sử dụng nó cho việc đó. Có một dự án tên là clcache nhằm cung cấp chức năng tương tự cho VS, nhưng tôi không thể bình luận về cách nó hoạt động tốt.
Craig Scott,

9

Tôi không muốn đặt liên kết biểu tượng từ g++thành ccache. Và CXX="ccache g++"không phù hợp với tôi vì một số trường hợp thử nghiệm cmake chỉ muốn có chương trình biên dịch mà không có thuộc tính.

Vì vậy, tôi đã sử dụng một tập lệnh bash nhỏ để thay thế:

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

và lưu nó dưới dạng tệp thực thi trong /usr/bin/ccache-g++.

Sau đó, C đã cấu hình cmake để sử dụng /usr/bin/ccache-g++làm trình biên dịch C ++. Bằng cách này, nó vượt qua các trường hợp thử nghiệm cmake và tôi cảm thấy thoải mái hơn so với việc có các liên kết tượng trưng mà tôi có thể quên mất trong 2 hoặc 3 tuần và sau đó có thể tự hỏi nếu điều gì đó không hoạt động ...


5

Theo tôi, cách tốt nhất là liên kết mã hóa gcc, g ++ với ccache, nhưng nếu bạn muốn sử dụng trong cmake, hãy thử cách này:

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

5

Tôi đã xác minh các tác phẩm sau (nguồn: liên kết này ):

        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" $*

Cập nhật : Sau đó tôi nhận ra rằng ngay cả điều này cũng không hoạt động. Kỳ lạ là nó hoạt động mọi lúc (những lần khác cmake phàn nàn).


4

Hãy để tôi thêm một mục quan trọng mà trước đây chưa được đề cập ở đây.

Trong khi khởi động hệ thống xây dựng tối giản từ hình ảnh docker ubunutu: 18.04, tôi thấy rằng thứ tự cài đặt tạo ra sự khác biệt.

Trong trường hợp của tôi, ccache hoạt động tốt khi gọi gcc, nhưng không bắt được các lệnh gọi của cùng một trình biên dịch bởi các tên khác: ccc++. Để cài đặt đầy đủ ccache, trước tiên bạn cần đảm bảo rằng tất cả các trình biên dịch đã được cài đặt hoặc thêm lệnh gọi đến các liên kết tượng trưng update-ccache để an toàn.

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

... và sau đó (do các liên kết tượng trưng được cập nhật) cũng gọi đến cc và c ++ bị bắt!


Cảm ơn Tôi không biết về update-ccache-symlinks, tôi đang tạo c++liên kết với một tập lệnh cho một dự án và nó đang hoạt động nhưng không phải cho một dự án khác (vẫn không biết tại sao, liên kết vẫn ổn), đã update-ccache-symlinksgiải quyết.
Alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.