File: UseCompilerCache.cmake

package info (click to toggle)
pcl 1.13.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 143,524 kB
  • sloc: cpp: 518,578; xml: 28,792; ansic: 13,676; python: 334; lisp: 93; sh: 49; makefile: 30
file content (133 lines) | stat: -rw-r--r-- 5,071 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# .rst:
# UseCompilerCache
# --------
#
# This module provides a function to setup a compiler cache tool (default: ``ccache``)
# Main function of interest is ``UseCompilerCache``
#
# Needs CMake 3.4 at least
# Inspired from:
# * https://crascit.com/2016/04/09/using-ccache-with-cmake/
# * https://stackoverflow.com/a/36515503/
# * https://gitlab.kitware.com/henryiii/cmake/blob/cache/Modules/UseCompilerCache.cmake

# .rst
# pcl_ccache_compat_file_gen
# -- Generates a wrapper file which launches the compiler commands using ccache.
#    This allows support for XCode and CCache < 3.3
function(pcl_ccache_compat_file_gen FILE_NAME CCACHE_PROGRAM COMPILER)
  message(STATUS "${FILE_NAME} for ${CCACHE_PROGRAM} with ${COMPILER}")
  file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" ""
       "#! /usr/bin/env sh\n"
       "\n"
       "# Xcode generator doesn't include the compiler as the\n"
       "# first argument, Ninja and Makefiles do. Handle both cases.\n"
       "if [ \"$1\" = \"${COMPILER}\" ] ; then\n"
       "  shift\n"
       "fi\n"
       "\n"
       "export CCACHE_CPP2=true\n"
       "exec \"${CCACHE_PROGRAM}\" \"${COMPILER}\" \"$@\"\n")
endfunction()

# .rst
# UseCompilerCache([PROGRAM <ccache_name>] [QUIET] [REQUIRED])
# -- Add the compiler cache tool (default to look for ccache on the path)
#    to your build through CMAKE_<LANG>_COMPILER_LAUNCHER variables. Also
#    supports XCode. Uses a wrapper for XCode and CCache < 3.3.
#    Sets the COMPILER_CACHE_VERSION variable.
function(UseCompilerCache)
  set(options QUIET REQUIRED)
  set(oneValueArgs CCACHE)
  set(multiValueArgs)

  cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  
  if(ARGS_UNPARSED_ARGUMENTS)
    message(FATAL_ERROR "Unknown arguments given to UseCompilerCache: ${ARGS_UNPARSED_ARGUMENTS}")
  endif()

  if(NOT ARGS_CCACHE)
    set(ARGS_CCACHE ccache)
  endif()

  find_program(CCACHE_PROGRAM ${ARGS_CCACHE})

  # Quit if not found
  if(NOT CCACHE_PROGRAM)
    if(REQUIRED)
      message(FATAL_ERROR "Failed to find ${CCACHE_PROGRAM} (REQUIRED)")
    endif()
    return()
  endif()

  if(CMAKE_GENERATOR MATCHES "Visual")
    message(FATAL_ERROR "MSVC isn't compatible with current solutions. Please rename compiler cache to cl.exe and prepend its location in env PATH variable")
    return()
  endif()

  # Get version number
  execute_process(COMMAND "${CCACHE_PROGRAM}" --version OUTPUT_VARIABLE output)
  string(REPLACE "\n" ";" output "${output}")
  foreach(line ${output})
    string(TOLOWER ${line} line)
    string(REGEX REPLACE "^ccache version ([\\.0-9]+)$" "\\1" version "${line}")
    if(version)
      set(COMPILER_CACHE_VERSION ${version} PARENT_SCOPE)
      break()
    endif()
  endforeach()

  if(NOT ARGS_QUIET)
    message(STATUS "Using Compiler Cache (${CCACHE_PROGRAM}) v${version} in the C/C++ toolchain")
  endif()

  set(xcode_compat FALSE)
  if(CMAKE_GENERATOR STREQUAL Xcode)
    set(xcode_compat TRUE)
  endif()
  set(ccache_compat FALSE)
  if((ARGS_CCACHE STREQUAL ccache) AND (version VERSION_LESS 3.3.0))
    set(ccache_compat TRUE)
  endif()

  # Indirect wrapper is needed for CCache < 3.3 or XCode
  if(NOT (${xcode_compat} OR ${ccache_compat}))
    # Support Unix Makefiles and Ninja
    message(STATUS "Compiler cache via cmake launcher prefix")
    set(CMAKE_C_COMPILER_LAUNCHER    "${CCACHE_PROGRAM}" PARENT_SCOPE)
    set(CMAKE_CXX_COMPILER_LAUNCHER  "${CCACHE_PROGRAM}" PARENT_SCOPE)
    set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" PARENT_SCOPE)
    return()
  endif()

  message(STATUS "Generating launch helpers for compiler cache")

  pcl_ccache_compat_file_gen("launch-c" ${CCACHE_PROGRAM} ${CMAKE_C_COMPILER})
  pcl_ccache_compat_file_gen("launch-cxx" ${CCACHE_PROGRAM} ${CMAKE_CXX_COMPILER})
  execute_process(COMMAND chmod a+rx
                  "${CMAKE_BINARY_DIR}/launch-c"
                  "${CMAKE_BINARY_DIR}/launch-cxx")

  if(CMAKE_CUDA_COMPILER)
    pcl_ccache_compat_file_gen("launch-cuda" ${CCACHE_PROGRAM} ${CMAKE_CUDA_COMPILER})
    execute_process(COMMAND chmod a+rx
                    "${CMAKE_BINARY_DIR}/launch-cuda")
  endif()

  if(${xcode_compat})
    # Set Xcode project attributes to route compilation and linking properly
    message(STATUS "Compiler cache via launch files to support XCode")
    set(CMAKE_XCODE_ATTRIBUTE_CC         "${CMAKE_BINARY_DIR}/launch-c" PARENT_SCOPE)
    set(CMAKE_XCODE_ATTRIBUTE_CXX        "${CMAKE_BINARY_DIR}/launch-cxx" PARENT_SCOPE)
    set(CMAKE_XCODE_ATTRIBUTE_LD         "${CMAKE_BINARY_DIR}/launch-c" PARENT_SCOPE)
    set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx" PARENT_SCOPE)
  else()
    message(STATUS "Compiler cache via launch files to support Unix Makefiles and Ninja")
    set(CMAKE_C_COMPILER_LAUNCHER    "${CMAKE_BINARY_DIR}/launch-c" PARENT_SCOPE)
    set(CMAKE_CXX_COMPILER_LAUNCHER  "${CMAKE_BINARY_DIR}/launch-cxx" PARENT_SCOPE)
    if (CMAKE_CUDA_COMPILER)
        set(CMAKE_CUDA_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cuda" PARENT_SCOPE)
    endif()
  endif()
endfunction()