diff --git a/CMakeLists.txt b/CMakeLists.txt
index 082093140ec6d403edc8c7bae99c2acc1b2f116a..16eb5f9e9ddb0513d6abb4cf6516931992a1c41a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,7 @@ cmake_dependent_option(
 )
 option(SRB2_CONFIG_HWRENDER "Enable hardware render (OpenGL) support" ON)
 option(SRB2_CONFIG_STATIC_OPENGL "Enable static linking GL (do not do this)" OFF)
+option(SRB2_CONFIG_ERRORMODE "Compile C code with warnings treated as errors. (C++ warnings are always treated as errors)" OFF)
 set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
 
 # Enable CCache
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2c98019e80bc50a15f5727eb79c756524706b195..97d48442198443bb6d85a9b3e91883f4c8cd2c97 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -128,13 +128,141 @@ endif()
 # We should really fix our code to not need this
 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
 	target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
-	target_compile_options(SRB2SDL2 PRIVATE -Wno-trigraphs)
 endif()
 
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-	target_compile_options(SRB2SDL2 PRIVATE -Wno-absolute-value)
+# Compiler warnings configuration
+target_compile_options(SRB2SDL2 PRIVATE
+	# Using generator expressions to handle per-language compile options
+
+	# C, GNU
+	# This is a direct translation from versions.mk
+	$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>:
+		-Wall
+		-Wno-trigraphs
+		-W # Was controlled by RELAXWARNINGS
+		-Wfloat-equal
+		-Wundef
+		-Wpointer-arith
+		-Wbad-function-cast
+		-Wcast-qual
+		-Wcast-align # Was controlled by NOCASTALIGNWARN
+		-Wwrite-strings
+		-Wsign-compare
+		-Waggregate-return
+		-Wmissing-prototypes
+		-Wmissing-declarations
+		-Wmissing-noreturn
+		-Wnested-externs
+		-Winline
+		-Wformat-y2k
+		-Wformat-security
+		
+		$<$<VERSION_LESS:$<C_COMPILER_VERSION>,2.9.5>:
+			-Wno-div-by-zero
+			-Wendif-labels
+			-Wdisabled-optimization
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,4.0.0>:
+			-Wold-style-definition
+			-Wmissing-field-initializers
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,4.1.0>:
+			-Wshadow
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,4.3.0>:
+			-funit-at-a-time
+			-Wlogical-op
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,4.5.0>:
+			-Wlogical-op
+			-Wno-error=array-bounds
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,4.6.0>:
+			-Wno-suggest-attribute=noreturn
+			-Wno-error=suggest-attribute=noreturn
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,5.4.0>:
+			-Wno-logical-op
+			-Wno-error=logical-op
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,6.1.0>:
+			-Wno-tautological-compare
+			-Wno-error=tautological-compare
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,7.1.0>:
+			-Wno-error=format-overflow=2
+			-Wimplicit-fallthrough=4
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,8.1.0>:
+			-Wno-error=format-overflow
+			-Wno-error=stringop-truncation
+			-Wno-error=stringop-overflow
+			-Wno-format-overflow
+			-Wno-stringop-truncation
+			-Wno-stringop-overflow
+			-Wno-error=multistatement-macros
+		>
+
+		$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,9.1.0>:
+			-Wno-error=address-of-packed-member
+		>
+	>
+
+	# C, Clang and Apple Clang
+	$<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
+		-Wall
+		-Wno-absolute-value
+		-Wno-trigraphs
+		-Wno-error=non-literal-null-conversion
+		-Wno-error=constant-conversion
+		-Wno-error=unused-but-set-variable
+	>
+
+	# C, MSVC
+	$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:MSVC>>:
+		# All warnings at and before Visual Studio 2019 RTM
+		# https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-by-compiler-version?view=msvc-170
+		/Wv:19.20.27004.0
+	>
+
+	# C++, GNU, Clang and Apple Clang
+	$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
+		-Wall
+	>
+
+	# C++, MSVC
+	$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:MSVC>>:
+		/Wv:19.20.27004.0
+	>
+)
+if(SRB2_CONFIG_ERRORMODE)
+	target_compile_options(SRB2SDL2 PRIVATE
+		$<$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>:
+			-Werror
+		>
+
+		$<$<C_COMPILER_ID:MSVC>:
+			/WX
+		>
+	)
 endif()
 
+# Link warnings configuration
+target_link_options(SRB2SDL2 PRIVATE
+	$<$<C_COMPILER_ID:GNU>:
+		# -Wl,--as-needed   - Was controlled by NOLDWARNING
+	>
+)
+
 if(${SRB2_CONFIG_DEV_BUILD})
 	target_compile_definitions(SRB2SDL2 PRIVATE -DDEVELOP)
 endif()