From dd74dd05a055cb882388862f8a3fe6e3ba4b194b Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Fri, 19 Nov 2021 23:55:09 +1300 Subject: CMake: add option USE_CCACHE=OFF to use ccache to compile C/C++ objs --- CMakeLists.txt | 6 +++++ cmake/Ccache.cmake | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ cmake/Makefile.am | 1 + docs/source/install.rst | 5 ++++ travis/install.sh | 17 +++++++++++-- 5 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 cmake/Ccache.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 661b3f6a..c1d58405 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,12 @@ set(PROJ_BUILD_VERSION "${PROJ_API_VERSION}.${PROJ_LIBTOOL_AGE}.${PROJ_LIBTOOL_R ################################################################################ # Build features and variants ################################################################################ + +option(USE_CCACHE "Use ccache to compile C/C++ objects" OFF) +if(USE_CCACHE) + include(Ccache) +endif() + include(ProjConfig) include(ProjMac) include(policies) diff --git a/cmake/Ccache.cmake b/cmake/Ccache.cmake new file mode 100644 index 00000000..09e81756 --- /dev/null +++ b/cmake/Ccache.cmake @@ -0,0 +1,66 @@ +# +# CMake module to support ccache +# +# see https://crascit.com/2016/04/09/using-ccache-with-cmake/ +# + +find_program(CCACHE_PROGRAM ccache) +# Note: REQUIRED keyword introduced in CMake 3.18 + +if(CCACHE_PROGRAM) + message(STATUS "Configuring ccache with ${CCACHE_PROGRAM}") + + set(C_LAUNCHER "${CCACHE_PROGRAM}") + set(CXX_LAUNCHER "${CCACHE_PROGRAM}") + + # Set up wrapper scripts + set(CCACHE_LAUNCH_C ${CMAKE_BINARY_DIR}/ccache-launch-c) + file(WRITE ${CCACHE_LAUNCH_C} "\ +#!/bin/sh + +# Xcode generator doesn't include the compiler as the +# first argument, Ninja and Makefiles do. Handle both cases. +if [ \"$1\" = \"${CMAKE_C_COMPILER}\" ] ; then + shift +fi + +export CCACHE_CPP2=true +exec \"${C_LAUNCHER}\" \"${CMAKE_C_COMPILER}\" \"$@\" +") + + set(CCACHE_LAUNCH_CXX ${CMAKE_BINARY_DIR}/ccache-launch-cxx) + file(WRITE ${CCACHE_LAUNCH_CXX} "\ +#!/bin/sh + +# Xcode generator doesn't include the compiler as the +# first argument, Ninja and Makefiles do. Handle both cases. +if [ \"$1\" = \"${CMAKE_CXX_COMPILER}\" ] ; then + shift +fi + +export CCACHE_CPP2=true +exec \"${CXX_LAUNCHER}\" \"${CMAKE_CXX_COMPILER}\" \"$@\" +") + + # Note: file(CHMOD) introduced in CMake 3.19 + execute_process( + COMMAND chmod a+rx + "${CCACHE_LAUNCH_C}" + "${CCACHE_LAUNCH_CXX}" + ) + + if(CMAKE_GENERATOR STREQUAL "Xcode") + # Set Xcode project attributes to route compilation and linking + # through our scripts + set(CMAKE_XCODE_ATTRIBUTE_CC "${CCACHE_LAUNCH_C}") + set(CMAKE_XCODE_ATTRIBUTE_CXX "${CCACHE_LAUNCH_CXX}") + set(CMAKE_XCODE_ATTRIBUTE_LD "${CCACHE_LAUNCH_C}") + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CCACHE_LAUNCH_CXX}") + else() + # Support Unix Makefiles and Ninja + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_LAUNCH_C}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_LAUNCH_CXX}") + endif() +else() + message(SEND_ERROR "Ccache requested, but ccache was not found") +endif() diff --git a/cmake/Makefile.am b/cmake/Makefile.am index cdad1ff8..de982198 100644 --- a/cmake/Makefile.am +++ b/cmake/Makefile.am @@ -1,4 +1,5 @@ EXTRA_DIST = CMakeLists.txt \ + Ccache.cmake \ ProjInstallPath.cmake \ ProjUtilities.cmake \ proj_config.cmake.in \ diff --git a/docs/source/install.rst b/docs/source/install.rst index 208b55d4..d4d202b8 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -465,6 +465,11 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory. ``TIFF_LIBRARY_DEBUG`` can also be specified to a similar library for building Debug releases. +.. option:: USE_CCACHE=OFF + + Configure CMake to use `ccache `_ to build C/C++ + objects. + Building on Windows with vcpkg and Visual Studio 2017 or 2019 -------------------------------------------------------------------------------- diff --git a/travis/install.sh b/travis/install.sh index d0b4d9cb..8a9a6f72 100755 --- a/travis/install.sh +++ b/travis/install.sh @@ -139,11 +139,24 @@ if [ "$BUILD_NAME" != "linux_gcc8" -a "$BUILD_NAME" != "linux_gcc_32bit" ]; then VERBOSE=1 make >/dev/null cd ../.. + # Use ccache if it's available + if command -v ccache &> /dev/null + then + USE_CCACHE=ON + ccache -s + else + USE_CCACHE=OFF + fi + # Regular build mkdir build_cmake cd build_cmake - cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/proj_cmake_install - VERBOSE=1 make >/dev/null + cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/proj_cmake_install -DUSE_CCACHE=${USE_CCACHE} + make >/dev/null + if [ "$USE_CCACHE" = "ON" ]; then + ccache -s + fi + make install >/dev/null ctest find /tmp/proj_cmake_install -- cgit v1.2.3 From 4889dcfa71505939966e119baa9449be189abaaf Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Thu, 25 Nov 2021 11:21:09 +1300 Subject: Also look for clcache for MSVC; only use wrappers for Xcode --- cmake/Ccache.cmake | 70 ++++++++++++++++++------------------------------- docs/source/install.rst | 5 ++-- travis/install.sh | 2 +- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/cmake/Ccache.cmake b/cmake/Ccache.cmake index 09e81756..7bc59429 100644 --- a/cmake/Ccache.cmake +++ b/cmake/Ccache.cmake @@ -1,66 +1,48 @@ # -# CMake module to support ccache -# -# see https://crascit.com/2016/04/09/using-ccache-with-cmake/ +# CMake module to support ccache (or clcache for MSVC) # +# Copyright (c) 2021, Mike Taves + +cmake_minimum_required(VERSION 3.4) -find_program(CCACHE_PROGRAM ccache) -# Note: REQUIRED keyword introduced in CMake 3.18 +find_program(CCACHE_PROGRAM NAMES ccache clcache) if(CCACHE_PROGRAM) message(STATUS "Configuring ccache with ${CCACHE_PROGRAM}") - set(C_LAUNCHER "${CCACHE_PROGRAM}") - set(CXX_LAUNCHER "${CCACHE_PROGRAM}") - - # Set up wrapper scripts - set(CCACHE_LAUNCH_C ${CMAKE_BINARY_DIR}/ccache-launch-c) - file(WRITE ${CCACHE_LAUNCH_C} "\ + if(CMAKE_GENERATOR STREQUAL "Xcode") + # see https://crascit.com/2016/04/09/using-ccache-with-cmake/ + set(C_LAUNCHER "${CCACHE_PROGRAM}") + set(CXX_LAUNCHER "${CCACHE_PROGRAM}") + set(CCACHE_LAUNCH_C ${CMAKE_BINARY_DIR}/ccache-c) + set(CCACHE_LAUNCH_CXX ${CMAKE_BINARY_DIR}/ccache-cxx) + file(WRITE "${CCACHE_LAUNCH_C}" "\ #!/bin/sh - -# Xcode generator doesn't include the compiler as the -# first argument, Ninja and Makefiles do. Handle both cases. -if [ \"$1\" = \"${CMAKE_C_COMPILER}\" ] ; then - shift -fi - -export CCACHE_CPP2=true +shift exec \"${C_LAUNCHER}\" \"${CMAKE_C_COMPILER}\" \"$@\" ") - - set(CCACHE_LAUNCH_CXX ${CMAKE_BINARY_DIR}/ccache-launch-cxx) - file(WRITE ${CCACHE_LAUNCH_CXX} "\ + file(WRITE "${CCACHE_LAUNCH_CXX}" "\ #!/bin/sh - -# Xcode generator doesn't include the compiler as the -# first argument, Ninja and Makefiles do. Handle both cases. -if [ \"$1\" = \"${CMAKE_CXX_COMPILER}\" ] ; then - shift -fi - -export CCACHE_CPP2=true +shift exec \"${CXX_LAUNCHER}\" \"${CMAKE_CXX_COMPILER}\" \"$@\" ") - - # Note: file(CHMOD) introduced in CMake 3.19 - execute_process( - COMMAND chmod a+rx - "${CCACHE_LAUNCH_C}" - "${CCACHE_LAUNCH_CXX}" - ) - - if(CMAKE_GENERATOR STREQUAL "Xcode") + # Note: file(CHMOD) introduced in CMake 3.19 + execute_process( + COMMAND chmod a+rx + "${CCACHE_LAUNCH_C}" + "${CCACHE_LAUNCH_CXX}" + ) # Set Xcode project attributes to route compilation and linking - # through our scripts + # through the wrapper scripts set(CMAKE_XCODE_ATTRIBUTE_CC "${CCACHE_LAUNCH_C}") set(CMAKE_XCODE_ATTRIBUTE_CXX "${CCACHE_LAUNCH_CXX}") set(CMAKE_XCODE_ATTRIBUTE_LD "${CCACHE_LAUNCH_C}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CCACHE_LAUNCH_CXX}") else() - # Support Unix Makefiles and Ninja - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_LAUNCH_C}") - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_LAUNCH_CXX}") + # Most other generators (Unix Makefiles, Ninja, etc.) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") endif() else() - message(SEND_ERROR "Ccache requested, but ccache was not found") + message(WARNING "Ccache was requested, but no program was not found") endif() diff --git a/docs/source/install.rst b/docs/source/install.rst index d4d202b8..23224e23 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -467,8 +467,9 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory. .. option:: USE_CCACHE=OFF - Configure CMake to use `ccache `_ to build C/C++ - objects. + Configure CMake to use `ccache `_ (or + `clcache `_ for MSVC) + to build C/C++ objects. Building on Windows with vcpkg and Visual Studio 2017 or 2019 diff --git a/travis/install.sh b/travis/install.sh index 8a9a6f72..916f554d 100755 --- a/travis/install.sh +++ b/travis/install.sh @@ -153,7 +153,7 @@ if [ "$BUILD_NAME" != "linux_gcc8" -a "$BUILD_NAME" != "linux_gcc_32bit" ]; then cd build_cmake cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/proj_cmake_install -DUSE_CCACHE=${USE_CCACHE} make >/dev/null - if [ "$USE_CCACHE" = "ON" ]; then + if [ "${USE_CCACHE}" = "ON" ]; then ccache -s fi -- cgit v1.2.3 From cd07dcf0c4b60860188fc7829ebd20df835c68d4 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Thu, 25 Nov 2021 11:57:02 +1300 Subject: Move option to module and add more comments --- CMakeLists.txt | 6 +----- cmake/Ccache.cmake | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1d58405..744ee4c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,11 +123,7 @@ set(PROJ_BUILD_VERSION "${PROJ_API_VERSION}.${PROJ_LIBTOOL_AGE}.${PROJ_LIBTOOL_R # Build features and variants ################################################################################ -option(USE_CCACHE "Use ccache to compile C/C++ objects" OFF) -if(USE_CCACHE) - include(Ccache) -endif() - +include(Ccache) include(ProjConfig) include(ProjMac) include(policies) diff --git a/cmake/Ccache.cmake b/cmake/Ccache.cmake index 7bc59429..10b4cfd0 100644 --- a/cmake/Ccache.cmake +++ b/cmake/Ccache.cmake @@ -2,11 +2,27 @@ # CMake module to support ccache (or clcache for MSVC) # # Copyright (c) 2021, Mike Taves +# +# Usage: +# Add "include(Ccache)" to CMakeLists.txt and enable +# using the option -D USE_CCACHE=ON cmake_minimum_required(VERSION 3.4) +option(USE_CCACHE + "Use ccache (or clcache for MSVC) to compile C/C++ objects" OFF) +if(NOT USE_CCACHE) + # stop here and return to including file + return() +endif() + +# Search priority: +# 1. ccache for many compilers except MSVC +# 2. clcache for MSVC + find_program(CCACHE_PROGRAM NAMES ccache clcache) + if(CCACHE_PROGRAM) message(STATUS "Configuring ccache with ${CCACHE_PROGRAM}") -- cgit v1.2.3