SDL: cmake: build with -Wdocumentation

From fcae9cd210878a4dabf6946d076e9f692e1af36f Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 7 Aug 2023 19:00:38 +0200
Subject: [PATCH] cmake: build with -Wdocumentation

---
 CMakeLists.txt               | 40 +++++++++++++++++++++++++++++++++++-
 cmake/sdlchecks.cmake        | 12 +++++------
 test/CMakeLists.txt          | 28 ++++++++++++++++++++++++-
 test/testautomation_math.c   | 36 ++++++++++++++++----------------
 test/testautomation_render.c |  2 +-
 5 files changed, 91 insertions(+), 27 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1b073eb14119..463e2610a03b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -582,6 +582,40 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC)
     list(APPEND EXTRA_CFLAGS "-fno-strict-aliasing")
   endif()
 
+  check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION)
+  if(HAVE_GCC_WDOCUMENTATION)
+    if(SDL_WERROR)
+      check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION)
+      if(HAVE_GCC_WERROR_DOCUMENTATION)
+        list(APPEND EXTRA_CFLAGS "-Werror=documentation")
+      endif()
+    endif()
+     list(APPEND EXTRA_CFLAGS "-Wdocumentation")
+  endif()
+
+  check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
+  if(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
+    if(SDL_WERROR)
+      check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
+      if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
+        list(APPEND EXTRA_CFLAGS "-Werror=documentation-unknown-command")
+      endif()
+    endif()
+    list(APPEND EXTRA_CFLAGS "-Wdocumentation-unknown-command")
+  endif()
+
+  check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS)
+  if(HAVE_GCC_COMMENT_BLOCK_COMMANDS)
+    list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=threadsafety")
+    list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=deprecated")
+  else()
+    check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
+    if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
+      list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=threadsafety")
+      list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=deprecated")
+    endif()
+  endif()
+
   check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
   if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
     if(SDL_WERROR)
@@ -2986,6 +3020,10 @@ endif()
 listtostr(EXTRA_CFLAGS _EXTRA_CFLAGS)
 set(EXTRA_CFLAGS ${_EXTRA_CFLAGS})
 
+if(USE_GCC OR USE_CLANG)
+  string(REGEX REPLACE "(^| )-I" "\\1 -isystem" EXTRA_CFLAGS "${EXTRA_CFLAGS}")
+endif()
+
 # Compat helpers for the configuration files
 
 if(EXISTS "${PROJECT_SOURCE_DIR}/VERSION.txt")
@@ -3169,7 +3207,7 @@ if (SDL_ASAN)
 endif()
 
 if(SDL_CCACHE AND NOT CMAKE_VERSION VERSION_LESS 3.4)
-  cmake_minimum_required(VERSION 3.4)
+  cmake_minimum_required(VERSION 3.4...3.5)
   find_program(CCACHE_BINARY ccache)
   if(CCACHE_BINARY)
     set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY})
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
index c11ddc346717..35dd043effb0 100644
--- a/cmake/sdlchecks.cmake
+++ b/cmake/sdlchecks.cmake
@@ -108,7 +108,7 @@ macro(CheckALSA)
         if(HAVE_SDL_LOADSO)
           FindLibraryAndSONAME("asound")
           if(ASOUND_LIB AND ASOUND_SHARED)
-            target_include_directories(sdl-build-options INTERFACE $<TARGET_PROPERTY:ALSA::ALSA,INTERFACE_INCLUDE_DIRECTORIES>)
+            target_include_directories(sdl-build-options SYSTEM INTERFACE $<TARGET_PROPERTY:ALSA::ALSA,INTERFACE_INCLUDE_DIRECTORIES>)
             set(SDL_AUDIO_DRIVER_ALSA_DYNAMIC "\"${ASOUND_LIB_SONAME}\"")
             set(HAVE_ALSA_SHARED TRUE)
           else()
@@ -380,7 +380,7 @@ macro(CheckLibSampleRate)
       set(HAVE_LIBSAMPLERATE TRUE)
       set(HAVE_LIBSAMPLERATE_H TRUE)
       if(SDL_LIBSAMPLERATE_SHARED)
-        target_include_directories(sdl-build-options INTERFACE $<TARGET_PROPERTY:SampleRate::samplerate,INTERFACE_INCLUDE_DIRECTORIES>)
+        target_include_directories(sdl-build-options SYSTEM INTERFACE $<TARGET_PROPERTY:SampleRate::samplerate,INTERFACE_INCLUDE_DIRECTORIES>)
         if(NOT HAVE_SDL_LOADSO)
           message_warn("You must have SDL_LoadObject() support for dynamic libsamplerate loading")
         else()
@@ -683,7 +683,7 @@ macro(CheckWayland)
 
     if(WAYLAND_FOUND)
       target_link_directories(sdl-build-options INTERFACE "${PKG_WAYLAND_LIBRARY_DIRS}")
-      target_include_directories(sdl-build-options INTERFACE "${PKG_WAYLAND_INCLUDE_DIRS}")
+      target_include_directories(sdl-build-options SYSTEM INTERFACE "${PKG_WAYLAND_INCLUDE_DIRS}")
 
       set(HAVE_WAYLAND TRUE)
       set(HAVE_SDL_VIDEO TRUE)
@@ -693,7 +693,7 @@ macro(CheckWayland)
 
       # We have to generate some protocol interface code for some unstable Wayland features.
       file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols")
-      target_include_directories(sdl-build-options INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols")
+      target_include_directories(sdl-build-options SYSTEM INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols")
 
       file(GLOB WAYLAND_PROTOCOLS_XML RELATIVE "${SDL2_SOURCE_DIR}/wayland-protocols/" "${SDL2_SOURCE_DIR}/wayland-protocols/*.xml")
       foreach(_XML ${WAYLAND_PROTOCOLS_XML})
@@ -729,7 +729,7 @@ macro(CheckWayland)
             set(HAVE_WAYLAND_LIBDECOR TRUE)
             set(HAVE_LIBDECOR_H 1)
             target_link_directories(sdl-build-options INTERFACE "${PKG_LIBDECOR_LIBRARY_DIRS}")
-            target_include_directories(sdl-build-options INTERFACE "${PKG_LIBDECOR_INCLUDE_DIRS}")
+            target_include_directories(sdl-build-options SYSTEM INTERFACE "${PKG_LIBDECOR_INCLUDE_DIRS}")
             if(SDL_WAYLAND_LIBDECOR_SHARED AND NOT HAVE_SDL_LOADSO)
                 message_warn("You must have SDL_LoadObject() support for dynamic libdecor loading")
             endif()
@@ -1303,7 +1303,7 @@ macro(CheckKMSDRM)
     pkg_check_modules(PKG_KMSDRM libdrm gbm egl)
     if(PKG_KMSDRM_FOUND AND HAVE_OPENGL_EGL)
       target_link_directories(sdl-build-options INTERFACE ${PKG_KMSDRM_LIBRARY_DIRS})
-      target_include_directories(sdl-build-options INTERFACE "${PKG_KMSDRM_INCLUDE_DIRS}")
+      target_include_directories(sdl-build-options SYSTEM INTERFACE "${PKG_KMSDRM_INCLUDE_DIRS}")
       set(HAVE_KMSDRM TRUE)
       set(HAVE_SDL_VIDEO TRUE)
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a7099e16c08a..82bb2da4e3a9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.0...3.5)
 project(SDL2_test)
 
 include(CheckCCompilerFlag)
@@ -20,6 +20,32 @@ macro(add_sdl_test_executable TARGET)
     if(AST_NEEDS_RESOURCES)
         list(APPEND SDL_TESTS_NEEDS_ESOURCES ${TARGET})
     endif()
+
+    if(HAVE_GCC_WDOCUMENTATION)
+        target_compile_options(${TARGET} PRIVATE "-Wdocumentation")
+        if(HAVE_GCC_WERROR_DOCUMENTATION)
+            target_compile_options(${TARGET} PRIVATE "-Werror=documentation")
+        endif()
+    endif()
+
+    if(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
+        if(SDL_WERROR)
+            if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
+                target_compile_options(${TARGET} PRIVATE "-Werror=documentation-unknown-command")
+            endif()
+        endif()
+        target_compile_options(${TARGET} PRIVATE "-Wdocumentation-unknown-command")
+    endif()
+
+    if(HAVE_GCC_COMMENT_BLOCK_COMMANDS)
+        target_compile_options(${TARGET} PRIVATE "-fcomment-block-commands=threadsafety")
+        target_compile_options(${TARGET} PRIVATE "-fcomment-block-commands=deprecated")
+    else()
+        if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
+            target_compile_options(${TARGET} PRIVATE "/clang:-fcomment-block-commands=threadsafety")
+            target_compile_options(${TARGET} PRIVATE "/clang:-fcomment-block-commands=deprecated")
+        endif()
+    endif()
 endmacro()
 
 if(NOT TARGET SDL2::SDL2-static)
diff --git a/test/testautomation_math.c b/test/testautomation_math.c
index 87637c01db69..9c05ca5e53f1 100644
--- a/test/testautomation_math.c
+++ b/test/testautomation_math.c
@@ -64,10 +64,10 @@ typedef double(SDLCALL *dd_to_d_func)(double, double);
  * \brief Runs all the cases on a given function with a signature double -> double.
  * The result is expected to be exact.
  *
- * \param func_name, a printable name for the tested function.
- * \param func, the function to call.
- * \param cases, an array of all the cases.
- * \param cases_size, the size of the cases array.
+ * \param func_name a printable name for the tested function.
+ * \param func the function to call.
+ * \param cases an array of all the cases.
+ * \param cases_size the size of the cases array.
  */
 static int
 helper_dtod(const char *func_name, d_to_d_func func,
@@ -90,10 +90,10 @@ helper_dtod(const char *func_name, d_to_d_func func,
  * \brief Runs all the cases on a given function with a signature double -> double.
  * Checks if the result between expected +/- EPSILON.
  *
- * \param func_name, a printable name for the tested function.
- * \param func, the function to call.
- * \param cases, an array of all the cases.
- * \param cases_size, the size of the cases array.
+ * \param func_name a printable name for the tested function.
+ * \param func the function to call.
+ * \param cases an array of all the cases.
+ * \param cases_size the size of the cases array.
  */
 static int
 helper_dtod_inexact(const char *func_name, d_to_d_func func,
@@ -119,10 +119,10 @@ helper_dtod_inexact(const char *func_name, d_to_d_func func,
  * \brief Runs all the cases on a given function with a signature
  * (double, double) -> double. The result is expected to be exact.
  *
- * \param func_name, a printable name for the tested function.
- * \param func, the function to call.
- * \param cases, an array of all the cases.
- * \param cases_size, the size of the cases array.
+ * \param func_name a printable name for the tested function.
+ * \param func the function to call.
+ * \param cases an array of all the cases.
+ * \param cases_size the size of the cases array.
  */
 static int
 helper_ddtod(const char *func_name, dd_to_d_func func,
@@ -145,10 +145,10 @@ helper_ddtod(const char *func_name, dd_to_d_func func,
  * \brief Runs all the cases on a given function with a signature
  * (double, double) -> double. Checks if the result between expected +/- EPSILON.
  *
- * \param func_name, a printable name for the tested function.
- * \param func, the function to call.
- * \param cases, an array of all the cases.
- * \param cases_size, the size of the cases array.
+ * \param func_name a printable name for the tested function.
+ * \param func the function to call.
+ * \param cases an array of all the cases.
+ * \param cases_size the size of the cases array.
  */
 static int
 helper_ddtod_inexact(const char *func_name, dd_to_d_func func,
@@ -176,8 +176,8 @@ helper_ddtod_inexact(const char *func_name, dd_to_d_func func,
  * This function is only meant to test functions that returns the input value if it is
  * integral: f(x) -> x for x in N.
  *
- * \param func_name, a printable name for the tested function.
- * \param func, the function to call.
+ * \param func_name a printable name for the tested function.
+ * \param func the function to call.
  */
 static int
 helper_range(const char *func_name, d_to_d_func func)
diff --git a/test/testautomation_render.c b/test/testautomation_render.c
index 74b96314609b..b03524489dc7 100644
--- a/test/testautomation_render.c
+++ b/test/testautomation_render.c
@@ -1043,7 +1043,7 @@ _hasTexAlpha(void)
 /**
  * @brief Compares screen pixels with image pixels. Helper function.
  *
- * @param s Image to compare against.
+ * @param referenceSurface Image to compare against.
  *
  * \sa
  * http://wiki.libsdl.org/SDL_RenderReadPixels