Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions recipes/ccache/binary/ccache-autoinject.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include_guard()

# Find ccache executable
find_program(CCACHE_PROGRAM NAMES ccache)

if(CCACHE_PROGRAM)
message(STATUS "ccache found: ${CCACHE_PROGRAM}, enabling via CMake launcher and environment.")
if (CMAKE_GENERATOR MATCHES "Visual Studio")
# Copy original ccache.exe and rename to cl.exe, this way intermediate cmd file is not needed
file(COPY_FILE ${CCACHE_PROGRAM} ${CMAKE_BINARY_DIR}/cl.exe ONLY_IF_DIFFERENT)

# Set Visual Studio global variables:
# - Use above cl.exe (ccache.exe) as a compiler
# - Enable parallel compilation
list(APPEND CMAKE_VS_GLOBALS
"CLToolExe=cl.exe"
"CLToolPath=${CMAKE_BINARY_DIR}"
"UseMultiToolTask=true"
"UseStructuredOutput=false"
)
elseif(CMAKE_GENERATOR MATCHES "Ninja" OR CMAKE_GENERATOR MATCHES "Unix Makefiles")
message(STATUS "Using ccache as compiler launcher for Ninja or Makefiles.")
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM} CACHE FILEPATH "CXX compiler cache used" FORCE)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM} CACHE FILEPATH "C compiler cache used" FORCE)
else()
message(WARNING "Unsupported generator for ccache integration: ${CMAKE_GENERATOR}. ccache will not be used.")
endif()
else()
message(WARNING "ccache not found. Not enabling ccache integration.")
endif()
23 changes: 23 additions & 0 deletions recipes/ccache/binary/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
sources:
"4.12":
Linux:
x86_64:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-linux-x86_64.tar.xz"
sha256: "d77e140d0403175b93f979f0b0d36e821bf31728b282f4bfda939f65836bcabe"
armv8:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-linux-aarch64.tar.xz"
sha256: "378ed4b9f645f5aab691447e4ec45b4c68508a424ac37c9be7baa28ded385791"
Macos:
universal:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-darwin.tar.gz"
sha256: "95cb03de0f2e0edb264d2443f2fe4500a13086689cc9ecd1095eb274dd8d9aee"
Windows:
armv8:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-windows-aarch64.zip"
sha256: "12d8a95507ce19bb90cff49faa5f5de07919d5d8d91f129bcf597dbc30d0c250"
x86:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-windows-i686.zip"
sha256: "c046ad7159d312312662c380da5932d441407f56164e451b09c16dad8db01051"
x86_64:
url: "https://github.com/ccache/ccache/releases/download/v4.12/ccache-4.12-windows-x86_64.zip"
sha256: "85c963b154dcf5e38dc6839d660218433a3b0b86387c302675d236e17ae7220d"
61 changes: 61 additions & 0 deletions recipes/ccache/binary/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
from pathlib import Path

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.files import get, copy

required_conan_version = ">=2.1"

AUTOIJECT_CMAKE = "ccache-autoinject.cmake"

class CcacheConan(ConanFile):
name = "ccache"
package_type = "application"
description = (
"Ccache (or “ccache”) is a compiler cache. It speeds up recompilation "
"by caching previous compilations and detecting when the same "
"compilation is being done again."
)
license = "GPL-3.0-or-later"
topics = ("compiler-cache", "recompilation", "cache", "compiler")
homepage = "https://ccache.dev"
url = "https://github.com/conan-io/conan-center-index"
settings = "os", "arch"
exports_sources = [AUTOIJECT_CMAKE]

@property
def _arch(self):
return str(self.settings.arch) if self.settings.os != "Macos" else "universal"

def validate(self):
if self.conan_data["sources"][self.version].get(str(self.settings.os), {}).get(self._arch) is None:
raise ConanInvalidConfiguration(f"ccache binaries do not support '{self.settings.os} - {self._arch}'")

def build(self):
get(self, **self.conan_data["sources"][self.version][str(self.settings.os)][self._arch],
destination=self.source_folder, strip_root=True)

def package_id(self):
if self.info.settings.os == "Macos":
self.info.settings.arch = "universal"

def package(self):
copy(self, "*GPL-*.txt", src=self.build_folder, dst=os.path.join(self.package_folder, "licenses"))
copy(self, "LICENSE.*", src=self.build_folder, dst=os.path.join(self.package_folder, "licenses"))
copy(self, "ccache*", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"))
copy(self, AUTOIJECT_CMAKE, src=self.build_folder, dst=self.package_folder)

def package_info(self):
self.cpp_info.libdirs = []
self.cpp_info.includedirs = []
if self.conf.get("user.ccache:auto_inject", default=True, check_type=bool):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a new remote/repo/recipe? Why can't we integrate that in the regular ccache (conan-center) recipe? What is different if auto_inject=False (default)?

self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", os.path.join(self.package_folder, AUTOIJECT_CMAKE))

# Set environment variables to allow ccache work correctly within conan build/create workflow
base_dir = self.conf.get("user.ccache:base_dir", default=str(Path.home()), check_type=str)
self.buildenv_info.define("CCACHE_BASEDIR", base_dir)
self.buildenv_info.define("CCACHE_NOHASHDIR", "1")

self.output.warning("ccache recipe can autoinject itself into CMake projects but you need to define CC/CXX "
"environment variables to use it in other build systems such as Meson, Autotools, Premake, etc.")
4 changes: 4 additions & 0 deletions recipes/ccache/binary/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES CXX)

add_executable(${PROJECT_NAME} test_package.cpp)
34 changes: 34 additions & 0 deletions recipes/ccache/binary/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import CMake, cmake_layout
from conan.errors import ConanException


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeToolchain"

def build_requirements(self):
self.tool_requires(self.tested_reference_str)

def layout(self):
cmake_layout(self)

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
generated_file = os.path.join(self.dependencies.build[self.tested_reference_str].package_folder, "ccache-autoinject.cmake")
if not os.path.exists(generated_file):
raise ConanException("ccache-autoinject.cmake toolchain file does not exist")
user_toolchain = self.conf.get("tools.cmake.cmaketoolchain:user_toolchain", check_type=list)
if generated_file not in user_toolchain:
raise ConanException("ccache not found in user toolchain")

if can_run(self):
self.run("ccache --version", env="conanbuild")
self.run("ccache --get-config hash_dir", env="conanbuild")
self.run("ccache --get-config base_dir", env="conanbuild")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also verify that ccache works:
In the test project, change the cache_dir (CCACHE_DIR) to a temporary, clean dir. Then after build, verify that the cache has 1 entry (ccache -s)

5 changes: 5 additions & 0 deletions recipes/ccache/binary/test_package/test_package.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <iostream>

int main() {
std::cout << "Hello world!\n";
}
3 changes: 3 additions & 0 deletions recipes/ccache/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"4.12":
folder: binary