diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt
index 18397528cb48e5329f809b07d1f543f58b61c87c..7aa04fc320ad33bcc524fd1e1f58e2ca6c12fd08 100644
--- a/thirdparty/CMakeLists.txt
+++ b/thirdparty/CMakeLists.txt
@@ -209,85 +209,11 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 	)
 	target_compile_features(gme PRIVATE cxx_std_11)
 	target_link_libraries(gme PRIVATE ZLIB::ZLIB)
-endif()
-
-CPMAddPackage(
-	NAME RapidJSON
-	VERSION 1.1.0
-	URL "https://github.com/Tencent/rapidjson/archive/v1.1.0.tar.gz"
-	EXCLUDE_FROM_ALL ON
-	DOWNLOAD_ONLY ON
-)
-if(RapidJSON_ADDED)
-	add_library(RapidJSON INTERFACE)
-	add_library(RapidJSON::RapidJSON ALIAS RapidJSON)
-	target_include_directories(RapidJSON INTERFACE "${RapidJSON_SOURCE_DIR}/include")
-endif()
-
-CPMAddPackage(
-	NAME DiscordRPC
-	VERSION 3.4.0
-	URL "https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.zip"
-	EXCLUDE_FROM_ALL ON
-	DOWNLOAD_ONLY ON
-)
-
-if(DiscordRPC_ADDED)
-	set(DiscordRPC_SOURCES
-		include/discord_rpc.h
-		include/discord_register.h
-
-		src/discord_rpc.cpp
-		src/rpc_connection.h
-		src/rpc_connection.cpp
-		src/serialization.h
-		src/serialization.cpp
-		src/connection.h
-		src/backoff.h
-		src/msg_queue.h
-	)
-	list(TRANSFORM DiscordRPC_SOURCES PREPEND "${DiscordRPC_SOURCE_DIR}/")
-
-	# Discord RPC is always statically linked because it's tiny.
-	add_library(discord-rpc STATIC ${DiscordRPC_SOURCES})
-	add_library(DiscordRPC::DiscordRPC ALIAS discord-rpc)
-
-	target_include_directories(discord-rpc PUBLIC "${DiscordRPC_SOURCE_DIR}/include")
-	target_compile_features(discord-rpc PUBLIC cxx_std_11)
-	target_link_libraries(discord-rpc PRIVATE RapidJSON::RapidJSON)
 
-	# Platform-specific connection and register impls
-	if(WIN32)
-		target_compile_definitions(discord-rpc PUBLIC -DDISCORD_WINDOWS)
-		target_sources(discord-rpc PRIVATE
-			"${DiscordRPC_SOURCE_DIR}/src/connection_win.cpp"
-			"${DiscordRPC_SOURCE_DIR}/src/discord_register_win.cpp"
-		)
-		target_link_libraries(discord-rpc PRIVATE psapi advapi32)
-	endif()
-
-	if(UNIX)
-		target_sources(discord-rpc PRIVATE
-			"${DiscordRPC_SOURCE_DIR}/src/connection_unix.cpp"
-		)
-
-		if(APPLE)
-			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_OSX)
-			target_sources(discord-rpc PRIVATE
-				"${DiscordRPC_SOURCE_DIR}/src/discord_register_osx.m"
-			)
-			target_link_libraries(discord-rpc PUBLIC "-framework AppKit")
-		endif()
-
-		if(UNIX AND NOT APPLE)
-			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_LINUX)
-			target_sources(discord-rpc PRIVATE
-				"${DiscordRPC_SOURCE_DIR}/src/discord_register_linux.cpp"
-			)
-		endif()
-	endif()
 endif()
 
+include("cpm-rapidjson.cmake")
+include("cpm-discordrpc.cmake")
 include("cpm-xmp-lite.cmake")
 
 add_subdirectory(tcbrindle_span)
diff --git a/thirdparty/cpm-discordrpc.cmake b/thirdparty/cpm-discordrpc.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..078ebaab5990c8cbf0c7fc7b9e23cecca26557fb
--- /dev/null
+++ b/thirdparty/cpm-discordrpc.cmake
@@ -0,0 +1,63 @@
+CPMAddPackage(
+	NAME DiscordRPC
+	VERSION 3.4.0
+	URL "https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.zip"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY ON
+)
+
+if(DiscordRPC_ADDED)
+	set(DiscordRPC_SOURCES
+		include/discord_rpc.h
+		include/discord_register.h
+
+		src/discord_rpc.cpp
+		src/rpc_connection.h
+		src/rpc_connection.cpp
+		src/serialization.h
+		src/serialization.cpp
+		src/connection.h
+		src/backoff.h
+		src/msg_queue.h
+	)
+	list(TRANSFORM DiscordRPC_SOURCES PREPEND "${DiscordRPC_SOURCE_DIR}/")
+
+	# Discord RPC is always statically linked because it's tiny.
+	add_library(discord-rpc STATIC ${DiscordRPC_SOURCES})
+	add_library(DiscordRPC::DiscordRPC ALIAS discord-rpc)
+
+	target_include_directories(discord-rpc PUBLIC "${DiscordRPC_SOURCE_DIR}/include")
+	target_compile_features(discord-rpc PUBLIC cxx_std_11)
+	target_link_libraries(discord-rpc PRIVATE RapidJSON::RapidJSON)
+
+	# Platform-specific connection and register impls
+	if(WIN32)
+		target_compile_definitions(discord-rpc PUBLIC -DDISCORD_WINDOWS)
+		target_sources(discord-rpc PRIVATE
+			"${DiscordRPC_SOURCE_DIR}/src/connection_win.cpp"
+			"${DiscordRPC_SOURCE_DIR}/src/discord_register_win.cpp"
+		)
+		target_link_libraries(discord-rpc PRIVATE psapi advapi32)
+	endif()
+
+	if(UNIX)
+		target_sources(discord-rpc PRIVATE
+			"${DiscordRPC_SOURCE_DIR}/src/connection_unix.cpp"
+		)
+
+		if(APPLE)
+			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_OSX)
+			target_sources(discord-rpc PRIVATE
+				"${DiscordRPC_SOURCE_DIR}/src/discord_register_osx.m"
+			)
+			target_link_libraries(discord-rpc PUBLIC "-framework AppKit")
+		endif()
+
+		if(UNIX AND NOT APPLE)
+			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_LINUX)
+			target_sources(discord-rpc PRIVATE
+				"${DiscordRPC_SOURCE_DIR}/src/discord_register_linux.cpp"
+			)
+		endif()
+	endif()
+endif()
diff --git a/thirdparty/cpm-rapidjson.cmake b/thirdparty/cpm-rapidjson.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2836625ed66c969b37819cb041c6de91bfde4ec1
--- /dev/null
+++ b/thirdparty/cpm-rapidjson.cmake
@@ -0,0 +1,13 @@
+CPMAddPackage(
+	NAME RapidJSON
+	VERSION 1.1.0
+	URL "https://github.com/Tencent/rapidjson/archive/v1.1.0.tar.gz"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY ON
+)
+
+if(RapidJSON_ADDED)
+	add_library(RapidJSON INTERFACE)
+	add_library(RapidJSON::RapidJSON ALIAS RapidJSON)
+	target_include_directories(RapidJSON INTERFACE "${RapidJSON_SOURCE_DIR}/include")
+endif()