quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

EnableWarnings.cmake (14203B)


      1 # Copyright (c) Monetra Technologies LLC
      2 # SPDX-License-Identifier: MIT
      3 
      4 # EnableWarnings.cmake
      5 #
      6 # Checks for and turns on a large number of warning C flags.
      7 #
      8 # Adds the following helper functions:
      9 #
     10 #	remove_warnings(... list of warnings ...)
     11 #		Turn off given list of individual warnings for all targets and subdirectories added after this.
     12 #
     13 #   remove_all_warnings()
     14 #		Remove all warning flags, add -w to suppress built-in warnings.
     15 #
     16 #   remove_all_warnings_from_targets(... list of targets ...)
     17 #       Suppress warnings for the given targets only.
     18 #
     19 #   push_warnings()
     20 #		Save current warning flags by pushing them onto an internal stack. Note that modifications to the internal
     21 #		stack are only visible in the current CMakeLists.txt file and its children.
     22 #
     23 #       Note: changing warning flags multiple times in the same directory only affects add_subdirectory() calls.
     24 #             Targets in the directory will always use the warning flags in effect at the end of the CMakeLists.txt
     25 #             file - this is due to really weird and annoying legacy behavior of CMAKE_C_FLAGS.
     26 #
     27 #   pop_warnings()
     28 #       Restore the last set of flags that were saved with push_warnings(). Note that modifications to the internal
     29 #		stack are only visible in the current CMakeLists.txt file and its children.
     30 #
     31 
     32 if (_internal_enable_warnings_already_run)
     33 	return()
     34 endif ()
     35 set(_internal_enable_warnings_already_run TRUE)
     36 
     37 include(CheckCCompilerFlag)
     38 include(CheckCXXCompilerFlag)
     39 
     40 get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
     41 
     42 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     43 # Helper functions
     44 
     45 
     46 # This function can be called in subdirectories, to prune out warnings that they don't want.
     47 #  vararg: warning flags to remove from list of enabled warnings. All "no" flags after EXPLICIT_DISABLE
     48 #          will be added to C flags.
     49 #
     50 # Ex.: remove_warnings(-Wall -Wdouble-promotion -Wcomment) prunes those warnings flags from the compile command.
     51 function(remove_warnings)
     52 	get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
     53 	set(langs C)
     54 	if ("CXX" IN_LIST languages)
     55 		list(APPEND langs CXX)
     56 	endif ()
     57 
     58 	foreach(lang ${langs})
     59 		set(toadd)
     60 		set(in_explicit_disable FALSE)
     61 		foreach (flag ${ARGN})
     62 			if (flag STREQUAL "EXPLICIT_DISABLE")
     63 				set(in_explicit_disable TRUE)
     64 			elseif (in_explicit_disable)
     65 				list(APPEND toadd "${flag}")
     66 			else ()
     67 				string(REGEX REPLACE "${flag}([ \t]+|$)" "" CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
     68 			endif ()
     69 		endforeach ()
     70 		_int_enable_warnings_set_flags(lang ${toadd})
     71 		string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
     72 		set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
     73 	endforeach()
     74 endfunction()
     75 
     76 
     77 # Explicitly suppress all warnings. As long as this flag is the last warning flag, warnings will be
     78 # suppressed even if earlier flags enabled warnings.
     79 function(remove_all_warnings)
     80 	get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
     81 	set(langs C)
     82 	if ("CXX" IN_LIST languages)
     83 		list(APPEND langs CXX)
     84 	endif ()
     85 
     86 	foreach(lang ${langs})
     87 		string(REGEX REPLACE "[-/][Ww][^ \t]*([ \t]+|$)" "" CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
     88 		if (MSVC)
     89 			string(APPEND CMAKE_${lang}_FLAGS " /w")
     90 		else ()
     91 			string(APPEND CMAKE_${lang}_FLAGS " -w")
     92 		endif ()
     93 		string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
     94 		set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
     95 	endforeach()
     96 endfunction()
     97 
     98 
     99 function(remove_all_warnings_from_targets)
    100 	foreach (target ${ARGN})
    101 		if (MSVC)
    102 			target_compile_options(${target} PRIVATE "/w")
    103 		else ()
    104 			target_compile_options(${target} PRIVATE "-w")
    105 		endif ()
    106 	endforeach()
    107 endfunction()
    108 
    109 
    110 # Save the current warning settings to an internal variable.
    111 function(push_warnings)
    112 	get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
    113 	set(langs C)
    114 	if ("CXX" IN_LIST languages)
    115 		list(APPEND langs CXX)
    116 	endif ()
    117 
    118 	foreach(lang ${langs})
    119 		if (CMAKE_${lang}_FLAGS MATCHES ";")
    120 			message(AUTHOR_WARNING "Cannot push warnings for ${lang}, CMAKE_${lang}_FLAGS contains semicolons")
    121 			continue()
    122 		endif ()
    123 		# Add current flags to end of internal list.
    124 		list(APPEND _enable_warnings_internal_${lang}_flags_stack "${CMAKE_${lang}_FLAGS}")
    125 		# Propagate results up to caller's scope.
    126 		set(_enable_warnings_internal_${lang}_flags_stack "${_enable_warnings_internal_${lang}_flags_stack}" PARENT_SCOPE)
    127 	endforeach()
    128 endfunction()
    129 
    130 
    131 # Restore the current warning settings from an internal variable.
    132 function(pop_warnings)
    133 	get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
    134 	set(langs C)
    135 	if ("CXX" IN_LIST languages)
    136 		list(APPEND langs CXX)
    137 	endif ()
    138 
    139 	foreach(lang ${langs})
    140 		if (NOT _enable_warnings_internal_${lang}_flags_stack)
    141 			continue()
    142 		endif ()
    143 		# Pop flags off of end of list, overwrite current flags with whatever we popped off.
    144 		list(GET _enable_warnings_internal_${lang}_flags_stack -1 CMAKE_${lang}_FLAGS)
    145 		list(REMOVE_AT _enable_warnings_internal_${lang}_flags_stack -1)
    146 		# Propagate results up to caller's scope.
    147 		set(_enable_warnings_internal_${lang}_flags_stack "${_enable_warnings_internal_${lang}_flags_stack}" PARENT_SCOPE)
    148 		string(STRIP "${CMAKE_${lang}_FLAGS}" CMAKE_${lang}_FLAGS)
    149 		set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}" PARENT_SCOPE)
    150 	endforeach()
    151 endfunction()
    152 
    153 
    154 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    155 # Runs when included automatically
    156 
    157 # internal helper: _int_enable_warnings_set_flags_ex(langs_var configs_var [warnings flags])
    158 function(_int_enable_warnings_set_flags_ex langs_var configs_var)
    159 	if (NOT ARGN)
    160 		return()
    161 	endif ()
    162 
    163 	if (NOT ${configs_var})
    164 		set(${configs_var} "NONE")
    165 	endif ()
    166 	string(TOUPPER "${${configs_var}}" ${configs_var})
    167 
    168 	foreach(_flag ${ARGN})
    169 		string(MAKE_C_IDENTIFIER "HAVE_${_flag}" varname)
    170 
    171 		if ("C" IN_LIST ${langs_var})
    172 			check_c_compiler_flag(${_flag} ${varname})
    173 			if (${varname})
    174 				foreach (config IN LISTS ${configs_var})
    175 					if (config STREQUAL "NONE")
    176 						set(config)
    177 					else ()
    178 						set(config "_${config}")
    179 					endif ()
    180 					string(APPEND CMAKE_C_FLAGS${config} " ${_flag}")
    181 				endforeach ()
    182 			endif ()
    183 		endif ()
    184 
    185 		if ("CXX" IN_LIST ${langs_var})
    186 			string(APPEND varname "_CXX")
    187 			check_cxx_compiler_flag(${_flag} ${varname})
    188 			if (${varname})
    189 				foreach (config IN LISTS ${configs_var})
    190 					if (config STREQUAL "NONE")
    191 						set(config)
    192 					else ()
    193 						set(config "_${config}")
    194 					endif ()
    195 					string(APPEND CMAKE_CXX_FLAGS${config} " ${_flag}")
    196 				endforeach ()
    197 			endif ()
    198 		endif ()
    199 	endforeach()
    200 
    201 	foreach(lang C CXX)
    202 		foreach (config IN LISTS ${configs_var})
    203 			string(TOUPPER "${config}" config)
    204 			if (config STREQUAL "NONE")
    205 				set(config)
    206 			else ()
    207 				set(config "_${config}")
    208 			endif ()
    209 			string(STRIP "${CMAKE_${lang}_FLAGS${config}}" CMAKE_${lang}_FLAGS${config})
    210 			set(CMAKE_${lang}_FLAGS${config} "${CMAKE_${lang}_FLAGS${config}}" PARENT_SCOPE)
    211 		endforeach ()
    212 	endforeach()
    213 endfunction()
    214 
    215 # internal helper: _int_enable_warnings_set_flags(langs_var [warnings flags])
    216 macro(_int_enable_warnings_set_flags langs_var)
    217 	set(configs "NONE")
    218 	_int_enable_warnings_set_flags_ex(${langs_var} configs ${ARGN})
    219 endmacro()
    220 
    221 set(_flags_C)
    222 set(_flags_CXX)
    223 set(_debug_flags_C)
    224 set(_debug_flags_CXX)
    225 
    226 if (MSVC)
    227 	# Don't automatically set /W3
    228 	CMAKE_POLICY (SET CMP0092 NEW)
    229 
    230 	# Visual Studio uses a completely different nomenclature for warnings than gcc/mingw/clang, so none of the
    231 	# "-W[name]" warnings will work.
    232 
    233 	set(_flags
    234 		# Enable warnings
    235 		/W4 # Baseline reasonable warnings
    236 		/w14242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
    237 		/w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
    238 		/w14263 # 'function': member function does not override any base class virtual member function
    239 		/w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may
    240 		        # not be destructed correctly
    241 		/w14287 # 'operator': unsigned/negative constant mismatch
    242 		/we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside
    243 		        # the for-loop scope
    244 		/w14296 # 'operator': expression is always 'boolean_value'
    245 		/w14311 # 'variable': pointer truncation from 'type1' to 'type2'
    246 		/w14545 # expression before comma evaluates to a function which is missing an argument list
    247 		/w14546 # function call before comma missing argument list
    248 		/w14547 # 'operator': operator before comma has no effect; expected operator with side-effect
    249 		/w14549 # 'operator': operator before comma has no effect; did you intend 'operator'?
    250 		/w14555 # expression has no effect; expected expression with side- effect
    251 		/w14619 # pragma warning: there is no warning number 'number'
    252 		/w14640 # Enable warning on thread un-safe static member initialization
    253 		/w14826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
    254 		/w14905 # wide string literal cast to 'LPSTR'
    255 		/w14906 # string literal cast to 'LPWSTR'
    256 		/w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
    257 
    258 		# Disable some warnings
    259 		/wd4201 # nonstandard extension used: nameless struct/union. Used in some windows headers, e.g. IO_STATUS_BLOCK,
    260 		        # disable.
    261 
    262 		# Turn some warnings into errors
    263 		/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
    264 	)
    265 
    266 	list(APPEND _flags_C   ${_flags})
    267 	list(APPEND _flags_CXX ${_flags})
    268 
    269 elseif (CMAKE_C_COMPILER_ID MATCHES "Intel")
    270 	# Intel's compiler warning flags are more like Visual Studio than GCC, though the numbers aren't the same.
    271 	set(_flags
    272 		# Use warning level 3, quite wordy.
    273 		-w3
    274 		# Disable warnings we don't care about (add more as they are encountered).
    275 		-wd383    # Spammy warning about initializing from a temporary object in C++ (which is done all the time ...).
    276 		-wd11074  # Diagnostic related to inlining.
    277 		-wd11076  # Diagnostic related to inlining.
    278 	)
    279 
    280 	list(APPEND _flags_C   ${_flags})
    281 	list(APPEND _flags_CXX ${_flags})
    282 
    283 elseif (CMAKE_C_COMPILER_ID MATCHES "XL")
    284 	set (_flags
    285 		-qwarn64
    286 		-qformat=all
    287 		-qflag=i:i
    288 	)
    289 	list(APPEND _flags_C   ${_flags})
    290 	list(APPEND _flags_CXX ${_flags})
    291 
    292 else ()
    293 	# If we're compiling with GCC / Clang / MinGW (or anything else besides Visual Studio or Intel):
    294 	# C Flags:
    295 	list(APPEND _flags_C
    296 		-Wall
    297 		-Wextra
    298 
    299 		# Enable additional warnings not covered by Wall and Wextra.
    300 		-Waggregate-return
    301 		-Wcast-align
    302 		-Wcast-qual
    303 		-Wconversion
    304 		-Wdeclaration-after-statement
    305 		-Wdouble-promotion
    306 		-Wfloat-equal
    307 		-Wformat-security
    308 		-Winit-self
    309 		-Wjump-misses-init
    310 		-Wlogical-op
    311 		-Wmissing-braces
    312 		-Wmissing-declarations
    313 		-Wmissing-format-attribute
    314 		-Wmissing-include-dirs
    315 		-Wmissing-prototypes
    316 		-Wnested-externs
    317 		-Wno-coverage-mismatch
    318 		-Wold-style-definition
    319 		-Wpacked
    320 		-Wpedantic
    321 		-Wpointer-arith
    322 		-Wredundant-decls
    323 		-Wshadow
    324 		-Wsign-conversion
    325 		-Wstrict-overflow
    326 		-Wstrict-prototypes
    327 		-Wtrampolines
    328 		-Wundef
    329 		-Wunreachable-code
    330 		-Wunused
    331 		-Wvariadic-macros
    332 		-Wvla
    333 		-Wwrite-strings
    334 
    335 		# On Windows MinGW I think implicit fallthrough enabled by -Wextra must not default to 3
    336 		-Wimplicit-fallthrough=3
    337 
    338 		# Treat implicit variable typing and implicit function declarations as errors.
    339 		-Werror=implicit-int
    340 		-Werror=implicit-function-declaration
    341 
    342 		# Make MacOSX honor -mmacosx-version-min
    343 		-Werror=partial-availability
    344 
    345 		# Some clang versions might warn if an argument like "-I/path/to/headers" is unused,
    346 		# silence these.
    347 		-Qunused-arguments
    348 
    349 		-Wno-long-long
    350 	)
    351 
    352 	# C++ flags:
    353 	list(APPEND _flags_CXX
    354 		-Wall
    355 		-Wextra
    356 
    357 		# Enable additional warnings not covered by Wall and Wextra.
    358 		-Wcast-align
    359 		-Wformat-security
    360 		-Wmissing-declarations
    361 		-Wmissing-format-attribute
    362 		-Wpacked-bitfield-compat
    363 		-Wredundant-decls
    364 		-Wvla
    365 
    366 		# Turn off unused parameter warnings with C++ (they happen often in C++ and Qt).
    367 		-Wno-unused-parameter
    368 
    369 		# Some clang versions might warn if an argument like "-I/path/to/headers" is unused,
    370 		# silence these.
    371 		-Qunused-arguments
    372 	)
    373 
    374 	# Note: when cross-compiling to Windows from Cygwin, the Qt Mingw packages have a bunch of
    375 	#       noisy type-conversion warnings in headers. So, only enable those warnings if we're
    376 	#       not building that configuration.
    377 	if (NOT (WIN32 AND (CMAKE_HOST_SYSTEM_NAME MATCHES "CYGWIN")))
    378 		list(APPEND _flags_CXX
    379 			-Wconversion
    380 			-Wfloat-equal
    381 			-Wsign-conversion
    382 		)
    383 	endif ()
    384 
    385 	# Add flags to force colored output even when output is redirected via pipe.
    386 	if (CMAKE_GENERATOR MATCHES "Ninja")
    387 		set(color_default TRUE)
    388 	else ()
    389 		set(color_default FALSE)
    390 	endif ()
    391 	option(FORCE_COLOR "Force compiler to always colorize, even when output is redirected." ${color_default})
    392 	mark_as_advanced(FORCE FORCE_COLOR)
    393 	if (FORCE_COLOR)
    394 		set(_flags
    395 			-fdiagnostics-color=always # GCC
    396 			-fcolor-diagnostics        # Clang
    397 		)
    398 		list(APPEND _flags_C   ${_flags})
    399 		list(APPEND _flags_CXX ${_flags})
    400 	endif ()
    401 
    402 	# Add -fno-omit-frame-pointer (and optionally -fno-inline) to make debugging and stack dumps nicer.
    403 	set(_flags
    404 		-fno-omit-frame-pointer
    405 	)
    406 	option(M_NO_INLINE "Disable function inlining for RelWithDebInfo and Debug configurations?" FALSE)
    407 	if (M_NO_INLINE)
    408 		list(APPEND _flags
    409 			-fno-inline
    410 		)
    411 	endif ()
    412 	list(APPEND _debug_flags_C   ${_flags})
    413 	list(APPEND _debug_flags_CXX ${_flags})
    414 endif ()
    415 
    416 # Check and set compiler flags.
    417 set(_debug_configs
    418 	RelWithDebInfo
    419 	Debug
    420 )
    421 foreach(_lang ${languages})
    422 	_int_enable_warnings_set_flags(_lang ${_flags_${_lang}})
    423 	_int_enable_warnings_set_flags_ex(_lang _debug_configs ${_debug_flags_${_lang}})
    424 
    425 	# Ensure pure Debug builds are NOT optimized (not possible on Visual Studio).
    426 	# Any optimization of a Debug build will prevent debuggers like lldb from
    427 	# fully displaying backtraces and stepping.
    428 	if (NOT MSVC)
    429 		set(_config Debug)
    430 		_int_enable_warnings_set_flags_ex(_lang _config -O0)
    431 	endif ()
    432 endforeach()
    433 
    434 # CMP0092 doesn't appear to really work, really remove the /W3 here.
    435 if (MSVC)
    436   remove_warnings(/W3)
    437 endif ()