Update minimum CMake version to 3.16

This replaces some workarounds and manual logic with new features
available with CMake 3.16, including list(FILTER), list(JOIN),
foreach(IN LISTS) and enable_language(OBJC).  Policy settings no longer
needed with 3.16 have been removed.

Related to #2541
diff --git a/CMake/GenerateMappings.cmake b/CMake/GenerateMappings.cmake
index c8c9e23..9a95df6 100644
--- a/CMake/GenerateMappings.cmake
+++ b/CMake/GenerateMappings.cmake
@@ -1,6 +1,8 @@
 # Usage:
 # cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
 
+cmake_policy(VERSION 3.16)
+
 set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
 set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
 set(template_path "${CMAKE_ARGV3}")
@@ -22,24 +24,24 @@
 endif()
 
 file(STRINGS "${source_path}" lines)
-foreach(line ${lines})
-    if (line MATCHES "^[0-9a-fA-F]")
-        if (line MATCHES "platform:Windows")
-            if (GLFW_WIN32_MAPPINGS)
-                string(APPEND GLFW_WIN32_MAPPINGS "\n")
-            endif()
-            string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
-        elseif (line MATCHES "platform:Mac OS X")
-            if (GLFW_COCOA_MAPPINGS)
-                string(APPEND GLFW_COCOA_MAPPINGS "\n")
-            endif()
-            string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
-        elseif (line MATCHES "platform:Linux")
-            if (GLFW_LINUX_MAPPINGS)
-                string(APPEND GLFW_LINUX_MAPPINGS "\n")
-            endif()
-            string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
+list(FILTER lines INCLUDE REGEX "^[0-9a-fA-F]")
+
+foreach(line IN LISTS lines)
+    if (line MATCHES "platform:Windows")
+        if (GLFW_WIN32_MAPPINGS)
+            string(APPEND GLFW_WIN32_MAPPINGS "\n")
         endif()
+        string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
+    elseif (line MATCHES "platform:Mac OS X")
+        if (GLFW_COCOA_MAPPINGS)
+            string(APPEND GLFW_COCOA_MAPPINGS "\n")
+        endif()
+        string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
+    elseif (line MATCHES "platform:Linux")
+        if (GLFW_LINUX_MAPPINGS)
+            string(APPEND GLFW_LINUX_MAPPINGS "\n")
+        endif()
+        string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
     endif()
 endforeach()
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 830f8fd..398b36e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,6 @@
-cmake_minimum_required(VERSION 3.4...3.28 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.16...3.28 FATAL_ERROR)
 
-project(GLFW VERSION 3.5.0 LANGUAGES C)
-
-if (POLICY CMP0069)
-    cmake_policy(SET CMP0069 NEW)
-endif()
-
-if (POLICY CMP0077)
-    cmake_policy(SET CMP0077 NEW)
-endif()
+project(GLFW VERSION 3.5.0 LANGUAGES C HOMEPAGE_URL "https://www.glfw.org/")
 
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
@@ -80,24 +72,7 @@
 # This is here because it also applies to tests and examples
 #--------------------------------------------------------------------
 if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
-    if (CMAKE_VERSION VERSION_LESS 3.15)
-        foreach (flag CMAKE_C_FLAGS
-                      CMAKE_C_FLAGS_DEBUG
-                      CMAKE_C_FLAGS_RELEASE
-                      CMAKE_C_FLAGS_MINSIZEREL
-                      CMAKE_C_FLAGS_RELWITHDEBINFO)
-
-            if (flag MATCHES "/MD")
-                string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
-            endif()
-            if (flag MATCHES "/MDd")
-                string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
-            endif()
-
-        endforeach()
-    else()
-        set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-    endif()
+    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
 endif()
 
 #--------------------------------------------------------------------
diff --git a/README.md b/README.md
index 10044fa..fb77b9d 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@
 
 ## Dependencies
 
-GLFW itself needs only CMake 3.4 or later and the headers and libraries for your
+GLFW itself needs only CMake 3.16 or later and the headers and libraries for your
 OS and window system.
 
 The examples and test programs depend on a number of tiny libraries.  These are
@@ -123,6 +123,7 @@
 
  - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
    the limit of the mouse button tokens to be reported (#2423)
+ - Updated minimum CMake version to 3.16 (#2541)
  - [Cocoa] Added `QuartzCore` framework as link-time dependency
  - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
  - [Wayland] Bugfix: The fractional scaling related objects were not destroyed
diff --git a/docs/compile.md b/docs/compile.md
index f8385fe..6b0b712 100644
--- a/docs/compile.md
+++ b/docs/compile.md
@@ -264,8 +264,8 @@
 static library version of the Visual C++ runtime library.  When enabled, the
 DLL version of the Visual C++ library is used.  This is enabled by default.
 
-On CMake 3.15 and later you can set the standard CMake [CMAKE_MSVC_RUNTIME_LIBRARY][]
-variable instead of this GLFW-specific option.
+It is recommended to set the standard CMake variable [CMAKE_MSVC_RUNTIME_LIBRARY][]
+instead of this GLFW-specific option.
 
 [CMAKE_MSVC_RUNTIME_LIBRARY]: https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7a8726d..fc4e17c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -30,6 +30,7 @@
 set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3")
 
 if (GLFW_BUILD_COCOA)
+    enable_language(OBJC)
     target_compile_definitions(glfw PRIVATE _GLFW_COCOA)
     target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h cocoa_init.m
                                 cocoa_joystick.m cocoa_monitor.m cocoa_window.m
@@ -137,13 +138,6 @@
                            "${GLFW_BINARY_DIR}/src")
 target_link_libraries(glfw PRIVATE Threads::Threads)
 
-# Workaround for CMake not knowing about .m files before version 3.16
-if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
-    set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
-                                cocoa_window.m nsgl_context.m PROPERTIES
-                                LANGUAGE C)
-endif()
-
 if (GLFW_BUILD_WIN32)
     list(APPEND glfw_PKG_LIBS "-lgdi32")
 endif()
@@ -349,12 +343,8 @@
     endif()
 endif()
 
-foreach(arg ${glfw_PKG_DEPS})
-    string(APPEND deps " ${arg}")
-endforeach()
-foreach(arg ${glfw_PKG_LIBS})
-    string(APPEND libs " ${arg}")
-endforeach()
+list(JOIN glfw_PKG_DEPS " " deps)
+list(JOIN glfw_PKG_LIBS " " libs)
 
 set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL
     "GLFW pkg-config Requires.private")