]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
cmake: speed up and extend picky clang/gcc options
authorViktor Szakats <commit@vsz.me>
Sun, 16 Apr 2023 22:28:25 +0000 (22:28 +0000)
committerViktor Szakats <commit@vsz.me>
Sun, 16 Apr 2023 22:28:25 +0000 (22:28 +0000)
Extend existing picky compiler options with ones missing compared to
autotools builds. Also sync options between clang and gcc.

Redesign the way we enable these options to avoid the slow option
detection almost completely.

This reduces the number of detections from 35 to zero for clang and
3 for gcc, even after adding a bunch of new options.

clang 3.0 (2011-11-29) and gcc 2.95 (1999-07-31) now required.

Also show enabled picky options.

Ref: https://github.com/libssh2/libssh2/pull/952

Reviewed-by: Daniel Stenberg
Closes #10973

CMake/PickyWarnings.cmake [new file with mode: 0644]
CMakeLists.txt
Makefile.am

diff --git a/CMake/PickyWarnings.cmake b/CMake/PickyWarnings.cmake
new file mode 100644 (file)
index 0000000..1310cb4
--- /dev/null
@@ -0,0 +1,197 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+include(CheckCCompilerFlag)
+
+if(PICKY_COMPILER)
+  if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+
+    # https://clang.llvm.org/docs/DiagnosticsReference.html
+    # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+
+    # WPICKY_ENABLE = Options we want to enable as-is.
+    # WPICKY_DETECT = Options we want to test first and enable if available.
+
+    # Prefer the -Wextra alias with clang.
+    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+      set(WPICKY_ENABLE "-Wextra")
+    else()
+      set(WPICKY_ENABLE "-W")
+    endif()
+
+    list(APPEND WPICKY_ENABLE
+      -Wall -pedantic
+    )
+
+    # ----------------------------------
+    # Add new options here, if in doubt:
+    # ----------------------------------
+    set(WPICKY_DETECT
+    )
+
+    # Assume these options always exist with both clang and gcc.
+    # Require clang 3.0 / gcc 2.95 or later.
+    list(APPEND WPICKY_ENABLE
+      -Wbad-function-cast                  # clang  3.0  gcc  2.95
+      -Wconversion                         # clang  3.0  gcc  2.95
+      -Winline                             # clang  1.0  gcc  1.0
+      -Wmissing-declarations               # clang  1.0  gcc  2.7
+      -Wmissing-prototypes                 # clang  1.0  gcc  1.0
+      -Wnested-externs                     # clang  1.0  gcc  2.7
+      -Wno-long-long                       # clang  1.0  gcc  2.95
+      -Wno-multichar                       # clang  1.0  gcc  2.95
+      -Wpointer-arith                      # clang  1.0  gcc  1.4
+      -Wshadow                             # clang  1.0  gcc  2.95
+      -Wsign-compare                       # clang  1.0  gcc  2.95
+      -Wundef                              # clang  1.0  gcc  2.95
+      -Wunused                             # clang  1.1  gcc  2.95
+      -Wwrite-strings                      # clang  1.0  gcc  1.4
+    )
+
+    # Always enable with clang, version dependent with gcc
+    set(WPICKY_COMMON_OLD
+      -Wcast-align                         # clang  1.0  gcc  4.2
+      -Wdeclaration-after-statement        # clang  1.0  gcc  3.4
+      -Wempty-body                         # clang  3.0  gcc  4.3
+      -Wendif-labels                       # clang  1.0  gcc  3.3
+      -Wfloat-equal                        # clang  1.0  gcc  2.96 (3.0)
+      -Wignored-qualifiers                 # clang  3.0  gcc  4.3
+      -Wno-format-nonliteral               # clang  1.0  gcc  2.96 (3.0)
+      -Wno-sign-conversion                 # clang  3.0  gcc  4.3
+      -Wno-system-headers                  # clang  1.0  gcc  3.0
+      -Wstrict-prototypes                  # clang  1.0  gcc  3.3
+      -Wtype-limits                        # clang  3.0  gcc  4.3
+      -Wvla                                # clang  2.8  gcc  4.3
+    )
+
+    set(WPICKY_COMMON
+      -Wdouble-promotion                   # clang  3.6  gcc  4.6  appleclang  6.3
+      -Wenum-conversion                    # clang  3.2  gcc 10.0  appleclang  4.6  g++ 11.0
+      -Wunused-const-variable              # clang  3.4  gcc  6.0  appleclang  5.1
+    )
+
+    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+      list(APPEND WPICKY_ENABLE
+        ${WPICKY_COMMON_OLD}
+        -Wshift-sign-overflow              # clang  2.9
+        -Wshorten-64-to-32                 # clang  1.0
+      )
+      # Enable based on compiler version
+      if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
+         (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
+        list(APPEND WPICKY_ENABLE
+          ${WPICKY_COMMON}
+        )
+      endif()
+      if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
+         (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3))
+        list(APPEND WPICKY_ENABLE
+          -Wcomma                          # clang  3.9            appleclang  8.3
+          -Wmissing-variable-declarations  # clang  3.2            appleclang  4.6
+        )
+      endif()
+      if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR
+         (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3))
+        list(APPEND WPICKY_ENABLE
+          -Wassign-enum                    # clang  7.0            appleclang 10.3
+          -Wextra-semi-stmt                # clang  7.0            appleclang 10.3
+        )
+      endif()
+    else()  # gcc
+      list(APPEND WPICKY_DETECT
+        ${WPICKY_COMMON}
+      )
+      # Enable based on compiler version
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
+        list(APPEND WPICKY_ENABLE
+          ${WPICKY_COMMON_OLD}
+          -Wmissing-parameter-type         #             gcc  4.3
+          -Wold-style-declaration          #             gcc  4.3
+          -Wstrict-aliasing=3              #             gcc  4.0
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW)
+        list(APPEND WPICKY_ENABLE
+          -Wno-pedantic-ms-format          #             gcc  4.5 (mingw-only)
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
+        list(APPEND WPICKY_ENABLE
+          -Wformat=2                       # clang  3.0  gcc  4.8 (clang part-default, enabling it fully causes -Wformat-nonliteral warnings)
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
+        list(APPEND WPICKY_ENABLE
+          -Warray-bounds=2 -ftree-vrp      # clang  3.0  gcc  5.0 (clang default: -Warray-bounds)
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
+        list(APPEND WPICKY_ENABLE
+          -Wduplicated-cond                #             gcc  6.0
+          -Wnull-dereference               # clang  3.0  gcc  6.0 (clang default)
+            -fdelete-null-pointer-checks
+          -Wshift-negative-value           # clang  3.7  gcc  6.0 (clang default)
+          -Wshift-overflow=2               # clang  3.0  gcc  6.0 (clang default: -Wshift-overflow)
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
+        list(APPEND WPICKY_ENABLE
+          -Walloc-zero                     #             gcc  7.0
+          -Wduplicated-branches            #             gcc  7.0
+          -Wformat-overflow=2              #             gcc  7.0
+          -Wformat-truncation=1            #             gcc  7.0
+          -Wrestrict                       #             gcc  7.0
+        )
+      endif()
+      if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
+        list(APPEND WPICKY_ENABLE
+          -Warith-conversion               #             gcc 10.0
+        )
+      endif()
+    endif()
+
+    #
+
+    unset(WPICKY)
+
+    foreach(_CCOPT ${WPICKY_ENABLE})
+      set(WPICKY "${WPICKY} ${_CCOPT}")
+    endforeach()
+
+    foreach(_CCOPT ${WPICKY_DETECT})
+      # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
+      # test result in.
+      string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
+      # GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
+      # so test for the positive form instead
+      string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}")
+      check_c_compiler_flag(${_CCOPT_ON} ${_optvarname})
+      if(${_optvarname})
+        set(WPICKY "${WPICKY} ${_CCOPT}")
+      endif()
+    endforeach()
+
+    message(STATUS "Picky compiler options:${WPICKY}")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WPICKY}")
+  endif()
+endif()
index 542957455fa1658a334e2b49406cdbbba10b6af8..a0fe76c244d42e096b5b1a5572d9259dbed0d61b 100644 (file)
@@ -127,28 +127,7 @@ cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DN
 option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
 option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
 
-if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
-  if(PICKY_COMPILER)
-    foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wfloat-equal -Wsign-compare -Wundef -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wvla -Wdouble-promotion -Wenum-conversion -Warith-conversion)
-      # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
-      # test result in.
-      string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
-      check_c_compiler_flag(${_CCOPT} ${_optvarname})
-      if(${_optvarname})
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
-      endif()
-    endforeach()
-    foreach(_CCOPT long-long multichar format-nonliteral sign-conversion system-headers pedantic-ms-format)
-      # GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
-      # so test for the positive form instead
-      string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
-      check_c_compiler_flag("-W${_CCOPT}" ${_optvarname})
-      if(${_optvarname})
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-${_CCOPT}")
-      endif()
-    endforeach()
-  endif()
-endif()
+include(PickyWarnings)
 
 if(ENABLE_DEBUG)
   # DEBUGBUILD will be defined only for Debug builds
index ac1ecd994460dffe4194eea8a6f443a7b6dc5a05..f25e4e2f0ed4de583b02a35a3d8fcf8c69592e50 100644 (file)
@@ -49,6 +49,7 @@ CMAKE_DIST =                                    \
  CMake/FindZstd.cmake                           \
  CMake/Macros.cmake                             \
  CMake/OtherTests.cmake                         \
+ CMake/PickyWarnings.cmake                      \
  CMake/Platforms/WindowsCache.cmake             \
  CMake/Utilities.cmake                          \
  CMakeLists.txt