From 27ba56c6930fde312466ceb15c64e7f6241f5e31 Mon Sep 17 00:00:00 2001 From: David Korth Date: Wed, 21 May 2025 18:14:39 -0400 Subject: [PATCH] [cmake] Backport more changes from rom-properties. Changes include: - Add RelWithDebugInfo flags. - Add NixOS handling. - Add ENABLE_WERROR. - Add more warning flags. - Add "-fprofile-update=atomic" for code coverage. - Fix DT_RELR. - Enable C++ assertions for libstdc++ and libc++. --- cmake/macros/DirInstallPaths.cmake | 19 +++++- cmake/options.cmake | 21 ++++--- cmake/platform.cmake | 12 ++++ cmake/platform/gcc.cmake | 99 +++++++++++++++++++++++------- cmake/platform/msvc.cmake | 89 +++++++++++++++++++-------- 5 files changed, 183 insertions(+), 57 deletions(-) diff --git a/cmake/macros/DirInstallPaths.cmake b/cmake/macros/DirInstallPaths.cmake index 095b0c9..8c00834 100644 --- a/cmake/macros/DirInstallPaths.cmake +++ b/cmake/macros/DirInstallPaths.cmake @@ -51,13 +51,26 @@ IF(UNIX AND NOT APPLE) SET(DIR_INSTALL_TRANSLATIONS "share/${PACKAGE_NAME}/translations") SET(DIR_INSTALL_DOC "share/doc/${PACKAGE_NAME}") SET(DIR_INSTALL_DOC_ROOT "${DIR_INSTALL_DOC}") - SET(DIR_INSTALL_XDG_DESKTOP "share/applications") SET(DIR_INSTALL_XDG_APPSTREAM "share/metainfo") SET(DIR_INSTALL_XDG_ICONS "share/icons") + SET(DIR_INSTALL_XDG_DESKTOP "share/applications") SET(DIR_INSTALL_EXE_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_EXE}") SET(DIR_INSTALL_DLL_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_DLL}") SET(DIR_INSTALL_LIB_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIB}") + IF(ENABLE_NIXOS) + # NixOS ends up with a double-path issue if CMAKE_INSTALL_PREFIX is specified here. + SET(DIR_INSTALL_EXE_DEBUG "lib/debug/${DIR_INSTALL_EXE}") + SET(DIR_INSTALL_DLL_DEBUG "lib/debug/${DIR_INSTALL_DLL}") + SET(DIR_INSTALL_LIB_DEBUG "lib/debug/${DIR_INSTALL_LIB}") + SET(DIR_INSTALL_LIBEXEC_DEBUG "lib/debug/${DIR_INSTALL_LIBEXEC}") + ELSE(ENABLE_NIXOS) + SET(DIR_INSTALL_EXE_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_EXE}") + SET(DIR_INSTALL_DLL_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_DLL}") + SET(DIR_INSTALL_LIB_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIB}") + SET(DIR_INSTALL_LIBEXEC_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIBEXEC}") + ENDIF(ENABLE_NIXOS) + # AppArmor profile directory SET(DIR_INSTALL_APPARMOR "/etc/apparmor.d") ELSEIF(APPLE) @@ -70,9 +83,9 @@ ELSEIF(APPLE) SET(DIR_INSTALL_TRANSLATIONS "share/${PACKAGE_NAME}/translations") SET(DIR_INSTALL_DOC "share/doc/${PACKAGE_NAME}") SET(DIR_INSTALL_DOC_ROOT "${DIR_INSTALL_DOC}") - UNSET(DIR_INSTALL_XDG_DESKTOP) UNSET(DIR_INSTALL_XDG_APPSTREAM) UNSET(DIR_INSTALL_XDG_ICONS) + UNSET(DIR_INSTALL_XDG_DESKTOP) SET(DIR_INSTALL_EXE_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_EXE}") SET(DIR_INSTALL_DLL_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_DLL}") SET(DIR_INSTALL_LIB_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIB}") @@ -86,9 +99,9 @@ ELSEIF(WIN32) SET(DIR_INSTALL_TRANSLATIONS "translations") SET(DIR_INSTALL_DOC "doc") SET(DIR_INSTALL_DOC_ROOT ".") - UNSET(DIR_INSTALL_XDG_DESKTOP) UNSET(DIR_INSTALL_XDG_APPSTREAM) UNSET(DIR_INSTALL_XDG_ICONS) + UNSET(DIR_INSTALL_XDG_DESKTOP) SET(DIR_INSTALL_EXE_DEBUG "debug") # Installing debug symbols for DLLs in the # same directory as the DLL. diff --git a/cmake/options.cmake b/cmake/options.cmake index be28d04..9aef2ea 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -1,20 +1,22 @@ # Build options. -# Enable UDEV on Linux. +OPTION(ENABLE_WERROR "Treat all compile warnings as errors. (Enable for development!)" OFF) + +# Enable UDEV on Linux IF(UNIX AND NOT APPLE) OPTION(ENABLE_UDEV "Enable UDEV for the 'query' command." ON) ELSE() SET(ENABLE_UDEV OFF CACHE INTERNAL "Enable UDEV for the 'query' command." FORCE) ENDIF() -# Enable D-Bus for DockManager / Unity API. +# Enable D-Bus for DockManager / Unity API IF(UNIX AND NOT APPLE) - OPTION(ENABLE_DBUS "Enable D-Bus support for DockManager / Unity API." 1) + OPTION(ENABLE_DBUS "Enable D-Bus support for DockManager / Unity API." 1) ELSE(UNIX AND NOT APPLE) SET(ENABLE_DBUS 0) ENDIF(UNIX AND NOT APPLE) -# Link-time optimization. +# Link-time optimization # FIXME: Not working in clang builds and Ubuntu's gcc... IF(MSVC) SET(LTO_DEFAULT ON) @@ -23,7 +25,7 @@ ELSE() ENDIF() OPTION(ENABLE_LTO "Enable link-time optimization in release builds." ${LTO_DEFAULT}) -# Split debug information into a separate file. +# Split debug information into a separate file # FIXME: macOS `strip` shows an error: # error: symbols referenced by indirect symbol table entries that can't be stripped in: [library] IF(APPLE) @@ -32,7 +34,7 @@ ELSE(APPLE) OPTION(SPLIT_DEBUG "Split debug information into a separate file." ON) ENDIF(APPLE) -# Install the split debug file. +# Install the split debug file OPTION(INSTALL_DEBUG "Install the split debug files." ON) IF(INSTALL_DEBUG AND NOT SPLIT_DEBUG) # Cannot install debug files if we're not splitting them. @@ -43,5 +45,10 @@ ENDIF(INSTALL_DEBUG AND NOT SPLIT_DEBUG) SET(QT_VERSION 5 CACHE STRING "Qt version to use. (default is 5)") SET_PROPERTY(CACHE QT_VERSION PROPERTY STRINGS 5 6) -# Translations. +# Translations OPTION(ENABLE_NLS "Enable NLS using Qt's built-in localization system." ON) + +# Special handling for NixOS +IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + OPTION(ENABLE_NIXOS "Enable special handling for NixOS builds." OFF) +ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/cmake/platform.cmake b/cmake/platform.cmake index a8933ed..944eb69 100644 --- a/cmake/platform.cmake +++ b/cmake/platform.cmake @@ -36,6 +36,12 @@ ENDIF(NOT HAVE_STDINT_H) # - RP_EXE_LINKER_FLAGS_RELEASE # - RP_SHARED_LINKER_FLAGS_RELEASE # - RP_MODULE_LINKER_FLAGS_RELEASE +# [RelWithDebInfo] +# - RP_C_FLAGS_RELWITHDEBINFO +# - RP_CXX_FLAGS_RELWITHDEBINFO +# - RP_EXE_LINKER_FLAGS_RELWITHDEBINFO +# - RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO +# - RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO # # DEBUG and RELEASE variables do *not* include COMMON. IF(MSVC) @@ -98,6 +104,12 @@ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${RP_CXX_FLAGS_RELEASE} SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${RP_EXE_LINKER_FLAGS_RELEASE}") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${RP_SHARED_LINKER_FLAGS_RELEASE}") SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${RP_MODULE_LINKER_FLAGS_RELEASE}") +# RelWithDebInfo +SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${RP_C_FLAGS_RELWITHDEBINFO}") +SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${RP_CXX_FLAGS_RELWITHDEBINFO}") +SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO}") +SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} ${RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") +SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} ${RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO}") # Unset temporary variables. # Common diff --git a/cmake/platform/gcc.cmake b/cmake/platform/gcc.cmake index eac93d1..18052f4 100644 --- a/cmake/platform/gcc.cmake +++ b/cmake/platform/gcc.cmake @@ -10,12 +10,6 @@ ELSEIF(CMAKE_COMPILER_IS_GNUCXX) ENDIF() ENDIF() -# gcc-5.4 and earlier have issues with LTO. -IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND - CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - SET(GCC_5xx_LTO_ISSUES ON) -ENDIF() - # Compiler flag modules. INCLUDE(CheckCCompilerFlag) INCLUDE(CheckCXXCompilerFlag) @@ -30,13 +24,14 @@ ADD_DEFINITIONS(-D_GNU_SOURCE=1) # Test for common CFLAGS and CXXFLAGS. # NOTE: Not adding -Werror=format-nonliteral because there are some # legitimate uses of non-literal format strings. -SET(CFLAGS_WARNINGS -Wall -Wextra -Wno-multichar -Werror=return-type) +SET(CFLAGS_WARNINGS -Wall -Wextra -Wno-multichar -Werror=return-type -Wheader-hygiene -Wno-psabi) SET(CFLAGS_WERROR_FORMAT -Werror=format -Werror=format-security -Werror=format-signedness -Werror=format-truncation -Werror=format-y2k) +SET(CFLAGS_OPTIONS -fstrict-aliasing -Werror=strict-aliasing -fno-common -fcf-protection -fno-math-errno) IF(MINGW) # MinGW: Ignore warnings caused by casting from GetProcAddress(). SET(CFLAGS_WARNINGS ${CFLAGS_WARNINGS} -Wno-cast-function-type) ENDIF(MINGW) -FOREACH(FLAG_TEST ${CFLAGS_WARNINGS} ${CFLAGS_WERROR_FORMAT} "-fstrict-aliasing" "-fno-common" "-fcf-protection") +FOREACH(FLAG_TEST ${CFLAGS_WARNINGS} ${CFLAGS_WERROR_FORMAT} ${CFLAGS_OPTIONS}) # CMake doesn't like certain characters in variable names. STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") @@ -51,14 +46,20 @@ FOREACH(FLAG_TEST ${CFLAGS_WARNINGS} ${CFLAGS_WERROR_FORMAT} "-fstrict-aliasing" SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") ENDIF(CXXFLAG_${FLAG_TEST_VARNAME}) UNSET(CXXFLAG_${FLAG_TEST_VARNAME}) -ENDFOREACH() +ENDFOREACH(FLAG_TEST) -# -Wimplicit-function-declaration should be an error. (C only) -CHECK_C_COMPILER_FLAG("-Werror=implicit-function-declaration" CFLAG_IMPLFUNC) -IF(CFLAG_IMPLFUNC) - SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -Werror=implicit-function-declaration") -ENDIF(CFLAG_IMPLFUNC) -UNSET(CFLAG_IMPLFUNC) +# Certain warnings should be errors. (C only) +SET(CFLAGS_WERROR_C_ONLY -Werror=implicit -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=int-conversion) +FOREACH(FLAG_TEST ${CFLAGS_WERROR_C_ONLY}) + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + + CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) + IF(CFLAG_${FLAG_TEST_VARNAME}) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CFLAG_${FLAG_TEST_VARNAME}) + UNSET(CFLAG_${FLAG_TEST_VARNAME}) +ENDFOREACH(FLAG_TEST) # Enable "suggest override" if available. (C++ only) # NOTE: If gcc, only enable on 9.2 and later, since earlier versions @@ -88,10 +89,9 @@ IF(ENABLE_COVERAGE) # Don't bother checking for the coverage options. # We're assuming they're always supported. - SET(RP_C_FLAGS_COVERAGE "--coverage -fprofile-arcs -ftest-coverage") + SET(RP_C_FLAGS_COVERAGE "--coverage -fprofile-arcs -ftest-coverage -fprofile-update=atomic") SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_C_FLAGS_COVERAGE}") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_COVERAGE}") - SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_COVERAGE}") # Create a code coverage target. @@ -217,12 +217,12 @@ IF(UNIX AND NOT APPLE) SET(TMP_HAVE_DT_RELR FALSE) MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs glibc-2.36 or later") ENDIF() - UNSET(TMP_HAVE_DT_RELR) ELSE(_ld_out MATCHES "-z pack-relative-relocs") SET(TMP_HAVE_DT_RELR FALSE) MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs binutils-2.38 or later") ENDIF(_ld_out MATCHES "-z pack-relative-relocs") SET(HAVE_DT_RELR ${TMP_HAVE_DT_RELR} CACHE INTERNAL "System supports DT_RELR") + UNSET(TMP_HAVE_DT_RELR) ENDIF(NOT DEFINED HAVE_DT_RELR) IF(HAVE_DT_RELR) @@ -270,11 +270,54 @@ IF(CFLAG_OPTIMIZE_FTREE_VECTORIZE) ENDIF() ENDIF(CFLAG_OPTIMIZE_FTREE_VECTORIZE) -# Debug/release flags. +# Add "-Werror" *after* checking for everything else. +IF(ENABLE_WERROR) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -Werror") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} -Werror") + + SET(CFLAGS_WNO_ERROR -Wno-error=unknown-pragmas -Wno-error=address -Wno-error=attributes -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=ignored-qualifiers -Wno-error=missing-field-initializers -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=type-limits -Wno-error=empty-body -Wno-error=address-of-packed-member -Wno-error=shift-negative-value -Wno-error=clobbered -Wno-error=overloaded-virtual -Wno-error=header-hygiene -Wno-error=cast-align -Wno-error=stringop-overread) + FOREACH(FLAG_TEST ${CFLAGS_WNO_ERROR}) + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + + CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) + IF(CFLAG_${FLAG_TEST_VARNAME}) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CFLAG_${FLAG_TEST_VARNAME}) + UNSET(CFLAG_${FLAG_TEST_VARNAME}) + ENDFOREACH(FLAG_TEST) +ENDIF(ENABLE_WERROR) + +### Debug/Release flags ### + SET(RP_C_FLAGS_DEBUG "${CFLAG_OPTIMIZE_DEBUG} -ggdb -DDEBUG -D_DEBUG") SET(RP_CXX_FLAGS_DEBUG "${CFLAG_OPTIMIZE_DEBUG} -ggdb -DDEBUG -D_DEBUG") -SET(RP_C_FLAGS_RELEASE "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") -SET(RP_CXX_FLAGS_RELEASE "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") + +SET(RP_C_FLAGS_RELEASE "-O2 -DNDEBUG ${CFLAGS_VECTORIZE}") +SET(RP_CXX_FLAGS_RELEASE "-O2 -DNDEBUG ${CFLAGS_VECTORIZE}") + +SET(RP_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") +SET(RP_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") + +# Enable C++ assertions and other hardening options. (libstdc++ / libc++) +# TODO: Check for the actual C++ runtime being used instead of +# assuming libc++ is only used with Clang. +SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC") + +# libc++ (clang only) +IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_ASSERT=1 -D_LIBCPP_DEBUG=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1") + + IF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50) + # clang-17: Use _LIBCPP_HARDENING_MODE. + SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG") + ELSE(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50) + # clang-16 or earlier: Use _LIBCPP_ENABLE_ASSERTIONS. + # NOTE: _LIBCPP_ENABLE_ASSERTIONS causes an error if using clang-17 or later. + SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_ENABLE_ASSERTIONS=1") + ENDIF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50) +ENDIF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # Unset temporary variables. UNSET(CFLAG_OPTIMIZE_DEBUG) @@ -291,6 +334,14 @@ IF(ENABLE_LTO) # occur in gcc-4.9 due to "slim" LTO objects, and possibly # earlier versions for various reasons. MESSAGE(STATUS "Checking if the gcc LTO wrappers are available:") + + # gcc-5.4 and earlier have issues with LTO. + IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + MESSAGE(STATUS "Checking if the gcc LTO wrappers are available: too old") + MESSAGE(FATAL_ERROR "gcc 6.1 or later is required for LTO.") + ENDIF() + IF("${CMAKE_AR}" MATCHES "gcc-ar$") # Already using the gcc-ar wrapper. SET(GCC_WRAPPER_AR "${CMAKE_AR}") @@ -320,6 +371,12 @@ IF(ENABLE_LTO) SET(RP_EXE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin") SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_SHARED_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin") SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin") + + SET(RP_C_FLAGS_RELWITHDEBINFO "${RP_C_FLAGS_RELWITHDEBINFO} -flto") + SET(RP_CXX_FLAGS_RELWITHDEBINFO "${RP_CXX_FLAGS_RELWITHDEBINFO} -flto") + SET(RP_EXE_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin") + SET(RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin") + SET(RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin") ELSE(CFLAG_LTO) MESSAGE(FATAL_ERROR "LTO optimization requested but -flto is not supported.") ENDIF(CFLAG_LTO) diff --git a/cmake/platform/msvc.cmake b/cmake/platform/msvc.cmake index bebc622..8da9446 100644 --- a/cmake/platform/msvc.cmake +++ b/cmake/platform/msvc.cmake @@ -3,9 +3,18 @@ IF(MSVC_VERSION LESS 1600) MESSAGE(FATAL_ERROR "MSVC 2010 (10.0) or later is required.") ENDIF() +# If an SDK version isn't specified by the user, set it to 10.0. +IF(NOT CMAKE_SYSTEM_VERSION) + SET(CMAKE_SYSTEM_VERSION 10.0) +ENDIF(NOT CMAKE_SYSTEM_VERSION) + # Disable useless warnings: # - MSVC "logo" messages +# - C4005: macro redefinition (libpng's intprefix.out.tf1 is breaking on this...) +# - C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared # - C4355: 'this' used in base member initializer list (used for Qt Dpointer pattern) +# - C4503: 'identifier': decorated name length exceeded, name was truncated (MSVC 2015 and earlier) [generated by RomHeaderTest] +# - C4800: 'BOOL': forcing value to bool 'true' or 'false' (performance warning) # - MSVCRT "deprecated" functions # - std::tr1 deprecation # Increase some warnings to errors: @@ -14,9 +23,13 @@ ENDIF() # - C4024: 'function': different types for formal and actual parameter n # - C4047: 'function': 'parameter' differs in levels of indirection from 'argument' # - C4477: 'function' : format string 'string' requires an argument of type 'type', but variadic argument number has type 'type' -SET(RP_C_FLAGS_COMMON "/nologo /wd4355 /wd4482 /we4013 /we4024 /we4047 /we4477") -SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") -ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) +SET(RP_C_FLAGS_COMMON "/nologo /W3") +IF(ENABLE_WERROR) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /WX") +ENDIF(ENABLE_WERROR) +SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4005 /wd4091 /wd4355 /wd4503 /wd4800 /we4013 /we4024 /we4047 /we4477") +SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON}") +ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS) # NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003) # NOTE 2: /TSAWARE is not applicable for DLLs. SET(RP_EXE_LINKER_FLAGS_COMMON "/NOLOGO /DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE") @@ -44,12 +57,12 @@ FOREACH(FLAG_TEST "/sdl" "/utf-8" "/guard:cf" "/guard:ehcont") IF(CFLAG_${FLAG_TEST_VARNAME}) SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") - # "/guard:cf" and "/guard:ehcont" must be added to linker flags in addition to CFLAGS. - IF(FLAG_TEST STREQUAL "/guard:cf" OR FLAG_TEST STREQUAL "/guard:ehcont") + # "/guard:*" must be added to linker flags in addition to CFLAGS. + IF(FLAG_TEST MATCHES "^/guard:") SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} ${FLAG_TEST}") SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} ${FLAG_TEST}") SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} ${FLAG_TEST}") - ENDIF(FLAG_TEST STREQUAL "/guard:cf" OR FLAG_TEST STREQUAL "/guard:ehcont") + ENDIF(FLAG_TEST MATCHES "^/guard:") ENDIF(CFLAG_${FLAG_TEST_VARNAME}) UNSET(CFLAG_${FLAG_TEST_VARNAME}) ENDFOREACH() @@ -72,7 +85,7 @@ IF(MSVC_VERSION GREATER 1919 AND _MSVC_C_ARCHITECTURE_FAMILY MATCHES "^([iI]?[xX ENDIF() # MSVC: C/C++ conformance settings -FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline" "/permissive-") +FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline") # CMake doesn't like certain characters in variable names. STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") @@ -84,11 +97,29 @@ FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline" "/permissive-") UNSET(CFLAG_${FLAG_TEST_VARNAME}) ENDFOREACH() +# MSVC: C/C++ conformance settings +IF(CMAKE_SYSTEM_VERSION VERSION_GREATER 9.9) + FOREACH(FLAG_TEST "/permissive-") + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + + CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) + IF(CFLAG_${FLAG_TEST_VARNAME}) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CFLAG_${FLAG_TEST_VARNAME}) + UNSET(CFLAG_${FLAG_TEST_VARNAME}) + ENDFOREACH() +ENDIF() + # MSVC: C++ conformance settings INCLUDE(CheckCXXCompilerFlag) -SET(CXX_CONFORMANCE_FLAGS "/Zc:__cplusplus" "/Zc:rvalueCast" "/Zc:ternary") +SET(CXX_CONFORMANCE_FLAGS "/Zc:__cplusplus" "/Zc:checkGwOdr" "/Zc:rvalueCast" "/Zc:templateScope" "/Zc:ternary") IF(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - SET(CXX_CONFORMANCE_FLAGS "/Zc:externC" "/Zc:noexceptTypes") + # clang-cl enables certain conformance options by default, + # and these cause warnings to be printed if specified. + # Only enable these for original MSVC. + SET(CXX_CONFORMANCE_FLAGS ${CXX_CONFORMANCE_FLAGS} "/Zc:externC" "/Zc:noexceptTypes" "/Zc:throwingNew") ENDIF(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") FOREACH(FLAG_TEST ${CXX_CONFORMANCE_FLAGS}) # CMake doesn't like certain characters in variable names. @@ -101,18 +132,6 @@ FOREACH(FLAG_TEST ${CXX_CONFORMANCE_FLAGS}) UNSET(CXXFLAG_${FLAG_TEST_VARNAME}) ENDFOREACH() -# "/Zc:throwingNew" is always enabled on clang-cl, and causes -# warnings to be printed if it's specified. -# NOTE: "/Zc:throwingNew" was added in MSVC 2015. -IF(NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang) - INCLUDE(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("/Zc:throwingNew" CXXFLAG__Zc_throwingNew) - IF(CXXFLAG__Zc_throwingNew) - SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Zc:throwingNew") - ENDIF(CXXFLAG__Zc_throwingNew) - UNSET(CXXFLAG__Zc_throwingNew) -ENDIF(NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang) - # Disable warning C4996 (deprecated), then re-enable it. # Otherwise, it gets handled as an error due to /sdl. SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4996 /w34996") @@ -123,7 +142,7 @@ SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /wd4996 /w34996") # NOTE: Only for i386 and amd64; enabling elsewhere because # Windows XP and Windows Server 2003 weren't available for ARM. IF(MSVC_VERSION GREATER 1899 AND _MSVC_C_ARCHITECTURE_FAMILY MATCHES "^([iI]?[xX3]86)|([xX]64)$") - MESSAGE(STATUS "MSVC: Disabling thread-safe statics for Windows XP and Windows Server 2003 compatibility") + MESSAGE(STATUS "MSVC: Disabling thread-safe statics for Windows XP and Windows Server 2003 compatibility") SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /Zc:threadSafeInit-") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Zc:threadSafeInit-") ENDIF() @@ -157,23 +176,35 @@ IF(NOT CMAKE_SIZEOF_VOID_P) ENDIF() ENDIF(NOT CMAKE_SIZEOF_VOID_P) +# MSVC needs a flag to automatically NULL-terminate strings in string tables. +# (It ignores the "\0" in string tables, too.) +SET(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /n") + # TODO: Code coverage checking for MSVC? IF(ENABLE_COVERAGE) MESSAGE(FATAL_ERROR "Code coverage testing is currently only supported on gcc and clang.") ENDIF(ENABLE_COVERAGE) -# Debug/release flags. -SET(RP_C_FLAGS_DEBUG "/Zi") -SET(RP_CXX_FLAGS_DEBUG "/Zi") -SET(RP_EXE_LINKER_FLAGS_DEBUG "/DEBUG /INCREMENTAL") +### Debug/Release flags ### + +SET(RP_C_FLAGS_DEBUG "/Zi ${RP_C_FLAGS_DEBUG}") +SET(RP_CXX_FLAGS_DEBUG "/Zi ${RP_CXX_FLAGS_DEBUG}") +SET(RP_EXE_LINKER_FLAGS_DEBUG "/DEBUG /INCREMENTAL") SET(RP_SHARED_LINKER_FLAGS_DEBUG "${RP_EXE_LINKER_FLAGS_DEBUG}") SET(RP_MODULE_LINKER_FLAGS_DEBUG "${RP_EXE_LINKER_FLAGS_DEBUG}") + SET(RP_C_FLAGS_RELEASE "/Zi") SET(RP_CXX_FLAGS_RELEASE "/Zi") SET(RP_EXE_LINKER_FLAGS_RELEASE "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF") SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}") SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}") +SET(RP_C_FLAGS_RELWITHDEBINFO "/Zi") +SET(RP_CXX_FLAGS_RELWITHDEBINFO "/Zi") +SET(RP_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF") +SET(RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO}") +SET(RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO}") + # Check for link-time optimization. (Release builds only.) IF(ENABLE_LTO) SET(RP_C_FLAGS_RELEASE "${RP_C_FLAGS_RELEASE} /GL") @@ -181,4 +212,10 @@ IF(ENABLE_LTO) SET(RP_EXE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE} /LTCG") SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_SHARED_LINKER_FLAGS_RELEASE} /LTCG") SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_MODULE_LINKER_FLAGS_RELEASE} /LTCG") + + SET(RP_C_FLAGS_RELWITHDEBINFO "${RP_C_FLAGS_RELWITHDEBINFO} /GL") + SET(RP_CXX_FLAGS_RELWITHDEBINFO "${RP_CXX_FLAGS_RELWITHDEBINFO} /GL") + SET(RP_EXE_LINKER_FLAGS_RELWITHDEBINFO "${RP_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + SET(RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${RP_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + SET(RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${RP_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") ENDIF(ENABLE_LTO)