A C library for asynchronous DNS requests (grpc依赖)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
14 KiB

# Copyright (c) Monetra Technologies LLC
# SPDX-License-Identifier: MIT
# EnableWarnings.cmake
#
# Checks for and turns on a large number of warning C flags.
#
# Adds the following helper functions:
#
# remove_warnings(... list of warnings ...)
# Turn off given list of individual warnings for all targets and subdirectories added after this.
#
# remove_all_warnings()
# Remove all warning flags, add -w to suppress built-in warnings.
#
# remove_all_warnings_from_targets(... list of targets ...)
# Suppress warnings for the given targets only.
#
# push_warnings()
# Save current warning flags by pushing them onto an internal stack. Note that modifications to the internal
# stack are only visible in the current CMakeLists.txt file and its children.
#
# Note: changing warning flags multiple times in the same directory only affects add_subdirectory() calls.
# Targets in the directory will always use the warning flags in effect at the end of the CMakeLists.txt
# file - this is due to really weird and annoying legacy behavior of CMAKE_C_FLAGS.
#
# pop_warnings()
# Restore the last set of flags that were saved with push_warnings(). Note that modifications to the internal
# stack are only visible in the current CMakeLists.txt file and its children.
#
if (_internal_enable_warnings_already_run)
return()
endif ()
set(_internal_enable_warnings_already_run TRUE)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Helper functions
# This function can be called in subdirectories, to prune out warnings that they don't want.
# vararg: warning flags to remove from list of enabled warnings. All "no" flags after EXPLICIT_DISABLE
# will be added to C flags.
#
# Ex.: remove_warnings(-Wall -Wdouble-promotion -Wcomment) prunes those warnings flags from the compile command.
function(remove_warnings)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
set(langs C)
if ("CXX" IN_LIST languages)
list(APPEND langs CXX)
endif ()
foreach(lang ${langs})
set(toadd)
set(in_explicit_disable FALSE)
foreach (flag ${ARGN})
if (flag STREQUAL "EXPLICIT_DISABLE")
set(in_explicit_disable TRUE)
elseif (in_explicit_disable)
list(APPEND toadd "${flag}")
else ()
string(REGEX REPLACE "${flag}([ \t]+|$)" "" CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
endif ()
endforeach ()
_int_enable_warnings_set_flags(lang ${toadd})
string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
endforeach()
endfunction()
# Explicitly suppress all warnings. As long as this flag is the last warning flag, warnings will be
# suppressed even if earlier flags enabled warnings.
function(remove_all_warnings)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
set(langs C)
if ("CXX" IN_LIST languages)
list(APPEND langs CXX)
endif ()
foreach(lang ${langs})
string(REGEX REPLACE "[-/][Ww][^ \t]*([ \t]+|$)" "" CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
if (MSVC)
string(APPEND CMAKE_${lang}_FLAGS " /w")
else ()
string(APPEND CMAKE_${lang}_FLAGS " -w")
endif ()
string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
endforeach()
endfunction()
function(remove_all_warnings_from_targets)
foreach (target ${ARGN})
if (MSVC)
target_compile_options(${target} PRIVATE "/w")
else ()
target_compile_options(${target} PRIVATE "-w")
endif ()
endforeach()
endfunction()
# Save the current warning settings to an internal variable.
function(push_warnings)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
set(langs C)
if ("CXX" IN_LIST languages)
list(APPEND langs CXX)
endif ()
foreach(lang ${langs})
if (CMAKE_${lang}_FLAGS MATCHES ";")
message(AUTHOR_WARNING "Cannot push warnings for ${lang}, CMAKE_${lang}_FLAGS contains semicolons")
continue()
endif ()
# Add current flags to end of internal list.
list(APPEND _enable_warnings_internal_${lang}_flags_stack "${CMAKE_${lang}_FLAGS}")
# Propagate results up to caller's scope.
set(_enable_warnings_internal_${lang}_flags_stack "${_enable_warnings_internal_${lang}_flags_stack}" PARENT_SCOPE)
endforeach()
endfunction()
# Restore the current warning settings from an internal variable.
function(pop_warnings)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
set(langs C)
if ("CXX" IN_LIST languages)
list(APPEND langs CXX)
endif ()
foreach(lang ${langs})
if (NOT _enable_warnings_internal_${lang}_flags_stack)
continue()
endif ()
# Pop flags off of end of list, overwrite current flags with whatever we popped off.
list(GET _enable_warnings_internal_${lang}_flags_stack -1 CMAKE_${lang}_FLAGS)
list(REMOVE_AT _enable_warnings_internal_${lang}_flags_stack -1)
# Propagate results up to caller's scope.
set(_enable_warnings_internal_${lang}_flags_stack "${_enable_warnings_internal_${lang}_flags_stack}" PARENT_SCOPE)
string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
endforeach()
endfunction()
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Runs when included automatically
# internal helper: _int_enable_warnings_set_flags_ex(langs_var configs_var [warnings flags])
function(_int_enable_warnings_set_flags_ex langs_var configs_var)
if (NOT ARGN)
return()
endif ()
if (NOT ${configs_var})
set(${configs_var} "NONE")
endif ()
string(TOUPPER "${${configs_var}}" ${configs_var})
foreach(_flag ${ARGN})
string(MAKE_C_IDENTIFIER "HAVE_${_flag}" varname)
if ("C" IN_LIST ${langs_var})
check_c_compiler_flag(${_flag} ${varname})
if (${varname})
foreach (config IN LISTS ${configs_var})
if (config STREQUAL "NONE")
set(config)
else ()
set(config "_${config}")
endif ()
string(APPEND CMAKE_C_FLAGS${config} " ${_flag}")
endforeach ()
endif ()
endif ()
if ("CXX" IN_LIST ${langs_var})
string(APPEND varname "_CXX")
check_cxx_compiler_flag(${_flag} ${varname})
if (${varname})
foreach (config IN LISTS ${configs_var})
if (config STREQUAL "NONE")
set(config)
else ()
set(config "_${config}")
endif ()
string(APPEND CMAKE_CXX_FLAGS${config} " ${_flag}")
endforeach ()
endif ()
endif ()
endforeach()
foreach(lang C CXX)
foreach (config IN LISTS ${configs_var})
string(TOUPPER "${config}" config)
if (config STREQUAL "NONE")
set(config)
else ()
set(config "_${config}")
endif ()
string(STRIP "${CMAKE_${lang}_FLAGS${config}}" CMAKE_${lang}_FLAGS${config})
set(CMAKE_${lang}_FLAGS${config} "${CMAKE_${lang}_FLAGS${config}}" PARENT_SCOPE)
endforeach ()
endforeach()
endfunction()
# internal helper: _int_enable_warnings_set_flags(langs_var [warnings flags])
macro(_int_enable_warnings_set_flags langs_var)
set(configs "NONE")
_int_enable_warnings_set_flags_ex(${langs_var} configs ${ARGN})
endmacro()
set(_flags_C)
set(_flags_CXX)
set(_debug_flags_C)
set(_debug_flags_CXX)
if (MSVC)
# Don't automatically set /W3
CMAKE_POLICY (SET CMP0092 NEW)
# Visual Studio uses a completely different nomenclature for warnings than gcc/mingw/clang, so none of the
# "-W[name]" warnings will work.
set(_flags
# Enable warnings
/W4 # Baseline reasonable warnings
/w14242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
/w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/w14263 # 'function': member function does not override any base class virtual member function
/w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may
# not be destructed correctly
/w14287 # 'operator': unsigned/negative constant mismatch
/we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside
# the for-loop scope
/w14296 # 'operator': expression is always 'boolean_value'
/w14311 # 'variable': pointer truncation from 'type1' to 'type2'
/w14545 # expression before comma evaluates to a function which is missing an argument list
/w14546 # function call before comma missing argument list
/w14547 # 'operator': operator before comma has no effect; expected operator with side-effect
/w14549 # 'operator': operator before comma has no effect; did you intend 'operator'?
/w14555 # expression has no effect; expected expression with side- effect
/w14619 # pragma warning: there is no warning number 'number'
/w14640 # Enable warning on thread un-safe static member initialization
/w14826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
/w14905 # wide string literal cast to 'LPSTR'
/w14906 # string literal cast to 'LPWSTR'
/w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
# Disable some warnings
/wd4201 # nonstandard extension used: nameless struct/union. Used in some windows headers, e.g. IO_STATUS_BLOCK,
# disable.
# Turn some warnings into errors
/we4013 # Treat "function undefined, assuming extern returning int" warning as an error. https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4013
)
list(APPEND _flags_C ${_flags})
list(APPEND _flags_CXX ${_flags})
elseif (CMAKE_C_COMPILER_ID MATCHES "Intel")
# Intel's compiler warning flags are more like Visual Studio than GCC, though the numbers aren't the same.
set(_flags
# Use warning level 3, quite wordy.
-w3
# Disable warnings we don't care about (add more as they are encountered).
-wd383 # Spammy warning about initializing from a temporary object in C++ (which is done all the time ...).
-wd11074 # Diagnostic related to inlining.
-wd11076 # Diagnostic related to inlining.
)
list(APPEND _flags_C ${_flags})
list(APPEND _flags_CXX ${_flags})
elseif (CMAKE_C_COMPILER_ID MATCHES "XL")
set (_flags
-qwarn64
-qformat=all
-qflag=i:i
)
list(APPEND _flags_C ${_flags})
list(APPEND _flags_CXX ${_flags})
else ()
# If we're compiling with GCC / Clang / MinGW (or anything else besides Visual Studio or Intel):
# C Flags:
list(APPEND _flags_C
-Wall
-Wextra
# Enable additional warnings not covered by Wall and Wextra.
-Waggregate-return
-Wcast-align
-Wcast-qual
-Wconversion
-Wdeclaration-after-statement
-Wdouble-promotion
-Wfloat-equal
-Wformat-security
-Winit-self
-Wjump-misses-init
-Wlogical-op
-Wmissing-braces
-Wmissing-declarations
-Wmissing-format-attribute
-Wmissing-include-dirs
-Wmissing-prototypes
-Wnested-externs
-Wno-coverage-mismatch
-Wold-style-definition
-Wpacked
-Wpedantic
-Wpointer-arith
-Wredundant-decls
-Wshadow
-Wsign-conversion
-Wstrict-overflow
-Wstrict-prototypes
-Wtrampolines
-Wundef
-Wunreachable-code
-Wunused
-Wvariadic-macros
-Wvla
-Wwrite-strings
# On Windows MinGW I think implicit fallthrough enabled by -Wextra must not default to 3
-Wimplicit-fallthrough=3
# Treat implicit variable typing and implicit function declarations as errors.
-Werror=implicit-int
-Werror=implicit-function-declaration
# Make MacOSX honor -mmacosx-version-min
-Werror=partial-availability
# Some clang versions might warn if an argument like "-I/path/to/headers" is unused,
# silence these.
-Qunused-arguments
-Wno-long-long
)
# C++ flags:
list(APPEND _flags_CXX
-Wall
-Wextra
# Enable additional warnings not covered by Wall and Wextra.
-Wcast-align
-Wformat-security
-Wmissing-declarations
-Wmissing-format-attribute
-Wpacked-bitfield-compat
-Wredundant-decls
-Wvla
# Turn off unused parameter warnings with C++ (they happen often in C++ and Qt).
-Wno-unused-parameter
# Some clang versions might warn if an argument like "-I/path/to/headers" is unused,
# silence these.
-Qunused-arguments
)
# Note: when cross-compiling to Windows from Cygwin, the Qt Mingw packages have a bunch of
# noisy type-conversion warnings in headers. So, only enable those warnings if we're
# not building that configuration.
if (NOT (WIN32 AND (CMAKE_HOST_SYSTEM_NAME MATCHES "CYGWIN")))
list(APPEND _flags_CXX
-Wconversion
-Wfloat-equal
-Wsign-conversion
)
endif ()
# Add flags to force colored output even when output is redirected via pipe.
if (CMAKE_GENERATOR MATCHES "Ninja")
set(color_default TRUE)
else ()
set(color_default FALSE)
endif ()
option(FORCE_COLOR "Force compiler to always colorize, even when output is redirected." ${color_default})
mark_as_advanced(FORCE FORCE_COLOR)
if (FORCE_COLOR)
set(_flags
-fdiagnostics-color=always # GCC
-fcolor-diagnostics # Clang
)
list(APPEND _flags_C ${_flags})
list(APPEND _flags_CXX ${_flags})
endif ()
# Add -fno-omit-frame-pointer (and optionally -fno-inline) to make debugging and stack dumps nicer.
set(_flags
-fno-omit-frame-pointer
)
option(M_NO_INLINE "Disable function inlining for RelWithDebInfo and Debug configurations?" FALSE)
if (M_NO_INLINE)
list(APPEND _flags
-fno-inline
)
endif ()
list(APPEND _debug_flags_C ${_flags})
list(APPEND _debug_flags_CXX ${_flags})
endif ()
# Check and set compiler flags.
set(_debug_configs
RelWithDebInfo
Debug
)
foreach(_lang ${languages})
_int_enable_warnings_set_flags(_lang ${_flags_${_lang}})
_int_enable_warnings_set_flags_ex(_lang _debug_configs ${_debug_flags_${_lang}})
# Ensure pure Debug builds are NOT optimized (not possible on Visual Studio).
# Any optimization of a Debug build will prevent debuggers like lldb from
# fully displaying backtraces and stepping.
if (NOT MSVC)
set(_config Debug)
_int_enable_warnings_set_flags_ex(_lang _config -O0)
endif ()
endforeach()
# CMP0092 doesn't appear to really work, really remove the /W3 here.
if (MSVC)
remove_warnings(/W3)
endif ()