Port over CMake changes from rom-properties.

- CPUInstructionSetFlags.cmake: Add more CPU architectures.

- DirInstallPaths.cmake: Set ${TARGET_CPU_ARCH} and add more
  CPU architectures.

- FindNETTLE.cmake: Use ${TARGET_CPU_ARCH}.

- SplitDebugInformation.cmake: Add the `mold` workaround.

- options.cmake: Disable split debug by default on macOS.

- platform.cmake: Minor cleanups.

- gcc.cmake: Code coverage cleanup, check for "--no-undefined" and
  "--no-allow-shlib-undefined" (but only allow them on Linux),
  and check for "-ftree-vectorize".

- msvc.cmake:
  - Add: /we4477 /MP /guard:cf /guard:ehcont /permissive-
  - On i386 only: /SAFESEH
  - Disable /Zc:externC /Zc:noexceptTypes on Clang.
  - Disable thread-safe statics only on i386 and amd64.

- win32-gcc.cmake, win32-msvc.cmake:
  - Various flag changes.
This commit is contained in:
David Korth 2023-11-25 10:09:48 -05:00
parent 6b49dfaa0f
commit 43372103cb
10 changed files with 226 additions and 80 deletions

View File

@ -37,17 +37,17 @@ ELSE(NOT WIN32)
SET(NETTLE_WIN32_BASE_PATH "${CMAKE_SOURCE_DIR}/extlib/nettle.win32")
SET(NETTLE_INCLUDE_DIRS "${NETTLE_WIN32_BASE_PATH}/include")
IF(MSVC)
SET(NETTLE_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libnettle-8.lib")
SET(HOGWEED_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libhogweed-6.lib")
SET(NETTLE_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libnettle-8.lib")
SET(HOGWEED_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libhogweed-6.lib")
ELSE(MSVC)
SET(NETTLE_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libnettle.dll.a")
SET(HOGWEED_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libhogweed.dll.a")
SET(NETTLE_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libnettle.dll.a")
SET(HOGWEED_LIBRARY "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libhogweed.dll.a")
ENDIF(MSVC)
SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY} ${HOGWEED_LIBRARY})
# Copy and install the DLLs.
SET(NETTLE_NETTLE_DLL "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libnettle-8.dll")
SET(NETTLE_HOGWEED_DLL "${NETTLE_WIN32_BASE_PATH}/lib.${arch}/libhogweed-6.dll")
SET(NETTLE_NETTLE_DLL "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libnettle-8.dll")
SET(NETTLE_HOGWEED_DLL "${NETTLE_WIN32_BASE_PATH}/lib.${TARGET_CPU_ARCH}/libhogweed-6.dll")
# Destination directory.
# If CMAKE_CFG_INTDIR is set, a Debug or Release subdirectory is being used.

View File

@ -1,5 +1,3 @@
# x86 instruction set flags.
# Determine CPU architecture.
IF(MSVC AND _MSVC_C_ARCHITECTURE_FAMILY)
# Check the MSVC architecture.
@ -18,10 +16,16 @@ IF(MSVC AND _MSVC_C_ARCHITECTURE_FAMILY)
SET(CPU_ia64 1)
SET(CMAKE_SYSTEM_PROCESSOR "IA64")
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ia64")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARMV7")
SET(CPU_arm 1)
SET(CMAKE_SYSTEM_PROCESSOR "ARM")
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "arm")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64EC")
SET(CPU_arm64 1)
SET(CPU_arm64ec 1)
SET(CMAKE_SYSTEM_PROCESSOR "ARM64")
# TODO: Does this change for ARM64EC?
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "arm64")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64")
SET(CPU_arm64 1)
SET(CMAKE_SYSTEM_PROCESSOR "ARM64")
@ -44,7 +48,7 @@ ELSE()
ELSEIF(arch STREQUAL "ia64")
SET(CPU_ia64 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ia64")
ELSEIF(arch MATCHES "^arm(|v[1-7](.|h[fl]|hfe[lb]))?$" OR arch STREQUAL "aarch64")
ELSEIF(arch MATCHES "^arm(|v[1-7](.|h[fl]|hfe[lb]))?$" OR arch STREQUAL "aarch64" OR arch STREQUAL "arm64" OR arch STREQUAL "cortex")
IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
SET(CPU_arm64 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "arm64")
@ -52,14 +56,28 @@ ELSE()
SET(CPU_arm 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "arm")
ENDIF()
ELSEIF(arch MATCHES "^ppc")
IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
ELSEIF(arch MATCHES "^ppc" OR arch STREQUAL "powerpc")
IF(arch STREQUAL "ppc64le")
SET(CPU_ppc64le 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ppc64le")
ELSEIF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
SET(CPU_arm64 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ppc64")
ELSE()
SET(CPU_arm 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ppc")
ENDIF()
ELSEIF(arch MATCHES "^riscv")
# TODO: Win32 manifest processor architecture, if it's ever ported to RISC-V.
IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
SET(CPU_riscv64 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "riscv64")
ELSE()
SET(CPU_riscv32 1)
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "riscv32")
ENDIF()
ELSE()
MESSAGE(FATAL_ERROR "Unable to determine CPU architecture.\nCMAKE_SYSTEM_PROCESSOR == ${CMAKE_SYSTEM_PROCESSOR}")
ENDIF()
UNSET(arch)
ENDIF()
@ -74,10 +92,10 @@ IF(CPU_i386 OR CPU_amd64)
SET(SSSE3_FLAG "/arch:SSE2")
SET(SSE41_FLAG "/arch:SSE2")
ENDIF(CPU_i386)
IF(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
SET(SSSE3_FLAG "-mssse3")
SET(SSE41_FLAG "-msse4.1")
ENDIF(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
ENDIF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
ELSE()
IF(CPU_i386)
SET(MMX_FLAG "-mmmx")

View File

@ -7,6 +7,8 @@
# be in the root of the Windows ZIP file. On other platforms,
# it's the same as DIR_INSTALL_DOC.
# TARGET_CPU_ARCH is set to indicate the target CPU architecture.
IF(NOT PACKAGE_NAME)
MESSAGE(FATAL_ERROR "PACKAGE_NAME is not set.")
ENDIF(NOT PACKAGE_NAME)
@ -21,15 +23,24 @@ ELSEIF(CPU_ia64)
SET(arch "ia64")
ELSEIF(CPU_arm)
SET(arch "arm")
ELSEIF(CPU_arm64ec)
SET(arch "arm64ec")
ELSEIF(CPU_arm64)
SET(arch "arm64")
ELSEIF(CPU_ppc)
SET(arch "ppc")
ELSEIF(CPU_ppc64)
SET(arch "ppc64")
ELSEIF(CPU_ppc64le)
SET(arch "ppc64le")
ELSEIF(CPU_riscv32)
SET(arch "riscv32")
ELSEIF(CPU_riscv64)
SET(arch "riscv64")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported CPU architecture, please fix!")
ENDIF()
SET(TARGET_CPU_ARCH "${arch}")
INCLUDE(GNUInstallDirs)
IF(UNIX AND NOT APPLE)
@ -87,3 +98,4 @@ ELSEIF(WIN32)
ELSE()
MESSAGE(WARNING "Installation paths have not been set up for this system.")
ENDIF()
UNSET(arch)

View File

@ -82,12 +82,14 @@ IF(SPLIT_OK)
# - .strtab: String table.
# These sections are split into the .debug file, so there's
# no reason to keep them in the executable.
# NOTE 2: `mold-2.2.0` adds a bogus .gnu_debuglink section.
# Make sure we explicitly remove it with `strip`.
ADD_CUSTOM_COMMAND(TARGET ${_target} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug ${OBJCOPY_COMPRESS_DEBUG_SECTIONS_PARAM}
${SPLITDEBUG_SOURCE} ${SPLITDEBUG_TARGET}
COMMAND ${CMAKE_STRIP}
${SPLITDEBUG_SOURCE}
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink="${SPLITDEBUG_TARGET}"
COMMAND ${CMAKE_OBJCOPY}
--remove-section=.gnu_debuglink
--add-gnu-debuglink="${SPLITDEBUG_TARGET}"
${SPLITDEBUG_SOURCE}
)

View File

@ -24,7 +24,13 @@ ENDIF()
OPTION(ENABLE_LTO "Enable link-time optimization in release builds." ${LTO_DEFAULT})
# Split debug information into a separate file.
OPTION(SPLIT_DEBUG "Split debug information into a separate file." ON)
# FIXME: macOS `strip` shows an error:
# error: symbols referenced by indirect symbol table entries that can't be stripped in: [library]
IF(APPLE)
OPTION(SPLIT_DEBUG "Split debug information into a separate file." OFF)
ELSE(APPLE)
OPTION(SPLIT_DEBUG "Split debug information into a separate file." ON)
ENDIF(APPLE)
# Install the split debug file.
OPTION(INSTALL_DEBUG "Install the split debug files." ON)

View File

@ -164,7 +164,6 @@ IF(WIN32)
SET(SETARGV_FLAG "setargv.obj")
ENDIF()
ENDIF(_setargv)
UNSET(UNICODE_FLAG)
ELSE(MSVC)
# MinGW does not automatically prepend an underscore.
# TODO: _setargv for MinGW.
@ -182,7 +181,6 @@ IF(WIN32)
SET(ENTRY_POINT "${_entrypoint}CRTStartup")
ENDIF(CPU_i386)
SET(ENTRY_POINT_FLAG "-Wl,-e,${ENTRY_POINT}")
UNSET(SETARGV_FLAG)
ENDIF(MSVC)
GET_TARGET_PROPERTY(TARGET_LINK_FLAGS ${_target} LINK_FLAGS)
@ -192,5 +190,8 @@ IF(WIN32)
SET(TARGET_LINK_FLAGS "${UNICODE_FLAG} ${ENTRY_POINT_FLAG} ${SETARGV_FLAG}")
ENDIF()
SET_TARGET_PROPERTIES(${_target} PROPERTIES LINK_FLAGS "${TARGET_LINK_FLAGS}")
UNSET(UNICODE_FLAG)
UNSET(ENTRY_POINT_FLAG)
UNSET(SETARGV_FLAG)
ENDIF(WIN32)
ENDFUNCTION()

View File

@ -20,6 +20,10 @@ ENDIF()
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCXXCompilerFlag)
SET(RP_C_FLAGS_COMMON "")
SET(RP_CXX_FLAGS_COMMON "")
SET(RP_EXE_LINKER_FLAGS_COMMON "")
# _GNU_SOURCE is needed for memmem() and statx().
ADD_DEFINITIONS(-D_GNU_SOURCE=1)
@ -88,15 +92,7 @@ IF(ENABLE_COVERAGE)
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}")
# Link gcov to all targets.
SET(GCOV_LIBRARY "gcov")
FOREACH(VAR "" C_ CXX_)
IF(CMAKE_${VAR}STANDARD_LIBRARIES)
SET(CMAKE_${VAR}STANDARD_LIBRARIES "${CMAKE_${VAR}STANDARD_LIBRARIES} ${GCOV_LIBRARY}")
ELSE(CMAKE_${VAR}STANDARD_LIBRARIES)
SET(CMAKE_${VAR}STANDARD_LIBRARIES "${GCOV_LIBRARY}")
ENDIF(CMAKE_${VAR}STANDARD_LIBRARIES)
ENDFOREACH(VAR)
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_COVERAGE}")
# Create a code coverage target.
FOREACH(_program gcov lcov genhtml)
@ -121,7 +117,7 @@ EXECUTE_PROCESS(COMMAND ${CMAKE_LINKER} --help
OUTPUT_VARIABLE _ld_out
ERROR_QUIET)
FOREACH(FLAG_TEST "--sort-common" "--as-needed" "--build-id" "-Bsymbolic-functions")
FOREACH(FLAG_TEST "--sort-common" "--as-needed" "--build-id" "-Bsymbolic-functions" "--no-undefined" "--no-allow-shlib-undefined")
IF(NOT DEFINED LDFLAG_${FLAG_TEST})
MESSAGE(STATUS "Checking if ld supports ${FLAG_TEST}")
IF(_ld_out MATCHES "${FLAG_TEST}")
@ -237,7 +233,18 @@ ENDIF(UNIX AND NOT APPLE)
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
# Check for -Og.
# Special case: On non-Linux systems, remove "--no-undefined" and
# "--no-allow-shlib-undefined" from SHARED and MODULE linker flags.
# On FreeBSD 13.2, `environ` and `__progname` are intentionally undefined,
# so this *always* fails when building a shared library.
IF(NOT CMAKE_SYSTEM MATCHES "Linux")
FOREACH(FLAG_REMOVE "--no-undefined" "--no-allow-shlib-undefined")
STRING(REPLACE "-Wl,${FLAG_REMOVE}" "" RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON}")
STRING(REPLACE "-Wl,${FLAG_REMOVE}" "" RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON}")
ENDFOREACH(FLAG_REMOVE)
ENDIF(NOT CMAKE_SYSTEM MATCHES "Linux")
# Debug builds: Check for -Og.
# This flag was added in gcc-4.8, and enables optimizations that
# don't interfere with debugging.
CHECK_C_COMPILER_FLAG("-Og" CFLAG_OPTIMIZE_DEBUG)
@ -247,11 +254,27 @@ ELSE(CFLAG_OPTIMIZE_DEBUG)
SET(CFLAG_OPTIMIZE_DEBUG "-O0")
ENDIF(CFLAG_OPTIMIZE_DEBUG)
# Release builds: Check for -ftree-vectorize.
# On i386, also add -mstackrealign to ensure proper stack alignment.
CHECK_C_COMPILER_FLAG("-ftree-vectorize" CFLAG_OPTIMIZE_FTREE_VECTORIZE)
IF(CFLAG_OPTIMIZE_FTREE_VECTORIZE)
IF(arch MATCHES "^(i.|x)86$" AND NOT CMAKE_CL_64 AND ("${CMAKE_SIZEOF_VOID_P}" EQUAL 4))
# i386: "-mstackrealign" is required.
CHECK_C_COMPILER_FLAG("-mstackrealign" CFLAG_OPTIMIZE_MSTACKREALIGN)
IF(CFLAG_OPTIMIZE_MSTACK_REALIGN)
SET(CFLAGS_VECTORIZE "-ftree-vectorize -mstackrealign")
ENDIF(CFLAG_OPTIMIZE_MSTACKREALIGN)
ELSE()
# Not i386. Add "-ftree-vectorize" without "-mstackrealign".
SET(CFLAGS_VECTORIZE "-ftree-vectorize")
ENDIF()
ENDIF(CFLAG_OPTIMIZE_FTREE_VECTORIZE)
# 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")
SET(RP_CXX_FLAGS_RELEASE "-O2 -ggdb -DNDEBUG")
SET(RP_C_FLAGS_RELEASE "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}")
SET(RP_CXX_FLAGS_RELEASE "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}")
# Unset temporary variables.
UNSET(CFLAG_OPTIMIZE_DEBUG)

View File

@ -13,7 +13,8 @@ ENDIF()
# probably cause a linker error.
# - C4024: 'function': different types for formal and actual parameter n
# - C4047: 'function': 'parameter' differs in levels of indirection from 'argument'
SET(RP_C_FLAGS_COMMON "/nologo /wd4355 /wd4482 /we4013 /we4024 /we4047")
# - 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)
# NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003)
@ -22,16 +23,20 @@ SET(RP_EXE_LINKER_FLAGS_COMMON "/NOLOGO /DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWAR
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
# Enable /EHsc if it isn't enabled already.
# Add /EHsc if it isn't present already.
# Default in most cases; not enabled for MSVC 2019 on ARM or ARM64.
IF(NOT CMAKE_CXX_FLAGS MATCHES "/EHsc")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /EHsc")
ENDIF(NOT CMAKE_CXX_FLAGS MATCHES "/EHsc")
# Add /MP for multi-processor compilation.
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /MP")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /MP")
# Test for MSVC-specific compiler flags.
# /utf-8 was added in MSVC 2015.
INCLUDE(CheckCCompilerFlag)
FOREACH(FLAG_TEST "/sdl" "/guard:cf" "/utf-8")
FOREACH(FLAG_TEST "/sdl" "/utf-8" "/guard:cf" "/guard:ehcont")
# CMake doesn't like certain characters in variable names.
STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
@ -39,23 +44,35 @@ FOREACH(FLAG_TEST "/sdl" "/guard:cf" "/utf-8")
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")
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(CFLAG_${FLAG_TEST_VARNAME})
UNSET(CFLAG_${FLAG_TEST_VARNAME})
ENDFOREACH()
# "/guard:cf" must be added to linker flags in addition to CFLAGS.
CHECK_C_COMPILER_FLAG("/guard:cf" CFLAG__guard_cf)
IF(CFLAG_guard_cf)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /guard:cf")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /guard:cf")
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} /guard:cf")
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} /guard:cf")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} /guard:cf")
ENDIF(CFLAG_guard_cf)
UNSET(CFLAG_guard_cf)
# Enable /SAFESEH. (i386 only)
IF(_MSVC_C_ARCHITECTURE_FAMILY MATCHES "^([iI]?[xX3]86)$")
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} /SAFESEH")
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} /SAFESEH")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} /SAFESEH")
ENDIF()
# MSVC 2019: Enable /CETCOMPAT.
# NOTE: i386/amd64 only. (last checked in MSVC 2022 [17.0])
# - LINK : fatal error LNK1246: '/CETCOMPAT' not compatible with 'ARM' target machine; link without '/CETCOMPAT'
# - LINK : fatal error LNK1246: '/CETCOMPAT' not compatible with 'ARM64' target machine; link without '/CETCOMPAT'
IF(MSVC_VERSION GREATER 1919 AND _MSVC_C_ARCHITECTURE_FAMILY MATCHES "^([iI]?[xX3]86)|([xX]64)$")
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} /CETCOMPAT")
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} /CETCOMPAT")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} /CETCOMPAT")
ENDIF()
# MSVC: C/C++ conformance settings
FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline")
FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline" "/permissive-")
# CMake doesn't like certain characters in variable names.
STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
@ -69,7 +86,11 @@ ENDFOREACH()
# MSVC: C++ conformance settings
INCLUDE(CheckCXXCompilerFlag)
FOREACH(FLAG_TEST "/Zc:__cplusplus" "/Zc:externC" "/Zc:noexceptTypes" "/Zc:rvalueCast" "/Zc:ternary")
SET(CXX_CONFORMANCE_FLAGS "/Zc:__cplusplus" "/Zc:rvalueCast" "/Zc:ternary")
IF(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
SET(CXX_CONFORMANCE_FLAGS "/Zc:externC" "/Zc:noexceptTypes")
ENDIF(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
FOREACH(FLAG_TEST ${CXX_CONFORMANCE_FLAGS})
# CMake doesn't like certain characters in variable names.
STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
@ -85,11 +106,11 @@ ENDFOREACH()
# 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)
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(CXXFLAG__Zc_throwingNew)
UNSET(CXXFLAG__Zc_throwingNew)
ENDIF(NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang)
# Disable warning C4996 (deprecated), then re-enable it.
@ -98,8 +119,11 @@ SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4996 /w34996")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /wd4996 /w34996")
# MSVC 2015 uses thread-safe statics by default.
# This doesn't work on XP, so disable it.
IF(MSVC_VERSION GREATER 1899)
# This doesn't work on Windows XP or Windows Server 2003, so disable it.
# 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")
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /Zc:threadSafeInit-")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Zc:threadSafeInit-")
ENDIF()

View File

@ -2,7 +2,7 @@
# For MinGW compilers.
# Enable "secure" API functions: *_s()
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DMINGW_HAS_SECURE_API")
ADD_DEFINITIONS(-DMINGW_HAS_SECURE_API)
# Subsystem and minimum Windows version:
# - If i386: 5.01
@ -43,32 +43,92 @@ IF(CMAKE_BUILD_TYPE MATCHES ^release)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(CMAKE_BUILD_TYPE MATCHES ^release)
# Test for various linker flags.
# Test for common LDFLAGS.
# NOTE: CHECK_C_COMPILER_FLAG() doesn't seem to work, even with
# CMAKE_TRY_COMPILE_TARGET_TYPE. Check `ld --help` for the various
# parameters instead.
# NOTE: --tsaware is only valid for EXEs, not DLLs.
# TODO: Make static linkage a CMake option: --static-libgcc, --static-libstdc++
FOREACH(FLAG_TEST "-Wl,--large-address-aware" "-Wl,--nxcompat" "-Wl,--tsaware")
# CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
EXECUTE_PROCESS(COMMAND ${CMAKE_LINKER} --help
OUTPUT_VARIABLE _ld_out
ERROR_QUIET)
IF(LDFLAG_${FLAG_TEST_VARNAME})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} ${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(FLAG_TEST_VARNAME)
# NOTE: Newer ld shows things like "--[disable-]dynamicbase".
IF(CPU_i386 OR CPU_arm)
# 32-bit only LDFLAGS
FOREACH(FLAG_TEST "large-address-aware")
IF(NOT DEFINED LDFLAG_${FLAG_TEST})
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST}")
IF(_ld_out MATCHES "${FLAG_TEST}")
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - yes")
SET(LDFLAG_${FLAG_TEST} 1 CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ELSE()
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - no")
SET(LDFLAG_${FLAG_TEST} "" CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ENDIF()
ENDIF()
IF(LDFLAG_${FLAG_TEST})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} -Wl,--${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST})
ENDFOREACH()
ELSEIF(CPU_amd64 OR CPU_arm64)
# 64-bit only LDFLAGS
FOREACH(FLAG_TEST "high-entropy-va")
IF(NOT DEFINED LDFLAG_${FLAG_TEST})
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST}")
IF(_ld_out MATCHES "${FLAG_TEST}")
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - yes")
SET(LDFLAG_${FLAG_TEST} 1 CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ELSE()
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - no")
SET(LDFLAG_${FLAG_TEST} "" CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ENDIF()
ENDIF()
IF(LDFLAG_${FLAG_TEST})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} -Wl,--${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST})
ENDFOREACH()
ENDIF()
# CPU-independent LDFLAGS
FOREACH(FLAG_TEST "dynamicbase" "nxcompat")
IF(NOT DEFINED LDFLAG_${FLAG_TEST})
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST}")
IF(_ld_out MATCHES "${FLAG_TEST}")
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - yes")
SET(LDFLAG_${FLAG_TEST} 1 CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ELSE()
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - no")
SET(LDFLAG_${FLAG_TEST} "" CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ENDIF()
ENDIF()
IF(LDFLAG_${FLAG_TEST})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} -Wl,--${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST})
ENDFOREACH()
SET(RP_SHARED_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32}")
SET(RP_MODULE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32}")
# EXE-only flags.
FOREACH(FLAG_TEST "-Wl,--tsaware")
# CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
FOREACH(FLAG_TEST "tsaware")
IF(NOT DEFINED LDFLAG_${FLAG_TEST})
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST}")
IF(_ld_out MATCHES "${FLAG_TEST}")
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - yes")
SET(LDFLAG_${FLAG_TEST} 1 CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ELSE()
MESSAGE(STATUS "Checking if ld supports --${FLAG_TEST} - no")
SET(LDFLAG_${FLAG_TEST} "" CACHE INTERNAL "Linker supports --${FLAG_TEST}")
ENDIF()
ENDIF()
IF(LDFLAG_${FLAG_TEST_VARNAME})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} ${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(FLAG_TEST_VARNAME)
IF(LDFLAG_${FLAG_TEST})
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} -Wl,--${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST})
ENDFOREACH()
# Test for dynamicbase (ASLR) support.

View File

@ -4,24 +4,24 @@
# - Enable strict type checking in the Windows headers.
# - Define WIN32_LEAN_AND_MEAN to reduce the number of Windows headers included.
# - Define NOMINMAX to disable the MIN() and MAX() macros.
SET(RP_C_FLAGS_WIN32 "-DSTRICT -DWIN32_LEAN_AND_MEAN -DNOMINMAX")
ADD_DEFINITIONS(-DSTRICT -DWIN32_LEAN_AND_MEAN -DNOMINMAX)
# NOTE: This program only supports Unicode on Windows.
# No support for ANSI Windows, i.e. Win9x.
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DUNICODE -D_UNICODE")
ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
# Minimum Windows version for the SDK is Windows XP.
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0600")
ADD_DEFINITIONS(-DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0600)
# Enable secure template overloads for C++.
# References:
# - MinGW's _mingw_secapi.h
# - http://msdn.microsoft.com/en-us/library/ms175759%28v=VS.100%29.aspx
SET(RP_CXX_FLAGS_WIN32 "-D_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES=1")
SET(RP_CXX_FLAGS_WIN32 "${RP_CXX_FLAGS_WIN32} -D_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY=1")
SET(RP_CXX_FLAGS_WIN32 "${RP_CXX_FLAGS_WIN32} -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
SET(RP_CXX_FLAGS_WIN32 "${RP_CXX_FLAGS_WIN32} -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
SET(RP_CXX_FLAGS_WIN32 "${RP_CXX_FLAGS_WIN32} -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY=1")
ADD_DEFINITIONS(-D_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES=1)
ADD_DEFINITIONS(-D_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY=1)
ADD_DEFINITIONS(-D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1)
ADD_DEFINITIONS(-D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1)
ADD_DEFINITIONS(-D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY=1)
# Compiler-specific Win32 flags.
IF(MSVC)