Browse Source

{cmake} Use the same compiler warnings as godot

Andy Maloney 2 years ago
parent
commit
d081b4bab6
2 changed files with 126 additions and 35 deletions
  1. 28 35
      CMakeLists.txt
  2. 98 0
      cmake/GodotCompilerWarnings.cmake

+ 28 - 35
CMakeLists.txt

@@ -2,10 +2,11 @@
 # CMAKE_BUILD_TYPE:			Compilation target (Debug or Release defaults to Debug)
 #
 # godot-cpp cmake arguments
-# GODOT_GDEXTENSION_DIR:	Path to the directory containing GDExtension interface header and API JSON file
-# GODOT_CPP_SYSTEM_HEADERS	Mark the header files as SYSTEM. This may be useful to supress warnings in projects including this one.
-# GODOT_CUSTOM_API_FILE:	Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
-# FLOAT_PRECISION:			Floating-point precision level ("single", "double")
+# GODOT_GDEXTENSION_DIR:		Path to the directory containing GDExtension interface header and API JSON file
+# GODOT_CPP_SYSTEM_HEADERS		Mark the header files as SYSTEM. This may be useful to supress warnings in projects including this one.
+# GODOT_CPP_WARNING_AS_ERROR	Treat any warnings as errors
+# GODOT_CUSTOM_API_FILE:		Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
+# FLOAT_PRECISION:				Floating-point precision level ("single", "double")
 #
 # Android cmake arguments
 # CMAKE_TOOLCHAIN_FILE:		The path to the android cmake toolchain ($ANDROID_NDK/build/cmake/android.toolchain.cmake)
@@ -41,6 +42,15 @@ cmake_minimum_required(VERSION 3.12)
 
 option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
 option(GODOT_CPP_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF)
+option(GODOT_CPP_WARNING_AS_ERROR "Treat warnings as errors" OFF)
+
+# Add path to modules
+list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
+
+# Check if we are building ourself or being included
+if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
+    set(GODOT_CPP_BUILDING_SELF ON)
+endif()
 
 # Default build type is Debug in the SConstruct
 if("${CMAKE_BUILD_TYPE}" STREQUAL "")
@@ -72,7 +82,7 @@ set(GODOT_LINKER_FLAGS )
 
 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 	# using Visual Studio C++
-	set(GODOT_COMPILE_FLAGS "/EHsc /WX") # /GF /MP
+	set(GODOT_COMPILE_FLAGS "/EHsc") # /GF /MP
 
 	if(CMAKE_BUILD_TYPE MATCHES Debug)
 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
@@ -82,39 +92,14 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 		string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
 	endif(CMAKE_BUILD_TYPE MATCHES Debug)
 
-	# Disable conversion warning, truncation, unreferenced var, signed mismatch, different type
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /wd4244 /wd4305 /wd4101 /wd4018 /wd4267 /wd4099")
-
 	add_definitions(-DNOMINMAX)
-
-	# Unkomment for warning level 4
-	#if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
-	#	string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-	#endif()
-
 else()  # GCC/Clang
 	set(GODOT_LINKER_FLAGS "-static-libgcc -static-libstdc++ -Wl,-R,'$$ORIGIN'")
 
 	if(NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
 		set(GODOT_COMPILE_FLAGS "-fPIC")
 	endif()
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g -Wwrite-strings")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wchar-subscripts -Wcomment -Wdisabled-optimization")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wformat -Wformat=2 -Wformat-security -Wformat-y2k")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wimport -Winit-self -Winline -Winvalid-pch")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-braces -Wmissing-format-attribute")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wredundant-decls -Wreturn-type -Wsequence-point")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wswitch -Wswitch-enum -Wtrigraphs")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused-label")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wunused-value -Wvariadic-macros -Wvolatile-register-var -Wno-error=attributes")
-
-	# -Wshadow -Wextra -Wall -Weffc++ -Wfloat-equal -Wstack-protector -Wunused-parameter -Wsign-compare -Wunused-variable -Wcast-align
-	# -Wunused-function -Wstrict-aliasing -Wstrict-aliasing=2 -Wmissing-field-initializers
-
-	if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
-		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wno-ignored-attributes")
-	endif()
+	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g")
 
 	if(CMAKE_BUILD_TYPE MATCHES Debug)
 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
@@ -157,14 +142,24 @@ add_library(${PROJECT_NAME}
 )
 add_library(godot::cpp ALIAS ${PROJECT_NAME})
 
+include(GodotCompilerWarnings)
+
+# Treat warnings as errors if we are building ourself
+if(GODOT_CPP_BUILDING_SELF)
+    unset( GODOT_CPP_WARNING_AS_ERROR CACHE )
+    set_warning_as_error()
+endif()
+
 target_compile_features(${PROJECT_NAME}
 	PRIVATE
 		cxx_std_17
 )
 
 target_compile_definitions(${PROJECT_NAME} PUBLIC
-	$<$<CONFIG:Debug>:DEBUG_ENABLED>
-	$<$<CONFIG:Debug>:DEBUG_METHODS_ENABLED>
+	$<$<CONFIG:Debug>:
+		DEBUG_ENABLED
+		DEBUG_METHODS_ENABLED
+	>
 )
 
 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
@@ -182,8 +177,6 @@ target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE}
 	${CMAKE_CURRENT_BINARY_DIR}/gen/include
 )
 
-unset( GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE )
-
 # Put godot headers as SYSTEM PUBLIC to exclude warnings from irrelevant headers
 target_include_directories(${PROJECT_NAME}
 	SYSTEM PUBLIC

+ 98 - 0
cmake/GodotCompilerWarnings.cmake

@@ -0,0 +1,98 @@
+# Add warnings based on compiler & version
+# Set some helper variables for readability
+set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
+set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
+set( compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>" )
+
+set( compiler_less_than_v8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>" )
+set( compiler_greater_than_or_equal_v9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>" )
+set( compiler_greater_than_or_equal_v11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>" )
+set( compiler_less_than_v11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>" )
+set( compiler_greater_than_or_equal_v12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>" )
+
+# These compiler options reflect what is in godot/SConstruct.
+target_compile_options( ${PROJECT_NAME} PRIVATE
+    # MSVC only
+    $<${compiler_is_msvc}:
+        /W4
+
+        # Disable warnings which we don't plan to fix.
+        /wd4100  # C4100 (unreferenced formal parameter): Doesn't play nice with polymorphism.
+        /wd4127  # C4127 (conditional expression is constant)
+        /wd4201  # C4201 (non-standard nameless struct/union): Only relevant for C89.
+        /wd4244  # C4244 C4245 C4267 (narrowing conversions): Unavoidable at this scale.
+        /wd4245
+        /wd4267
+        /wd4305  # C4305 (truncation): double to float or real_t, too hard to avoid.
+        /wd4514  # C4514 (unreferenced inline function has been removed)
+        /wd4714  # C4714 (function marked as __forceinline not inlined)
+        /wd4820  # C4820 (padding added after construct)
+    >
+
+    # Clang and GNU common options
+    $<$<OR:${compiler_is_clang},${compiler_is_gnu}>:
+        -Wall
+        -Wctor-dtor-privacy
+        -Wextra
+        -Wno-unused-parameter
+        -Wnon-virtual-dtor
+        -Wwrite-strings
+    >
+
+    # Clang only
+    $<${compiler_is_clang}:
+        -Wimplicit-fallthrough
+        -Wno-ordered-compare-function-pointers
+    >
+
+    # GNU only
+    $<${compiler_is_gnu}:
+        -Walloc-zero
+        -Wduplicated-branches
+        -Wduplicated-cond
+        -Wno-misleading-indentation
+        -Wplacement-new=1
+        -Wshadow-local
+        -Wstringop-overflow=4
+    >
+    $<$<AND:${compiler_is_gnu},${compiler_less_than_v8}>:
+        # Bogus warning fixed in 8+.
+        -Wno-strict-overflow
+    >
+    $<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v9}>:
+        -Wattribute-alias=2
+    >
+    $<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v11}>:
+        # Broke on MethodBind templates before GCC 11.
+        -Wlogical-op
+    >
+    $<$<AND:${compiler_is_gnu},${compiler_less_than_v11}>:
+        # Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it.
+        -Wno-type-limits
+    >
+    $<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v12}>:
+        # False positives in our error macros, see GH-58747.
+        -Wno-return-type
+    >
+)
+
+# Treat warnings as errors
+function( set_warning_as_error )
+    message( STATUS "[${PROJECT_NAME}] Treating warnings as errors")
+    if ( CMAKE_VERSION VERSION_GREATER_EQUAL "3.24" )
+        set_target_properties( ${PROJECT_NAME}
+            PROPERTIES
+                COMPILE_WARNING_AS_ERROR ON
+        )
+    else()
+        target_compile_options( ${PROJECT_NAME}
+            PRIVATE
+                $<${compiler_is_msvc}:/WX>
+                $<$<OR:${compiler_is_clang},${compiler_is_gnu}>:-Werror>
+        )
+    endif()
+endfunction()
+
+if ( GODOT_CPP_WARNING_AS_ERROR )
+    set_warning_as_error()
+endif()