1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-18 15:20:56 +03:00
Files
libssh2/cmake/max_warnings.cmake
Viktor Szakats ec0feae792 build: speed up and extend picky compiler options
Implement picky warnings with clang in autotools. Extend picky gcc
warnings, sync them between build tools and compilers and greatly
speed up detection in CMake.

- autotools: enable clang compiler warnings with `--enable-debug`.

- autotools: enable more gcc compiler warnings with `--enable-debug`.

- autotools/cmake: sync compiler warning options between gcc and clang.

- sync compiler warning options between autotools and cmake.

- cmake: reduce option-checks to speed up the detection phase.
  Bring them down to 3 (from 35). Leaving some checks to keep the
  CMake logic alive and for an easy way to add new options.

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

- autotools logic copied from curl, with these differences:

  - delete `-Wimplicit-fallthrough=4` due to a false positive.

  - reduce `-Wformat-truncation=2` to `1` due to a false positive.

  - simplify MinGW detection for `-Wno-pedantic-ms-format`.

- cmake: show enabled picky compiler options (like autotools).

- cmake: do compile `tests/simple.c` and `tests/ssh2.c`.

- fix new compiler warnings.

- `tests/CMakeLists.txt`: fix indentation.

Original source of autotools logic:
- a8fbdb461c/acinclude.m4
- a8fbdb461c/m4/curl-compilers.m4

Notice that the autotools implementation considers Apple clang as
legacy clang 3.7. CMake detection works more accurately, at the same
time more error-prone and difficult to update due to the sparsely
documented nature of Apple clang option evolution.

Closes #952
2023-04-13 11:12:22 +00:00

209 lines
8.4 KiB
CMake

include(CheckCCompilerFlag)
option(ENABLE_WERROR "Turn compiler warnings into errors" OFF)
option(PICKY_COMPILER "Enable picky compiler options" ON)
if(ENABLE_WERROR)
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
else() # llvm/clang and gcc style options
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif()
endif()
if(MSVC)
# Use the highest warning level for Visual Studio.
if(PICKY_COMPILER)
if(CMAKE_CXX_FLAGS MATCHES "[/-]W[0-4]")
string(REGEX REPLACE "[/-]W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
if(CMAKE_C_FLAGS MATCHES "[/-]W[0-4]")
string(REGEX REPLACE "[/-]W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
endif()
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
# https://clang.llvm.org/docs/DiagnosticsReference.html
# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
if(NOT CMAKE_C_FLAGS MATCHES "-Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
endif()
if(PICKY_COMPILER)
# 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
-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
-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 1.0
-Wno-long-long # clang 1.0 gcc 2.95
-Wno-multichar # clang 1.0 gcc 2.95
-Wpointer-arith # clang 1.0 gcc 1.0
-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.0
)
# 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()