diff --git a/CMakeLists.txt b/CMakeLists.txt
index dc92de90c670cd1ecfa993f21785dce782980736..495da101effe8e7c7dc91cbfe884840b64531ba9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,17 @@
 cmake_minimum_required(VERSION 3.0)
+
+# Enable CCache early
+set(SRB2_USE_CCACHE OFF CACHE BOOL "Use CCache")
+if (${SRB2_USE_CCACHE})
+	find_program(CCACHE_PROGRAM ccache)
+	if(CCACHE_PROGRAM)
+		message(STATUS "Found CCache: ${CCACHE_PROGRAM}")
+		set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
+	else()
+		message(WARNING "You have specified to use CCACHE but it was not found. Object files will not be cached.")
+	endif()
+endif()
+
 # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
 # Version change is fine.
 project(SRB2
@@ -9,6 +22,10 @@ if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
 	message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.")
 endif()
 
+if ((${SRB2_USE_CCACHE}) AND (${CMAKE_C_COMPILER} MATCHES "clang"))
+	message(WARNING "Using clang and CCache: You may want to set environment variable CCACHE_CPP2=yes to prevent include errors during compile.")
+endif()
+
 # Set up CMAKE path
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 
diff --git a/launch-c.in b/launch-c.in
new file mode 100644
index 0000000000000000000000000000000000000000..c6055823265594d03c9d16e4d14547c3622150bd
--- /dev/null
+++ b/launch-c.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+export CCACHE_CPP2=true
+exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"
diff --git a/launch-cxx.in b/launch-cxx.in
new file mode 100644
index 0000000000000000000000000000000000000000..c6055823265594d03c9d16e4d14547c3622150bd
--- /dev/null
+++ b/launch-cxx.in
@@ -0,0 +1,3 @@
+#!/bin/sh
+export CCACHE_CPP2=true
+exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 840feb3fa02a0c499164f077776e4990e57aa4e5..fda3f2e7e3d51cc0fd42249dee918cc4aad9f578 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -523,6 +523,27 @@ endif()
 
 # Targets
 
+# If using CCACHE, then force it.
+# https://github.com/Cockatrice/Cockatrice/pull/3052/files
+if (${CMAKE_SYSTEM} MATCHES "Darwin")
+	get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
+	if(RULE_LAUNCH_COMPILE)
+		MESSAGE(STATUS "Force enabling CCache usage under macOS")
+		# Set up wrapper scripts
+		configure_file(${CMAKE_MODULE_PATH}/launch-c.in   launch-c)
+		configure_file(${CMAKE_MODULE_PATH}/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()
+endif()
+
 # Compatibility flag with later versions of GCC
 # We should really fix our code to not need this
 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")