Copied various CMake module updates from rom-properties.

- Changed several macros to functions, e.g. C/C++ language version checks.
- Improved CPU architecture detection.
- Improved LFS detection on some *BSD platforms.
- Preliminary support for Windows on ARM.
- Added toolchain files for i686 and x86_64 MinGW-w64.
This commit is contained in:
David Korth 2020-06-20 14:01:52 -04:00
parent 556ced2327
commit 6ca6180f43
10 changed files with 280 additions and 183 deletions

View File

@ -16,82 +16,80 @@
INCLUDE(CheckCSourceCompiles) INCLUDE(CheckCSourceCompiles)
MACRO(CHECK_C11_C99_COMPILER_FLAG _RESULT) FUNCTION(CHECK_C11_C99_COMPILER_FLAG _result)
# Flag listing borrowed from GNU autoconf's AC_PROG_CC_C99 macro. # Flag listing borrowed from GNU autoconf's AC_PROG_CC_C99 macro.
UNSET(${_RESULT}) UNSET(${_result} PARENT_SCOPE)
# MSVC doesn't allow setting the C standard. # MSVC doesn't allow setting the C standard.
IF(NOT MSVC) IF(NOT DEFINED _SYS_C11_C99_CFLAG AND NOT MSVC)
# Check if C11 is present without any flags. # Check if C11 is present without any flags.
# gcc-5.1 uses C11 mode by default. # gcc-5.1 uses C11 mode by default.
MESSAGE(STATUS "Checking if C11 is enabled by default:") MESSAGE(STATUS "Checking if C11 is enabled by default:")
CHECK_C_SOURCE_COMPILES(" CHECK_C_SOURCE_COMPILES("
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
#error C11 is not enabled # error C11 is not enabled
#endif #endif
int main() { return 0; }" CHECK_C11_ENABLED_DEFAULT) int main() { return 0; }" CHECK_C11_ENABLED_DEFAULT)
IF (${CHECK_C11_ENABLED_DEFAULT}) IF (CHECK_C11_ENABLED_DEFAULT)
UNSET(${_RESULT}) SET(_SYS_C11_C99_CFLAG "" CACHE INTERNAL "CFLAG required for C11 or C99 mode.")
MESSAGE(STATUS "Checking if C11 is enabled by default: yes") MESSAGE(STATUS "Checking if C11 is enabled by default: yes")
ELSE() ELSE(CHECK_C11_ENABLED_DEFAULT)
MESSAGE(STATUS "Checking if C11 is enabled by default: no") MESSAGE(STATUS "Checking if C11 is enabled by default: no")
MESSAGE(STATUS "Checking what CFLAG is required for C11:") MESSAGE(STATUS "Checking what CFLAG is required for C11:")
FOREACH(CHECK_C11_CFLAG "-std=gnu11" "-std=c11" "-c99" "-AC99" "-xc99=all" "-qlanglvl=extc1x" "-qlanglvl=stdc11") FOREACH(CHECK_C11_CFLAG "-std=gnu11" "-std=c11" "-c99" "-AC99" "-xc99=all" "-qlanglvl=extc1x" "-qlanglvl=stdc11")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_C11_CFLAG}")
CHECK_C_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_C11_CFLAG})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(CFLAG_${CHECK_C11_CFLAG})
SET(${_RESULT} ${CHECK_C11_CFLAG})
BREAK()
ENDIF(CFLAG_${CHECK_C11_CFLAG})
UNSET(CFLAG_${CHECK_C11_CFLAG})
ENDFOREACH()
IF(${_RESULT})
MESSAGE(STATUS "Checking what CFLAG is required for C11: ${${_RESULT}}")
ELSE(${_RESULT})
MESSAGE(STATUS "Checking what CFLAG is required for C11: unavailable")
ENDIF(${_RESULT})
ENDIF()
IF(NOT CHECK_C11_ENABLED_DEFAULT AND NOT ${_RESULT})
# Could not enable C11. Try C99 instead.
MESSAGE(STATUS "Checking if C99 is enabled by default:")
CHECK_C_SOURCE_COMPILES("
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
#error C99 is not enabled
#endif
int main() { return 0; }" CHECK_C99_ENABLED_DEFAULT)
IF (${CHECK_C99_ENABLED_DEFAULT})
UNSET(${_RESULT})
MESSAGE(STATUS "Checking if C99 is enabled by default: yes")
ELSE()
MESSAGE(STATUS "Checking if C99 is enabled by default: no")
MESSAGE(STATUS "Checking what CFLAG is required for C99:")
FOREACH(CHECK_C99_CFLAG "-std=gnu99" "-std=c99" "-c99" "-AC99" "-xc99=all" "-qlanglvl=extc99")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_C99_CFLAG}") SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_C11_CFLAG}")
CHECK_C_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_C99_CFLAG}) CHECK_C_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_C11_CFLAG})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(CFLAG_${CHECK_C99_CFLAG}) IF(CFLAG_${CHECK_C11_CFLAG})
SET(${_RESULT} ${CHECK_C99_CFLAG}) SET(_SYS_C11_C99_CFLAG "${CHECK_C11_CFLAG}" CACHE INTERNAL "CFLAG required for C11 or C99 mode.")
BREAK() BREAK()
ENDIF(CFLAG_${CHECK_C99_CFLAG}) ENDIF(CFLAG_${CHECK_C11_CFLAG})
UNSET(CFLAG_${CHECK_C99_CFLAG})
ENDFOREACH() ENDFOREACH()
IF(${_RESULT}) IF(_SYS_C11_C99_CFLAG)
MESSAGE(STATUS "Checking what CFLAG is required for C99: ${${_RESULT}}") MESSAGE(STATUS "Checking what CFLAG is required for C11: ${_SYS_C11_C99_CFLAG}")
ELSE(${_RESULT}) ELSE(_SYS_C11_C99_CFLAG)
MESSAGE(STATUS "Checking what CFLAG is required for C99: unavailable") MESSAGE(STATUS "Checking what CFLAG is required for C11: unavailable")
ENDIF(${_RESULT}) ENDIF(_SYS_C11_C99_CFLAG)
ENDIF() ENDIF(CHECK_C11_ENABLED_DEFAULT)
ENDIF(NOT CHECK_C11_ENABLED_DEFAULT AND NOT ${_RESULT})
UNSET(CHECK_C11_ENABLED_DEFAULT) IF(NOT CHECK_C11_ENABLED_DEFAULT AND NOT _SYS_C11_C99_CFLAG)
UNSET(CHECK_C99_ENABLED_DEFAULT) # Could not enable C11. Try C99 instead.
ENDIF(NOT MSVC) MESSAGE(STATUS "Checking if C99 is enabled by default:")
ENDMACRO(CHECK_C11_C99_COMPILER_FLAG) CHECK_C_SOURCE_COMPILES("
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
# error C99 is not enabled
#endif
int main() { return 0; }" CHECK_C99_ENABLED_DEFAULT)
IF (CHECK_C99_ENABLED_DEFAULT)
SET(_SYS_C11_C99_CFLAG "" CACHE INTERNAL "CFLAG required for C11 or C99 mode.")
MESSAGE(STATUS "Checking if C99 is enabled by default: yes")
ELSE(CHECK_C99_ENABLED_DEFAULT)
MESSAGE(STATUS "Checking if C99 is enabled by default: no")
MESSAGE(STATUS "Checking what CFLAG is required for C99:")
FOREACH(CHECK_C99_CFLAG "-std=gnu99" "-std=c99" "-c99" "-AC99" "-xc99=all" "-qlanglvl=extc99")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_C99_CFLAG}")
CHECK_C_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_C99_CFLAG})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(CFLAG_${CHECK_C99_CFLAG})
SET(_SYS_C11_C99_CFLAG "${CHECK_C99_CFLAG}" CACHE INTERNAL "CFLAG required for C11 or C99 mode.")
BREAK()
ENDIF(CFLAG_${CHECK_C99_CFLAG})
ENDFOREACH()
IF(_SYS_C11_C99_CFLAG)
MESSAGE(STATUS "Checking what CFLAG is required for C99: ${_SYS_C11_C99_CFLAG}")
ELSE(_SYS_C11_C99_CFLAG)
SET(${_SYS_C11_C99_CFLAG} "" CACHE INTERNAL "CFLAG required for C11 or C99 mode.")
MESSAGE(STATUS "Checking what CFLAG is required for C99: unavailable")
ENDIF(_SYS_C11_C99_CFLAG)
ENDIF(CHECK_C99_ENABLED_DEFAULT)
ENDIF(NOT CHECK_C11_ENABLED_DEFAULT AND NOT _SYS_C11_C99_CFLAG)
ENDIF(NOT DEFINED _SYS_C11_C99_CFLAG AND NOT MSVC)
SET(${_result} "${_SYS_C11_C99_CFLAG}" PARENT_SCOPE)
ENDFUNCTION(CHECK_C11_C99_COMPILER_FLAG)

View File

@ -17,51 +17,49 @@
INCLUDE(CheckCXXSourceCompiles) INCLUDE(CheckCXXSourceCompiles)
MACRO(CHECK_CXX11_COMPILER_FLAG _RESULT) FUNCTION(CHECK_CXX11_COMPILER_FLAG _result)
UNSET(${_RESULT}) UNSET(${_result} PARENT_SCOPE)
# MSVC doesn't allow setting the C standard. # MSVC doesn't allow setting the C standard.
IF(NOT MSVC) IF(NOT DEFINED _SYS_CXX11_CXXFLAG AND NOT MSVC)
# Check if C++ 2011 is present without any flags. # Check if C++ 2011 is present without any flags.
# g++-5.1 uses C++ 1998 by default, but this may change # g++-5.1 uses C++ 1998 by default, but this may change
# in future versions of gcc. # in future versions of gcc.
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default:") MESSAGE(STATUS "Checking if C++ 2011 is enabled by default:")
CHECK_CXX_SOURCE_COMPILES(" CHECK_CXX_SOURCE_COMPILES("
#if !defined(__cplusplus) || __cplusplus < 201103L #if !defined(__cplusplus) || __cplusplus < 201103L
#error C++ 2011 is not enabled # error C++ 2011 is not enabled
#endif #endif
int main() { return 0; }" CHECK_CXX11_ENABLED_DEFAULT) int main() { return 0; }" CHECK_CXX11_ENABLED_DEFAULT)
IF (${CHECK_CXX11_ENABLED_DEFAULT}) IF (CHECK_CXX11_ENABLED_DEFAULT)
UNSET(${_RESULT}) SET(_SYS_CXX11_CXXFLAG "" CACHE INTERNAL "CXXFLAG required for C++11 mode.")
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: yes") MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: yes")
ELSE() ELSE(CHECK_CXX11_ENABLED_DEFAULT)
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: no") MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: no")
MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011:") MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011:")
FOREACH(CHECK_CXX11_CXXFLAG "-std=gnu++11" "-std=gnu++0x" "-std=c++11" "-std=c++0x") FOREACH(CHECK_CXX11_CXXFLAG "-std=gnu++11" "-std=gnu++0x" "-std=c++11" "-std=c++0x")
# CMake doesn't like "+" characters in variable names. # CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" CHECK_CXX11_CXXFLAG_VARNAME "CHECK_CXXFLAG_${CHECK_CXX11_CXXFLAG}") STRING(REPLACE "+" "_" CHECK_CXX11_CXXFLAG_VARNAME "CHECK_CXXFLAG_${CHECK_CXX11_CXXFLAG}")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_CXX11_CXXFLAG}") SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_CXX11_CXXFLAG}")
CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(0 == 0, \"test assertion\"); return 0; }" ${CHECK_CXX11_CXXFLAG_VARNAME}) CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(0 == 0, \"test assertion\"); return 0; }" ${CHECK_CXX11_CXXFLAG_VARNAME})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(${${CHECK_CXX11_CXXFLAG_VARNAME}}) IF(${${CHECK_CXX11_CXXFLAG_VARNAME}})
SET(${_RESULT} ${CHECK_CXX11_CXXFLAG}) SET(_SYS_CXX11_CXXFLAG ${CHECK_CXX11_CXXFLAG} CACHE INTERNAL "CXXFLAG required for C++11 mode.")
UNSET(${CHECK_CXX11_CXXFLAG_VARNAME}) BREAK()
UNSET(CHECK_CXX11_CXXFLAG_VARNAME) ENDIF(${${CHECK_CXX11_CXXFLAG_VARNAME}})
BREAK() ENDFOREACH()
ENDIF(${${CHECK_CXX11_CXXFLAG_VARNAME}}) IF(_SYS_CXX11_CXXFLAG)
UNSET(${CHECK_CXX11_CXXFLAG_VARNAME}) MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: ${_SYS_CXX11_CXXFLAG}")
UNSET(CHECK_CXX11_CXXFLAG_VARNAME) ELSE(_SYS_CXX11_CXXFLAG)
ENDFOREACH() SET(${_SYS_CXX11_CXXFLAG} "" CACHE INTERNAL "CXXFLAG required for C++11 mode.")
IF(${_RESULT}) MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: unavailable")
MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: ${${_RESULT}}") ENDIF(_SYS_CXX11_CXXFLAG)
ELSE(${_RESULT}) ENDIF(CHECK_CXX11_ENABLED_DEFAULT)
MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: none") ENDIF(NOT DEFINED _SYS_CXX11_CXXFLAG AND NOT MSVC)
ENDIF(${_RESULT})
ENDIF() SET(${_result} "${_SYS_CXX11_CXXFLAG}" PARENT_SCOPE)
UNSET(CHECK_CXX11_ENABLED_DEFAULT) ENDFUNCTION(CHECK_CXX11_COMPILER_FLAG)
ENDIF(NOT MSVC)
ENDMACRO(CHECK_CXX11_COMPILER_FLAG)

View File

@ -18,11 +18,15 @@
# - LFS_FOUND_FSEEKI64: Set to 1 if LFS is supported using _fseeki64(). # - LFS_FOUND_FSEEKI64: Set to 1 if LFS is supported using _fseeki64().
# - LFS_DEFINITIONS: Preprocessor macros required for large file support, if any. # - LFS_DEFINITIONS: Preprocessor macros required for large file support, if any.
# Additional variables are set based on the existance of types:
# - SIZEOF_OFF_T: sizeof(off_t), if available.
# - SIZEOF_OFF64_T: sizeof(off64_t), if available.
# TODO: Use _fseeki64() and _ftelli64() on MinGW to avoid # TODO: Use _fseeki64() and _ftelli64() on MinGW to avoid
# the use of wrapper functions? # the use of wrapper functions?
FUNCTION(CHECK_LARGE_FILE_SUPPORT) FUNCTION(CHECK_LARGE_FILE_SUPPORT)
IF(NOT DEFINED LFS_FOUND) IF(NOT DEFINED LFS_FOUND OR NOT DEFINED CHECKED_OFF_T)
# NOTE: ${CMAKE_MODULE_PATH} has two directories, macros/ and libs/, # NOTE: ${CMAKE_MODULE_PATH} has two directories, macros/ and libs/,
# so we have to configure this manually. # so we have to configure this manually.
SET(LFS_SOURCE_PATH "${CMAKE_SOURCE_DIR}/cmake/macros") SET(LFS_SOURCE_PATH "${CMAKE_SOURCE_DIR}/cmake/macros")
@ -51,21 +55,18 @@ FUNCTION(CHECK_LARGE_FILE_SUPPORT)
MESSAGE(STATUS "Checking if Large File Support is available - yes") MESSAGE(STATUS "Checking if Large File Support is available - yes")
ELSE() ELSE()
# Try adding LFS macros. # Try adding LFS macros.
SET(TMP_LFS_DEFINITIONS -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64) SET(TMP_LFS_DEFINITIONS_BITS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
TRY_COMPILE(TMP_LFS_FOUND "${CMAKE_BINARY_DIR}" TRY_COMPILE(TMP_LFS_FOUND "${CMAKE_BINARY_DIR}"
"${LFS_SOURCE_PATH}/LargeFileSupport_fseeko.c" "${LFS_SOURCE_PATH}/LargeFileSupport_fseeko.c"
COMPILE_DEFINITIONS ${TMP_LFS_DEFINITIONS}) COMPILE_DEFINITIONS ${TMP_LFS_DEFINITIONS_BITS})
IF(TMP_LFS_FOUND) IF(TMP_LFS_FOUND)
# LFS macros work. # LFS macros work.
MESSAGE(STATUS "Checking if Large File Support is available - yes, using LFS macros") MESSAGE(STATUS "Checking if Large File Support is available - yes, using LFS macros")
SET(TMP_LFS_FOUND_FSEEKO 1) SET(TMP_LFS_FOUND_FSEEKO 1)
# NOTE: COMPILE_DEFINITIONS requires a semicolon-separated list; SET(TMP_LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS_BITS}")
# CFLAGS reqiures space-separated.
STRING(REPLACE ";" " " TMP_LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}")
ELSE() ELSE()
# LFS macros failed. # LFS macros failed.
MESSAGE(STATUS "Checking if Large File Support is available - no") MESSAGE(STATUS "Checking if Large File Support is available - no")
UNSET(TMP_LFS_DEFINITIONS)
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
@ -73,6 +74,23 @@ FUNCTION(CHECK_LARGE_FILE_SUPPORT)
SET(LFS_FOUND ${TMP_LFS_FOUND} CACHE INTERNAL "Is Large File Support available?") SET(LFS_FOUND ${TMP_LFS_FOUND} CACHE INTERNAL "Is Large File Support available?")
SET(LFS_FOUND_FSEEKO ${TMP_LFS_FOUND_FSEEKO} CACHE INTERNAL "Large File Support is available using LFS macros") SET(LFS_FOUND_FSEEKO ${TMP_LFS_FOUND_FSEEKO} CACHE INTERNAL "Large File Support is available using LFS macros")
SET(LFS_FOUND_FSEEKI64 ${TMP_LFS_FOUND_FSEEKI64} CACHE INTERNAL "Large File Support is available using MSVC non-standard functions") SET(LFS_FOUND_FSEEKI64 ${TMP_LFS_FOUND_FSEEKI64} CACHE INTERNAL "Large File Support is available using MSVC non-standard functions")
# Check for off_t and off64_t.
INCLUDE(CheckTypeSize)
SET(CMAKE_REQUIRED_INCLUDES "unistd.h")
SET(CMAKE_REQUIRED_DEFINITIONS ${TMP_LFS_DEFINITIONS})
CHECK_TYPE_SIZE("off_t" OFF_T)
# off64_t requires -D_LARGEFILE64_SOURCE.
SET(CMAKE_REQUIRED_DEFINITIONS "${TMP_LFS_DEFINITIONS};-D_LARGEFILE64_SOURCE")
CHECK_TYPE_SIZE("off64_t" OFF64_T)
IF(HAVE_OFF64_T)
SET(TMP_LFS_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
ENDIF(HAVE_OFF64_T)
SET(CHECKED_OFF_T "1" CACHE INTERNAL "off_t/off64_t were checked")
# NOTE: COMPILE_DEFINITIONS requires a semicolon-separated list;
# CFLAGS reqiures space-separated.
STRING(REPLACE ";" " " TMP_LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}")
SET(LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}" CACHE INTERNAL "Definitions required for Large File Support") SET(LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}" CACHE INTERNAL "Definitions required for Large File Support")
ENDIF() ENDIF()
ENDFUNCTION(CHECK_LARGE_FILE_SUPPORT) ENDFUNCTION(CHECK_LARGE_FILE_SUPPORT)

View File

@ -17,21 +17,24 @@
INCLUDE(CheckCSourceCompiles) INCLUDE(CheckCSourceCompiles)
MACRO(CHECK_STACK_PROTECTOR_COMPILER_FLAG _RESULT) FUNCTION(CHECK_STACK_PROTECTOR_COMPILER_FLAG _result)
UNSET(${_RESULT}) UNSET(${_result} PARENT_SCOPE)
IF(NOT DEFINED _SYS_STACK_PROTECTOR_COMPILER_FLAG)
IF(MSVC) IF(MSVC)
# MSVC 2002 introduced the /GS option. # MSVC 2002 introduced the /GS option.
# MSVC 2005+ enables it by default. # MSVC 2005+ enables it by default.
IF(MSVC_VERSION GREATER 1399) IF(MSVC_VERSION GREATER 1399)
# MSVC 2005+. # MSVC 2005+.
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: none") SET(_SYS_STACK_PROTECTOR_COMPILER_FLAG "" CACHE INTERNAL "CFLAG required for stack smashing protection.")
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: none, enabled by default")
ELSEIF(MSVC_VERSION GREATER 1299) ELSEIF(MSVC_VERSION GREATER 1299)
# MSVC 2002 or 2003. # MSVC 2002 or 2003.
SET(${_RESULT} "/GS") SET(_SYS_STACK_PROTECTOR_COMPILER_FLAG "/GS" CACHE INTERNAL "CFLAG required for stack smashing protection.")
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${${_RESULT}}") MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${_SYS_STACK_PROTECTOR_COMPILER_FLAG}")
ELSE() ELSE()
# MSVC 2002 or earlier. # MSVC 2002 or earlier.
SET(_SYS_STACK_PROTECTOR_COMPILER_FLAG "" CACHE INTERNAL "CFLAG required for stack smashing protection.")
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: not available") MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: not available")
ENDIF() ENDIF()
ELSE(MSVC) ELSE(MSVC)
@ -96,21 +99,19 @@ int main(int argc, char *argv[])
SET(CMAKE_REQUIRED_LIBRARIES "${SAFE_CMAKE_REQUIRED_LIBRARIES}") SET(CMAKE_REQUIRED_LIBRARIES "${SAFE_CMAKE_REQUIRED_LIBRARIES}")
IF(${${CHECK_STACK_CFLAG_VARNAME}}) IF(${${CHECK_STACK_CFLAG_VARNAME}})
SET(${_RESULT} ${CHECK_STACK_CFLAG}) SET(_SYS_STACK_PROTECTOR_COMPILER_FLAG "${CHECK_STACK_CFLAG}" CACHE INTERNAL "CFLAG required for stack smashing protection.")
UNSET(${CHECK_STACK_CFLAG_VARNAME})
UNSET(CHECK_STACK_CFLAG_VARNAME)
BREAK() BREAK()
ENDIF(${${CHECK_STACK_CFLAG_VARNAME}}) ENDIF(${${CHECK_STACK_CFLAG_VARNAME}})
UNSET(${CHECK_STACK_CFLAG_VARNAME})
UNSET(CHECK_STACK_CFLAG_VARNAME)
UNSET(SAFE_CMAKE_REQUIRED_DEFINITIONS)
UNSET(SAFE_CMAKE_REQUIRED_LIBRARIES)
ENDFOREACH() ENDFOREACH()
IF(${_RESULT}) IF(_SYS_STACK_PROTECTOR_COMPILER_FLAG)
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${${_RESULT}}") MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${_SYS_STACK_PROTECTOR_COMPILER_FLAG}")
ELSE(${_RESULT}) ELSE(_SYS_STACK_PROTECTOR_COMPILER_FLAG)
SET(_SYS_STACK_PROTECTOR_COMPILER_FLAG "" CACHE INTERNAL "CFLAG required for stack smashing protection.")
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: not available") MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: not available")
MESSAGE(WARNING "Stack smashing protection is not available.\nPlease check your toolchain installation.") MESSAGE(WARNING "Stack smashing protection is not available.\nPlease check your toolchain installation.")
ENDIF(${_RESULT}) ENDIF(_SYS_STACK_PROTECTOR_COMPILER_FLAG)
ENDIF(MSVC) ENDIF(MSVC)
ENDMACRO(CHECK_STACK_PROTECTOR_COMPILER_FLAG) ENDIF(NOT DEFINED _SYS_STACK_PROTECTOR_COMPILER_FLAG)
SET(${_result} "${_SYS_STACK_PROTECTOR_COMPILER_FLAG}" PARENT_SCOPE)
ENDFUNCTION(CHECK_STACK_PROTECTOR_COMPILER_FLAG)

View File

@ -18,23 +18,50 @@ IF(NOT HAVE_STDINT_H)
ENDIF(NOT HAVE_STDINT_H) ENDIF(NOT HAVE_STDINT_H)
# CPU architecture. # CPU architecture.
# TODO: Verify cross-compile functionality. IF(MSVC AND _MSVC_C_ARCHITECTURE_FAMILY)
# TODO: ARM/ARM64 is untested. # Check the MSVC architecture.
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch) # Set CMAKE_SYSTEM_PROCESSOR to match, since it doesn't get
IF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$") # set to the target architecture correctly.
IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)) # TODO: Verify 32-bit.
SET(CPU_amd64 1) IF(_MSVC_C_ARCHITECTURE_FAMILY MATCHES "^[iI]?[xX3]86$")
ELSE()
SET(CPU_i386 1) SET(CPU_i386 1)
SET(CMAKE_SYSTEM_PROCESSOR "x86")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY MATCHES "^[xX]64$")
SET(CPU_amd64 1)
SET(CMAKE_SYSTEM_PROCESSOR "AMD64")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY MATCHES "[iI][aA]64")
SET(CPU_ia64 1)
SET(CMAKE_SYSTEM_PROCESSOR "IA64")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM")
SET(CPU_arm 1)
SET(CMAKE_SYSTEM_PROCESSOR "ARM")
ELSEIF(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64")
SET(CPU_arm64 1)
SET(CMAKE_SYSTEM_PROCESSOR "ARM64")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported value for _MSVC_C_ARCHITECTURE_FAMILY: ${_MSVC_C_ARCHITECTURE_FAMILY}")
ENDIF() ENDIF()
ELSEIF(arch STREQUAL "ia64") ELSE()
SET(CPU_ia64 1) # TODO: Verify cross-compile functionality.
ELSEIF(arch STREQUAL "arm") # TODO: ARM/ARM64 is untested.
SET(CPU_arm 1) STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
ELSEIF(arch STREQUAL "aarch64") IF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$")
SET(CPU_arm64 1) IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
SET(CPU_amd64 1)
ELSE()
SET(CPU_i386 1)
ENDIF()
ELSEIF(arch STREQUAL "ia64")
SET(CPU_ia64 1)
ELSEIF(arch STREQUAL "arm" OR arch STREQUAL "aarch64")
IF(CMAKE_CL_64 OR ("${CMAKE_SIZEOF_VOID_P}" EQUAL 8))
SET(CPU_arm64 1)
ELSE()
SET(CPU_arm 1)
ENDIF()
ENDIF()
UNSET(arch)
ENDIF() ENDIF()
UNSET(arch)
# Common flag variables: # Common flag variables:
# [common] # [common]
@ -186,7 +213,6 @@ IF(WIN32)
UNSET(UNICODE_FLAG) UNSET(UNICODE_FLAG)
ELSE(MSVC) ELSE(MSVC)
# MinGW does not automatically prepend an underscore. # MinGW does not automatically prepend an underscore.
# TODO: Does ARM Windows have a leading underscore?
# TODO: _setargv for MinGW. # TODO: _setargv for MinGW.
# NOTE: MinGW uses separate crt*.o files for Unicode # NOTE: MinGW uses separate crt*.o files for Unicode
@ -196,15 +222,11 @@ IF(WIN32)
STRING(SUBSTRING "${_entrypoint}" 1 -1 _entrypoint) STRING(SUBSTRING "${_entrypoint}" 1 -1 _entrypoint)
ENDIF() ENDIF()
IF(CPU_i386 OR CPU_amd64) IF(CPU_i386)
IF(CMAKE_SIZEOF_VOID_P EQUAL 4) SET(ENTRY_POINT "_${_entrypoint}CRTStartup")
SET(ENTRY_POINT "_${_entrypoint}CRTStartup") ELSE(CPU_i386)
ELSE()
SET(ENTRY_POINT "${_entrypoint}CRTStartup")
ENDIF()
ELSE()
SET(ENTRY_POINT "${_entrypoint}CRTStartup") SET(ENTRY_POINT "${_entrypoint}CRTStartup")
ENDIF(CPU_i386 OR CPU_amd64) ENDIF(CPU_i386)
SET(ENTRY_POINT_FLAG "-Wl,-e,${ENTRY_POINT}") SET(ENTRY_POINT_FLAG "-Wl,-e,${ENTRY_POINT}")
UNSET(SETARGV_FLAG) UNSET(SETARGV_FLAG)
ENDIF(MSVC) ENDIF(MSVC)

View File

@ -10,6 +10,12 @@ ELSEIF(CMAKE_COMPILER_IS_GNUCXX)
ENDIF() ENDIF()
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. # Compiler flag modules.
INCLUDE(CheckCCompilerFlag) INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCXXCompilerFlag) INCLUDE(CheckCXXCompilerFlag)
@ -22,10 +28,13 @@ CHECK_C11_C99_COMPILER_FLAG(RP_C11_CFLAG)
INCLUDE(CheckCXX11CompilerFlag) INCLUDE(CheckCXX11CompilerFlag)
CHECK_CXX11_COMPILER_FLAG(RP_CXX11_CXXFLAG) CHECK_CXX11_COMPILER_FLAG(RP_CXX11_CXXFLAG)
SET(RP_C_FLAGS_COMMON "-D_GNU_SOURCE=1 ${RP_C11_CFLAG}") SET(RP_C_FLAGS_COMMON "${RP_C11_CFLAG}")
SET(RP_CXX_FLAGS_COMMON "-D_GNU_SOURCE=1 ${RP_CXX11_CXXFLAG}") SET(RP_CXX_FLAGS_COMMON "${RP_CXX11_CXXFLAG}")
SET(RP_EXE_LINKER_FLAGS_COMMON "") SET(RP_EXE_LINKER_FLAGS_COMMON "")
# _GNU_SOURCE is needed for memmem() and statx().
ADD_DEFINITIONS(-D_GNU_SOURCE=1)
UNSET(RP_C11_CFLAG) UNSET(RP_C11_CFLAG)
UNSET(RP_CXX11_CXXFLAG) UNSET(RP_CXX11_CXXFLAG)

View File

@ -5,21 +5,33 @@
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DMINGW_HAS_SECURE_API") SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DMINGW_HAS_SECURE_API")
# Subsystem and minimum Windows version: # Subsystem and minimum Windows version:
# - If 32-bit: 5.01 # - If i386: 5.01
# - If 64-bit: 5.02 # - If amd64: 5.02
# - If arm or arm64: 6.02
# NOTE: MS_ENH_RSA_AES_PROV is only available starting with # NOTE: MS_ENH_RSA_AES_PROV is only available starting with
# Windows XP. Because we're actually using some XP-specific # Windows XP. Because we're actually using some XP-specific
# functionality now, the minimum version is now Windows XP. # functionality now, the minimum version is now Windows XP.
IF(CMAKE_SIZEOF_VOID_P EQUAL 8) IF(CPU_amd64)
# 64-bit, Unicode Windows only. # amd64 (64-bit), Unicode Windows only.
# (There is no 64-bit ANSI Windows.) # (There is no amd64 ANSI Windows.)
SET(CMAKE_CREATE_WIN32_EXE "-Wl,--subsystem,windows:5.02") # Minimum target version is Windows Server 2003 / XP 64-bit.
SET(CMAKE_CREATE_CONSOLE_EXE "-Wl,--subsystem,console:5.02") SET(RP_WIN32_SUBSYSTEM_VERSION "5.02")
ELSE() ELSEIF(CPU_arm OR CPU_arm64)
# ARM (32-bit or 64-bit), Unicode windows only. (MSVC)
# (There is no ARM ANSI Windows.)
# Minimum target version is Windows 8.
SET(RP_WIN32_SUBSYSTEM_VERSION "6.02")
ELSEIF(CPU_i386)
# 32-bit, Unicode Windows only. # 32-bit, Unicode Windows only.
SET(CMAKE_CREATE_WIN32_EXE "-Wl,--subsystem,windows:5.01") # Minimum target version is Windows XP.
SET(CMAKE_CREATE_CONSOLE_EXE "-Wl,--subsystem,console:5.01") SET(RP_WIN32_SUBSYSTEM_VERSION "5.01")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported CPU.")
ENDIF() ENDIF()
# FIXME: Maybe we should use RP_LINKER_FLAGS_WIN32_EXE and RP_LINKER_FLAGS_CONSOLE_EXE.
# This is what's used in win32-msvc.cmake.
SET(CMAKE_CREATE_WIN32_EXE "-Wl,--subsystem,windows:${RP_WIN32_SUBSYSTEM_VERSION}")
SET(CMAKE_CREATE_CONSOLE_EXE "-Wl,--subsystem,console:${RP_WIN32_SUBSYSTEM_VERSION}")
SET(RP_EXE_LINKER_FLAGS_WIN32 "") SET(RP_EXE_LINKER_FLAGS_WIN32 "")
SET(RP_SHARED_LINKER_FLAGS_WIN32 "") SET(RP_SHARED_LINKER_FLAGS_WIN32 "")

View File

@ -11,8 +11,9 @@ ENDIF()
# No ANSI support. # No ANSI support.
# Subsystem and minimum Windows version: # Subsystem and minimum Windows version:
# - If 32-bit: 5.01 # - If i386: 5.01
# - If 64-bit: 5.02 # - If amd64: 5.02
# - If arm or arm64: 6.02
# ROM Properties does NOT support ANSI Windows. # ROM Properties does NOT support ANSI Windows.
# MSVC 2010's minimum supported target OS is XP SP2. # MSVC 2010's minimum supported target OS is XP SP2.
# MSVC 2012 and later has a minimum subsystem value of 5.01. # MSVC 2012 and later has a minimum subsystem value of 5.01.
@ -25,20 +26,22 @@ ENDIF()
# NOTE: MS_ENH_RSA_AES_PROV is only available starting with # NOTE: MS_ENH_RSA_AES_PROV is only available starting with
# Windows XP. Because we're actually using some XP-specific # Windows XP. Because we're actually using some XP-specific
# functionality now, the minimum version is now Windows XP. # functionality now, the minimum version is now Windows XP.
IF(MSVC AND CMAKE_CL_64) IF(CPU_amd64)
# 64-bit, Unicode Windows only. (MSVC) # amd64 (64-bit), Unicode Windows only. (MSVC)
# (There is no 64-bit ANSI Windows.) # (There is no amd64 ANSI Windows.)
# Minimum target version is Windows Server 2003 / XP 64-bit. # Minimum target version is Windows Server 2003 / XP 64-bit.
SET(RP_WIN32_SUBSYSTEM_VERSION "5.02") SET(RP_WIN32_SUBSYSTEM_VERSION "5.02")
ELSEIF(NOT MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) ELSEIF(CPU_arm OR CPU_arm64)
# 64-bit, Unicode Windows only. (MinGW) # ARM (32-bit or 64-bit), Unicode windows only. (MSVC)
# (There is no 64-bit ANSI Windows.) # (There is no ARM ANSI Windows.)
# Minimum target version is Windows Server 2003 / XP 64-bit. # Minimum target version is Windows 8.
SET(RP_WIN32_SUBSYSTEM_VERSION "5.02") SET(RP_WIN32_SUBSYSTEM_VERSION "6.02")
ELSE() ELSEIF(CPU_i386)
# 32-bit, Unicode Windows only. # i386 (32-bit), Unicode Windows only.
# Minimum target version is Windows XP. # Minimum target version is Windows XP.
SET(RP_WIN32_SUBSYSTEM_VERSION "5.01") SET(RP_WIN32_SUBSYSTEM_VERSION "5.01")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported CPU.")
ENDIF() ENDIF()
SET(RP_LINKER_FLAGS_WIN32_EXE "/SUBSYSTEM:WINDOWS,${RP_WIN32_SUBSYSTEM_VERSION}") SET(RP_LINKER_FLAGS_WIN32_EXE "/SUBSYSTEM:WINDOWS,${RP_WIN32_SUBSYSTEM_VERSION}")
SET(RP_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,${RP_WIN32_SUBSYSTEM_VERSION}") SET(RP_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,${RP_WIN32_SUBSYSTEM_VERSION}")
@ -47,10 +50,6 @@ UNSET(RP_WIN32_SUBSYSTEM_VERSION)
# Append the CFLAGS and LDFLAGS. # Append the CFLAGS and LDFLAGS.
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_C_FLAGS_WIN32}") SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_C_FLAGS_WIN32}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_WIN32} ${RP_CXX_FLAGS_WIN32}") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_WIN32} ${RP_CXX_FLAGS_WIN32}")
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} ${RP_EXE_LINKER_FLAGS_WIN32}")
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} ${RP_EXE_LINKER_FLAGS_WIN32}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} ${RP_EXE_LINKER_FLAGS_WIN32}")
# Unset temporary variables. # Unset temporary variables.
UNSET(RP_C_FLAGS_WIN32) UNSET(RP_C_FLAGS_WIN32)
UNSET(RP_EXE_LINKER_FLAGS_WIN32)

View File

@ -0,0 +1,20 @@
SET(HOST_SYSTEM i686-w64-mingw32)
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR i686)
# which compilers to use for C and C++
SET(CMAKE_C_COMPILER ${HOST_SYSTEM}-gcc)
SET(CMAKE_CXX_COMPILER ${HOST_SYSTEM}-g++)
SET(CMAKE_RC_COMPILER ${HOST_SYSTEM}-windres)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/${HOST_SYSTEM})
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -0,0 +1,20 @@
SET(HOST_SYSTEM x86_64-w64-mingw32)
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
# which compilers to use for C and C++
SET(CMAKE_C_COMPILER ${HOST_SYSTEM}-gcc)
SET(CMAKE_CXX_COMPILER ${HOST_SYSTEM}-g++)
SET(CMAKE_RC_COMPILER ${HOST_SYSTEM}-windres)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/${HOST_SYSTEM})
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)