1#*************************************************************************** 2# _ _ ____ _ 3# Project ___| | | | _ \| | 4# / __| | | | |_) | | 5# | (__| |_| | _ <| |___ 6# \___|\___/|_| \_\_____| 7# 8# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9# 10# This software is licensed as described in the file COPYING, which 11# you should have received as part of this distribution. The terms 12# are also available at https://curl.se/docs/copyright.html. 13# 14# You may opt to use, copy, modify, merge, publish, distribute and/or sell 15# copies of the Software, and permit persons to whom the Software is 16# furnished to do so, under the terms of the COPYING file. 17# 18# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19# KIND, either express or implied. 20# 21# SPDX-License-Identifier: curl 22# 23########################################################################### 24include(CheckCCompilerFlag) 25 26unset(_picky) 27 28if(CURL_WERROR AND 29 ((CMAKE_COMPILER_IS_GNUCC AND 30 NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND 31 NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR # to avoid check_symbol_exists() conflicting with GCC -pedantic-errors 32 CMAKE_C_COMPILER_ID MATCHES "Clang")) 33 list(APPEND _picky "-pedantic-errors") 34 if(MSVC) # clang-cl 35 list(APPEND _picky "-Wno-language-extension-token") # Override default error to make __int64 size detection pass 36 endif() 37endif() 38 39if(APPLE AND 40 (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR 41 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3)) 42 list(APPEND _picky "-Werror=partial-availability") # clang 3.6 appleclang 6.3 43endif() 44 45if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 46 list(APPEND _picky "-Werror-implicit-function-declaration") # clang 1.0 gcc 2.95 47endif() 48 49if(PICKY_COMPILER) 50 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 51 52 # https://clang.llvm.org/docs/DiagnosticsReference.html 53 # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html 54 55 # _picky_enable = Options we want to enable as-is. 56 # _picky_detect = Options we want to test first and enable if available. 57 58 # Prefer the -Wextra alias with clang. 59 if(CMAKE_C_COMPILER_ID MATCHES "Clang") 60 set(_picky_enable "-Wextra") 61 else() 62 set(_picky_enable "-W") 63 endif() 64 65 list(APPEND _picky_enable 66 -Wall -pedantic 67 ) 68 69 # ---------------------------------- 70 # Add new options here, if in doubt: 71 # ---------------------------------- 72 set(_picky_detect 73 ) 74 75 # Assume these options always exist with both clang and gcc. 76 # Require clang 3.0 / gcc 2.95 or later. 77 list(APPEND _picky_enable 78 -Wbad-function-cast # clang 2.7 gcc 2.95 79 -Wconversion # clang 2.7 gcc 2.95 80 -Winline # clang 1.0 gcc 1.0 81 -Wmissing-declarations # clang 1.0 gcc 2.7 82 -Wmissing-prototypes # clang 1.0 gcc 1.0 83 -Wnested-externs # clang 1.0 gcc 2.7 84 -Wno-long-long # clang 1.0 gcc 2.95 85 -Wno-multichar # clang 1.0 gcc 2.95 86 -Wpointer-arith # clang 1.0 gcc 1.4 87 -Wshadow # clang 1.0 gcc 2.95 88 -Wsign-compare # clang 1.0 gcc 2.95 89 -Wundef # clang 1.0 gcc 2.95 90 -Wunused # clang 1.1 gcc 2.95 91 -Wwrite-strings # clang 1.0 gcc 1.4 92 ) 93 94 # Always enable with clang, version dependent with gcc 95 set(_picky_common_old 96 -Waddress # clang 2.7 gcc 4.3 97 -Wattributes # clang 2.7 gcc 4.1 98 -Wcast-align # clang 1.0 gcc 4.2 99 -Wdeclaration-after-statement # clang 1.0 gcc 3.4 100 -Wdiv-by-zero # clang 2.7 gcc 4.1 101 -Wempty-body # clang 2.7 gcc 4.3 102 -Wendif-labels # clang 1.0 gcc 3.3 103 -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) 104 -Wformat-security # clang 2.7 gcc 4.1 105 -Wignored-qualifiers # clang 2.8 gcc 4.3 106 -Wmissing-field-initializers # clang 2.7 gcc 4.1 107 -Wmissing-noreturn # clang 2.7 gcc 4.1 108 -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) 109 -Wno-system-headers # clang 1.0 gcc 3.0 110 # -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs 111 -Wold-style-definition # clang 2.7 gcc 3.4 112 -Wredundant-decls # clang 2.7 gcc 4.1 113 -Wsign-conversion # clang 2.9 gcc 4.3 114 -Wno-error=sign-conversion # FIXME 115 -Wstrict-prototypes # clang 1.0 gcc 3.3 116 # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case 117 -Wtype-limits # clang 2.7 gcc 4.3 118 -Wunreachable-code # clang 2.7 gcc 4.1 119 # -Wunused-macros # clang 2.7 gcc 4.1 # Not practical 120 -Wunused-parameter # clang 2.7 gcc 4.1 121 -Wvla # clang 2.8 gcc 4.3 122 ) 123 124 set(_picky_common 125 -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 126 -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 127 -Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0 128 -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 129 ) 130 131 if(CMAKE_C_COMPILER_ID MATCHES "Clang") 132 list(APPEND _picky_enable 133 ${_picky_common_old} 134 -Wshift-sign-overflow # clang 2.9 135 -Wshorten-64-to-32 # clang 1.0 136 -Wformat=2 # clang 3.0 gcc 4.8 137 ) 138 if(NOT MSVC) 139 list(APPEND _picky_enable 140 -Wlanguage-extension-token # clang 3.0 # Avoid for clang-cl to allow __int64 141 ) 142 endif() 143 # Enable based on compiler version 144 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR 145 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3)) 146 list(APPEND _picky_enable 147 ${_picky_common} 148 # -Wunreachable-code-break # clang 3.5 appleclang 6.0 # Not used: Silent in "unity" builds 149 -Wheader-guard # clang 3.4 appleclang 5.1 150 -Wsometimes-uninitialized # clang 3.2 appleclang 4.6 151 ) 152 endif() 153 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR 154 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3)) 155 list(APPEND _picky_enable 156 -Wcomma # clang 3.9 appleclang 8.3 157 -Wmissing-variable-declarations # clang 3.2 appleclang 4.6 158 ) 159 endif() 160 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR 161 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3)) 162 list(APPEND _picky_enable 163 -Wassign-enum # clang 7.0 appleclang 10.3 164 -Wextra-semi-stmt # clang 7.0 appleclang 10.3 165 ) 166 endif() 167 if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) OR 168 (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.4)) 169 list(APPEND _picky_enable 170 -Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # We do silencing for clang 10.0 and above only 171 ) 172 endif() 173 else() # gcc 174 list(APPEND _picky_detect 175 ${_picky_common} 176 ) 177 # Enable based on compiler version 178 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3) 179 list(APPEND _picky_enable 180 ${_picky_common_old} 181 -Wclobbered # gcc 4.3 182 -Wmissing-parameter-type # gcc 4.3 183 -Wold-style-declaration # gcc 4.3 184 -Wstrict-aliasing=3 # gcc 4.0 185 -Wtrampolines # gcc 4.3 186 ) 187 endif() 188 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW) 189 list(APPEND _picky_enable 190 -Wno-pedantic-ms-format # gcc 4.5 (MinGW-only) 191 ) 192 endif() 193 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) 194 list(APPEND _picky_enable 195 -Wformat=2 # clang 3.0 gcc 4.8 196 ) 197 endif() 198 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) 199 list(APPEND _picky_enable 200 -Warray-bounds=2 -ftree-vrp # clang 3.0 gcc 5.0 (clang default: -Warray-bounds) 201 ) 202 endif() 203 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) 204 list(APPEND _picky_enable 205 -Wduplicated-cond # gcc 6.0 206 -Wnull-dereference # clang 3.0 gcc 6.0 (clang default) 207 -fdelete-null-pointer-checks 208 -Wshift-negative-value # clang 3.7 gcc 6.0 (clang default) 209 -Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow) 210 ) 211 endif() 212 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) 213 list(APPEND _picky_enable 214 -Walloc-zero # gcc 7.0 215 -Wduplicated-branches # gcc 7.0 216 -Wformat-truncation=2 # gcc 7.0 217 -Wimplicit-fallthrough # clang 4.0 gcc 7.0 218 -Wrestrict # gcc 7.0 219 ) 220 endif() 221 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) 222 list(APPEND _picky_enable 223 -Warith-conversion # gcc 10.0 224 ) 225 endif() 226 endif() 227 228 # 229 230 foreach(_ccopt IN LISTS _picky_enable) 231 list(APPEND _picky "${_ccopt}") 232 endforeach() 233 234 foreach(_ccopt IN LISTS _picky_detect) 235 # Use a unique variable name 1. for meaningful log output 2. to have a fresh, undefined variable for each detection 236 string(MAKE_C_IDENTIFIER "OPT${_ccopt}" _optvarname) 237 # GCC only warns about unknown -Wno- options if there are also other diagnostic messages, 238 # so test for the positive form instead 239 string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}") 240 check_c_compiler_flag(${_ccopt_on} ${_optvarname}) 241 if(${_optvarname}) 242 list(APPEND _picky "${_ccopt}") 243 endif() 244 endforeach() 245 endif() 246endif() 247 248# clang-cl 249if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC) 250 if(CMAKE_VERSION VERSION_LESS 3.12) 251 set(_picky_tmp "") 252 foreach(_ccopt IN LISTS _picky) 253 list(APPEND _picky_tmp "/clang:${_ccopt}") 254 endforeach() 255 set(_picky ${_picky_tmp}) 256 else() 257 list(TRANSFORM _picky PREPEND "/clang:") 258 endif() 259endif() 260 261if(_picky) 262 string(REPLACE ";" " " _picky "${_picky}") 263 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_picky}") 264 message(STATUS "Picky compiler options: ${_picky}") 265endif() 266