Added CMake macros and C++ 2011 compatibility files from Gens/GS.

Some stuff was stripped out, including support for ANSI Windows.
The minimum version I'm officially going to support once I add
Windows support is XP, though 2000 might "just work".
This commit is contained in:
David Korth 2016-07-19 23:47:51 -04:00
parent 19b2eea6c5
commit 5b8fb8e945
20 changed files with 1256 additions and 0 deletions

View File

@ -1,7 +1,15 @@
PROJECT(rom-properties)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0)
# TODO: Options.
SET(BUILD_KDE4 ON)
LIST(APPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros"
)
# Check for platform-specific functionality.
INCLUDE(cmake/platform.cmake)
# Project subdirectories.
ADD_SUBDIRECTORY(src)

View File

@ -0,0 +1,60 @@
# - Check what flag is needed to activate C99 mode.
# CHECK_C99_COMPILER_FLAG(VARIABLE)
#
# VARIABLE - variable to store the result
#
# This actually calls the check_c_source_compiles macro.
# See help for CheckCSourceCompiles for a listing of variables
# that can modify the build.
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Based on CHECK_C_COMPILER_FLAG(). (CheckCCompilerFlag.cmake)
INCLUDE(CheckCSourceCompiles)
MACRO(CHECK_C99_COMPILER_FLAG _RESULT)
# Flag listing borrowed from GNU autoconf's AC_PROG_CC_C99 macro.
UNSET(${_RESULT})
# MSVC doesn't allow setting the C standard.
IF(NOT MSVC)
# Check if C99 is present without any flags.
# gcc-5.1 uses C11 mode by default.
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(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(${_RESULT} ${CHECK_C99_CFLAG})
BREAK()
ENDIF(CFLAG_${CHECK_C99_CFLAG})
UNSET(CFLAG_${CHECK_C99_CFLAG})
ENDFOREACH()
IF(${_RESULT})
MESSAGE(STATUS "Checking what CFLAG is required for C99: ${${_RESULT}}")
ELSE(${_RESULT})
MESSAGE(STATUS "Checking what CFLAG is required for C99: none")
ENDIF(${_RESULT})
ENDIF()
UNSET(CHECK_C99_ENABLED_DEFAULT)
ENDIF(NOT MSVC)
ENDMACRO (CHECK_C99_COMPILER_FLAG)

View File

@ -0,0 +1,67 @@
# - Check what flag is needed to activate C++ 2011 mode.
# CHECK_CXX11_COMPILER_FLAG(VARIABLE)
#
# VARIABLE - variable to store the result
#
# This actually calls the check_c_source_compiles macro.
# See help for CheckCSourceCompiles for a listing of variables
# that can modify the build.
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
# C++ 2011 version Copyright (c) 2011 by David Korth.
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Based on CHECK_C99_COMPILER_FLAG(). (CheckC99CompilerFlag.cmake)
INCLUDE(CheckCXXSourceCompiles)
MACRO(CHECK_CXX11_COMPILER_FLAG _RESULT)
UNSET(${_RESULT})
# MSVC doesn't allow setting the C standard.
IF(NOT MSVC)
# Check if C++ 2011 is present without any flags.
# g++-5.1 uses C++ 1998 by default, but this may change
# in future versions of gcc.
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default:")
CHECK_CXX_SOURCE_COMPILES("
#if !defined(__cplusplus) || __cplusplus < 201103L
#error C++ 2011 is not enabled
#endif
int main() { return 0; }" CHECK_CXX11_ENABLED_DEFAULT)
IF (${CHECK_CXX11_ENABLED_DEFAULT})
UNSET(${_RESULT})
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: yes")
ELSE()
MESSAGE(STATUS "Checking if C++ 2011 is enabled by default: no")
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")
# CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" CHECK_CXX11_CXXFLAG_VARNAME "CHECK_CXXFLAG_${CHECK_CXX11_CXXFLAG}")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_CXX11_CXXFLAG}")
CHECK_CXX_SOURCE_COMPILES("int main() { void *ptr = nullptr; return 0; }" ${CHECK_CXX11_CXXFLAG_VARNAME})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(${${CHECK_CXX11_CXXFLAG_VARNAME}})
SET(${_RESULT} ${CHECK_CXX11_CXXFLAG})
UNSET(${CHECK_CXX11_CXXFLAG_VARNAME})
UNSET(CHECK_CXX11_CXXFLAG_VARNAME)
BREAK()
ENDIF(${${CHECK_CXX11_CXXFLAG_VARNAME}})
UNSET(${CHECK_CXX11_CXXFLAG_VARNAME})
UNSET(CHECK_CXX11_CXXFLAG_VARNAME)
ENDFOREACH()
IF(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: ${${_RESULT}}")
ELSE(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required for C++ 2011: none")
ENDIF(${_RESULT})
ENDIF()
UNSET(CHECK_CXX11_ENABLED_DEFAULT)
ENDIF(NOT MSVC)
ENDMACRO(CHECK_CXX11_COMPILER_FLAG)

View File

@ -0,0 +1,47 @@
# - Check what flag is needed to disable C++ exceptions.
# CHECK_CXX_NO_EXCEPTIONS_COMPILER_FLAG(VARIABLE)
#
# VARIABLE - variable to store the result
#
# This actually calls the check_cxx_source_compiles macro.
# See help for CheckCXXSourceCompiles for a listing of variables
# that can modify the build.
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Based on CHECK_CXX_COMPILER_FLAG(). (CheckCXXCompilerFlag.cmake)
INCLUDE(CheckCXXSourceCompiles)
MACRO(CHECK_CXX_NO_EXCEPTIONS_COMPILER_FLAG _RESULT)
UNSET(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ exceptions:")
IF(MSVC)
# NOTE: This doesn't disable C++ exceptions.
# It only disables "asynchronous" exceptions, which are
# similar to Unix signals.
SET(${_RESULT} "-EHsc")
ELSE(MSVC)
FOREACH(CHECK_CXX_NO_EXCEPTIONS_CFLAG "-fno-exceptions")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_CXX_NO_EXCEPTIONS_CFLAG}")
CHECK_CXX_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_CXX_NO_EXCEPTIONS_CFLAG})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(CFLAG_${CHECK_CXX_NO_EXCEPTIONS_CFLAG})
SET(${_RESULT} ${CHECK_CXX_NO_EXCEPTIONS_CFLAG})
BREAK()
ENDIF(CFLAG_${CHECK_CXX_NO_EXCEPTIONS_CFLAG})
UNSET(CFLAG_${CHECK_CXX_NO_EXCEPTIONS_CFLAG})
ENDFOREACH()
ENDIF(MSVC)
IF(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ exceptions: ${${_RESULT}}")
ELSE(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ exceptions: none")
ENDIF(${_RESULT})
ENDMACRO (CHECK_CXX_NO_EXCEPTIONS_COMPILER_FLAG)

View File

@ -0,0 +1,46 @@
# - Check what flag is needed to disable C++ RTTI.
# CHECK_CXX_NO_RTTI_COMPILER_FLAG(VARIABLE)
#
# VARIABLE - variable to store the result
#
# This actually calls the check_cxx_source_compiles macro.
# See help for CheckCXXSourceCompiles for a listing of variables
# that can modify the build.
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Based on CHECK_CXX_COMPILER_FLAG(). (CheckCXXCompilerFlag.cmake)
# TODO: Add more CXXFLAGS!
INCLUDE(CheckCXXSourceCompiles)
MACRO(CHECK_CXX_NO_RTTI_COMPILER_FLAG _RESULT)
UNSET(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ RTTI:")
IF(MSVC)
SET(${_RESULT} "-GR-")
ELSE(MSVC)
FOREACH(CHECK_CXX_NO_RTTI_CFLAG "-fno-rtti")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_CXX_NO_RTTI_CFLAG}")
CHECK_CXX_SOURCE_COMPILES("int main() { return 0; }" CFLAG_${CHECK_CXX_NO_RTTI_CFLAG})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
IF(CFLAG_${CHECK_CXX_NO_RTTI_CFLAG})
SET(${_RESULT} ${CHECK_CXX_NO_RTTI_CFLAG})
BREAK()
ENDIF(CFLAG_${CHECK_CXX_NO_RTTI_CFLAG})
UNSET(CFLAG_${CHECK_CXX_NO_RTTI_CFLAG})
ENDFOREACH()
ENDIF(MSVC)
IF(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ RTTI: ${${_RESULT}}")
ELSE(${_RESULT})
MESSAGE(STATUS "Checking what CXXFLAG is required to disable C++ RTTI: none")
ENDIF(${_RESULT})
ENDMACRO (CHECK_CXX_NO_RTTI_COMPILER_FLAG)

View File

@ -0,0 +1,31 @@
# Split debug information from an executable into a separate file.
# SPLIT_DEBUG_INFORMATION(EXE_TARGET)
#
# References:
# - http://cmake.3232098.n2.nabble.com/Save-stripped-debugging-information-td6819195.html
# - http://sourceware.org/bugzilla/show_bug.cgi?id=14527
# - If debug symbols are stripped before .gnu_debuglink is added,
# the section will be truncated to .gnu_deb, and hence won't
# be recognized by gdb.
# - FIXME: If the above .gnu_debuglink workaround is used, Windows XP
# and Windows 7 will claim that the executable isn't a valid Win32
# executable. (Wine ignores it and works fine!)
#
MACRO(SET_MSVC_DEBUG_PATH _target)
IF(MSVC)
# CMake seems to use weird settings for the PDB file.
# (at least version 2.8.12.2; 3.0.0 might be different)
STRING(REGEX REPLACE
"/Fd<OBJECT_DIR>/"
"/Fd<TARGET_PDB>"
CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}")
STRING(REGEX REPLACE
"/Fd<OBJECT_DIR>/"
"/Fd<TARGET_PDB>"
CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}")
# Set the target PDB filename.
SET_TARGET_PROPERTIES(${_target}
PROPERTIES PDB "${CMAKE_CURRENT_BINARY_DIRECTORY}/${_target}.pdb")
ENDIF(MSVC)
ENDMACRO(SET_MSVC_DEBUG_PATH)

View File

@ -0,0 +1,60 @@
# Split debug information from an executable into a separate file.
# SPLIT_DEBUG_INFORMATION(EXE_TARGET)
#
# References:
# - http://cmake.3232098.n2.nabble.com/Save-stripped-debugging-information-td6819195.html
# - http://sourceware.org/bugzilla/show_bug.cgi?id=14527
# - If debug symbols are stripped before .gnu_debuglink is added,
# the section will be truncated to .gnu_deb, and hence won't
# be recognized by gdb.
# - FIXME: If the above .gnu_debuglink workaround is used, Windows XP
# and Windows 7 will claim that the executable isn't a valid Win32
# executable. (Wine ignores it and works fine!)
#
IF(NOT MSVC)
# CMake automatically finds objcopy and strip as
# part of its toolchain initialization.
IF(NOT CMAKE_OBJCOPY)
MESSAGE(WARNING "'objcopy' was not found; debug information will not be split.")
ELSEIF(NOT CMAKE_STRIP)
MESSAGE(WARNING "'strip' was not found; debug information will not be split.")
ENDIF()
ENDIF(NOT MSVC)
MACRO(SPLIT_DEBUG_INFORMATION EXE_TARGET)
SET(SPLIT_OK 1)
IF(MSVC)
# MSVC splits debug information by itself.
SET(SPLIT_OK 0)
ELSEIF(NOT CMAKE_OBJCOPY)
# 'objcopy' is missing.
SET(SPLIT_OK 0)
ELSEIF(NOT CMAKE_STRIP)
# 'strip' is missing.
SET(SPLIT_OK 0)
ENDIF()
IF(SPLIT_OK)
# NOTE: $<TARGET_FILE:gcbanner> is preferred,
# but this doesn't seem to work on Ubuntu 10.04.
# (cmake_2.8.0-5ubuntu1_i386)
GET_PROPERTY(SPLITDEBUG_EXE_LOCATION TARGET ${EXE_TARGET} PROPERTY LOCATION)
# NOTE: objcopy --strip-debug does NOT fully
# strip the binary; two sections are left:
# - .symtab: Symbol table.
# - .strtab: String table.
# These sections are split into the .debug file, so there's
# no reason to keep them in the executable.
ADD_CUSTOM_COMMAND(TARGET ${EXE_TARGET} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug
${SPLITDEBUG_EXE_LOCATION} ${CMAKE_CURRENT_BINARY_DIR}/${EXE_TARGET}.debug
COMMAND ${CMAKE_STRIP}
${SPLITDEBUG_EXE_LOCATION}
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=${EXE_TARGET}.debug
${SPLITDEBUG_EXE_LOCATION}
)
UNSET(SPLITDEBUG_EXE_LOCATION)
ENDIF(SPLIT_OK)
ENDMACRO(SPLIT_DEBUG_INFORMATION)

View File

@ -0,0 +1,35 @@
# Win32 image version linker flags.
# Determines the appropriate flags to use with MinGW and MSVC.
# The TARGET_VERSION field causes executables to be named
# program.exe-1.0 when built with MinGW, so we can't use it.
#
# The appropriate flags are automatically appended to
# CMAKE_EXE_LINKER_FLAGS_(DEBUG|RELEASE) and
# CMAKE_SHARED_LINKER_FLAGS_(DEBUG|RELEASE).
MACRO(WIN32_IMAGE_VERSION_LINKER_FLAGS _major_version _minor_version)
IF(WIN32)
IF(MSVC)
SET(_remove_flags "/version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>")
SET(_linker_flags "-version:${_major_version}.${_minor_version}")
ELSEIF(MINGW)
# NOTE: Also ${CMAKE_GNULD_IMAGE_VERSION}.
SET(_remove_flags "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>")
SET(_linker_flags "-Wl,--major-image-version,${_major_version},--minor-image-version,${_minor_version}")
ELSE()
MESSAGE(FATAL_ERROR "Unknown Windows compiler, please fix WIN32_IMAGE_VERSION_LINKER_FLAGS.")
ENDIF()
# Replace the version flags.
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}")
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
STRING(REPLACE "${_remove_flags}" "${_linker_flags}" CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE}")
# Unset temporary variables.
UNSET(_remove_flags)
UNSET(_linker_flags)
ENDIF(WIN32)
ENDMACRO(WIN32_IMAGE_VERSION_LINKER_FLAGS)

75
cmake/platform.cmake Normal file
View File

@ -0,0 +1,75 @@
# Platform-specific functionality.
# Hack to remove -rdynamic from CFLAGS and CXXFLAGS
# See http://public.kitware.com/pipermail/cmake/2006-July/010404.html
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
ENDIF()
# Don't embed rpaths in the executables.
SET(CMAKE_SKIP_RPATH ON)
# Common flag variables:
# [common]
# - RP_C_FLAGS_COMMON
# - RP_CXX_FLAGS_COMMON
# - RP_EXE_LINKER_FLAGS_COMMON
# - RP_SHARED_LINKER_FLAGS_COMMON
# [debug]
# - RP_C_FLAGS_DEBUG
# - RP_CXX_FLAGS_DEBUG
# - RP_EXE_LINKER_FLAGS_DEBUG
# - RP_SHARED_LINKER_FLAGS_DEBUG
# [release]
# - RP_C_FLAGS_RELEASE
# - RP_CXX_FLAGS_RELEASE
# - RP_EXE_LINKER_FLAGS_RELEASE
# - RP_SHARED_LINKER_FLAGS_RELEASE
#
# DEBUG and RELEASE variables do *not* include COMMON.
IF(MSVC)
INCLUDE(cmake/platform/msvc.cmake)
ELSE(MSVC)
INCLUDE(cmake/platform/gcc.cmake)
ENDIF(MSVC)
# Platform-specific configuration.
IF(WIN32)
INCLUDE(cmake/platform/win32.cmake)
ENDIF(WIN32)
# Set CMAKE flags.
# TODO: RelWithDebInfo / MinSizeRel?
# Common
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RP_C_FLAGS_COMMON}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RP_CXX_FLAGS_COMMON}")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${RP_EXE_LINKER_FLAGS_COMMON}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${RP_SHARED_LINKER_FLAGS_COMMON}")
# Debug
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${RP_C_FLAGS_DEBUG}")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${RP_CXX_FLAGS_DEBUG}")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${RP_EXE_LINKER_FLAGS_DEBUG}")
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${RP_SHARED_LINKER_FLAGS_DEBUG}")
# Release
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RP_C_FLAGS_RELEASE}")
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}")
# Unset temporary variables.
# Common
UNSET(RP_C_FLAGS_COMMON)
UNSET(RP_CXX_FLAGS_COMMON)
UNSET(RP_EXE_LINKER_FLAGS_COMMON)
UNSET(RP_SHARED_LINKER_FLAGS_COMMON)
# Debug
UNSET(RP_C_FLAGS_DEBUG)
UNSET(RP_CXX_FLAGS_DEBUG)
UNSET(RP_EXE_LINKER_FLAGS_DEBUG)
UNSET(RP_SHARED_LINKER_FLAGS_DEBUG)
# Release
UNSET(RP_C_FLAGS_RELEASE)
UNSET(RP_CXX_FLAGS_RELEASE)
UNSET(RP_EXE_LINKER_FLAGS_RELEASE)
UNSET(RP_SHARED_LINKER_FLAGS_RELEASE)

85
cmake/platform/gcc.cmake Normal file
View File

@ -0,0 +1,85 @@
# gcc (and other Unix-like compilers, e.g. MinGW)
# Compiler flag modules.
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCXXCompilerFlag)
# Check what flag is needed for C99 support.
INCLUDE(CheckC99CompilerFlag)
CHECK_C99_COMPILER_FLAG(RP_C99_CFLAG)
# Check what flag is needed for C++ 2011 support.
INCLUDE(CheckCXX11CompilerFlag)
CHECK_CXX11_COMPILER_FLAG(RP_CXX11_CXXFLAG)
# Disable C++ RTTI.
INCLUDE(CheckCXXNoRTTICompilerFlag)
CHECK_CXX_NO_RTTI_COMPILER_FLAG(RP_CXX_NO_RTTI_CXXFLAG)
# Disable C++ exceptions.
INCLUDE(CheckCXXNoExceptionsCompilerFlag)
CHECK_CXX_NO_EXCEPTIONS_COMPILER_FLAG(RP_CXX_NO_EXCEPTIONS_CXXFLAG)
SET(RP_C_FLAGS_COMMON "${RP_C99_CFLAG}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX11_CXXFLAG} ${RP_CXX_NO_RTTI_CXXFLAG} ${RP_CXX_NO_EXCEPTIONS_CXXFLAG}")
SET(RP_EXE_LINKER_FLAGS_COMMON "")
UNSET(RP_C99_CFLAG)
UNSET(RP_CXX11_CXXFLAG)
UNSET(RP_CXX_NO_RTTI_CXXFLAG)
UNSET(RP_CXX_NO_EXCEPTIONS_CXXFLAG)
# Test for common CFLAGS and CXXFLAGS.
FOREACH(FLAG_TEST "-Wall" "-Wextra" "-fstrict-aliasing" "-fvisibility=hidden")
CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST})
IF(CFLAG_${FLAG_TEST})
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}")
ENDIF(CFLAG_${FLAG_TEST})
UNSET(CFLAG_${FLAG_TEST})
CHECK_CXX_COMPILER_FLAG("${FLAG_TEST}" CXXFLAG_${FLAG_TEST})
IF(CXXFLAG_${FLAG_TEST})
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}")
ENDIF(CXXFLAG_${FLAG_TEST})
UNSET(CXXFLAG_${FLAG_TEST})
ENDFOREACH()
# Test for common CXXFLAGS.
FOREACH(FLAG_TEST "-fvisibility-inlines-hidden")
CHECK_CXX_COMPILER_FLAG("${FLAG_TEST}" CXXFLAG_${FLAG_TEST})
IF(CXXFLAG_${FLAG_TEST})
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}")
ENDIF(CXXFLAG_${FLAG_TEST})
UNSET(CXXFLAG_${FLAG_TEST})
ENDFOREACH()
# Test for common LDFLAGS.
# TODO: Doesn't work on OS X. (which means it's not really testing it!)
IF(NOT APPLE)
FOREACH(FLAG_TEST "-Wl,-O1" "-Wl,--sort-common" "-Wl,--as-needed")
CHECK_C_COMPILER_FLAG("${FLAG_TEST}" LDFLAG_${FLAG_TEST})
IF(LDFLAG_${FLAG_TEST})
SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} ${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST})
UNSET(LDFLAG_${FLAG_TEST})
ENDFOREACH()
ENDIF(NOT APPLE)
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
# 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)
IF (CFLAG_OPTIMIZE_DEBUG)
SET(CFLAG_OPTIMIZE_DEBUG "-Og")
ELSE(CFLAG_OPTIMIZE_DEBUG)
SET(CFLAG_OPTIMIZE_DEBUG "-O0")
ENDIF(CFLAG_OPTIMIZE_DEBUG)
# 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")
# Unset temporary variables.
UNSET(CFLAG_OPTIMIZE_DEBUG)

59
cmake/platform/msvc.cmake Normal file
View File

@ -0,0 +1,59 @@
# Microsoft Visual C++
# CMake has a bunch of defaults, including /Od for debug and /O2 for release.
# Remove some default CFLAGS/CXXFLAGS.
STRING(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# Disable useless warnings:
# - MSVC "logo" messages
# - C4355: 'this' used in base member initializer list (used for Qt Dpointer pattern)
# - MSVCRT "deprecated" functions
SET(GENS_C_FLAGS_COMMON "-nologo -wd4355 -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE")
SET(GENS_CXX_FLAGS_COMMON "${GENS_C_FLAGS_COMMON}")
# NOTE: -tsaware is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003)
SET(GENS_EXE_LINKER_FLAGS_COMMON "-nologo /manifest:no -dynamicbase -nxcompat -largeaddressaware")
SET(GENS_SHARED_LINKER_FLAGS_COMMON "${GENS_EXE_LINKER_FLAGS_COMMON}")
# Disable C++ RTTI and asynchronous exceptions.
SET(GENS_CXX_FLAGS_COMMON "${GENS_CXX_FLAGS_COMMON} -GR- -EHsc")
# Disable the RC and MASM "logo".
SET(CMAKE_RC_FLAGS "-nologo")
SET(CMAKE_ASM_MASM_FLAGS "-nologo")
# Check for link-time optimization.
IF(ENABLE_LTO)
SET(GENS_C_FLAGS_COMMON "${GENS_C_FLAGS_COMMON} -GL")
SET(GENS_CXX_FLAGS_COMMON "${GENS_CXX_FLAGS_COMMON} -GL")
SET(GENS_EXE_LINKER_FLAGS_COMMON "${GENS_EXE_LINKER_FLAGS_COMMON} -LTCG")
SET(GENS_SHARED_LINKER_FLAGS_COMMON "${GENS_SHARED_LINKER_FLAGS_COMMON} -LTCG")
ENDIF(ENABLE_LTO)
# Check if CMAKE_SIZEOF_VOID_P is set correctly.
IF(NOT CMAKE_SIZEOF_VOID_P)
# CMAKE_SIZEOF_VOID_P isn't set.
# Set it based on CMAKE_SYSTEM_PROCESSOR.
# FIXME: This won't work if we're cross-compiling, e.g. using
# the x86_amd64 or amd64_x86 toolchains.
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
IF(arch MATCHES "^x86_64$|^amd64$|^ia64$")
SET(CMAKE_SIZEOF_VOID_P 8)
ELSEIF(arch MATCHES "^(i.|x)86$")
SET(CMAKE_SIZEOF_VOID_P 4)
ELSE()
# Assume other CPUs are 32-bit.
SET(CMAKE_SIZEOF_VOID_P 4)
ENDIF()
UNSET(arch)
ENDIF(NOT CMAKE_SIZEOF_VOID_P)
# Debug/release flags.
SET(GENS_C_FLAGS_DEBUG "-Zi")
SET(GENS_CXX_FLAGS_DEBUG "-Zi")
SET(GENS_EXE_LINKER_FLAGS_DEBUG "-debug -incremental")
SET(GENS_SHARED_LINKER_FLAGS_DEBUG "${GENS_EXE_LINKER_FLAGS_DEBUG}")
SET(GENS_C_FLAGS_RELEASE "-Zi")
SET(GENS_CXX_FLAGS_RELEASE "-Zi")
SET(GENS_EXE_LINKER_FLAGS_RELEASE "-debug -incremental:no -opt:icf,ref")
SET(GENS_SHARED_LINKER_FLAGS_RELEASE "${GENS_EXE_LINKER_FLAGS_RELEASE}")

View File

@ -0,0 +1,102 @@
# Win32-specific CFLAGS/CXXFLAGS.
# For MinGW compilers.
# Basic platform flags for gcc:
# - wchar_t is short.
# - Enable MSVC 2005 compatibility. (In MinGW-w64 v4.0.2, this enables 64-bit time_t.)
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -D__MINGW_USE_VC2005_COMPAT")
# NOTE: This program is Unicode only on Windows.
# No ANSI support.
# Subsystem and minimum Windows version:
# - If 32-bit: 5.00
# - If 64-bit: 5.02
# TODO: Does CMAKE_CREATE_*_EXE also affect DLLs?
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit, Unicode Windows only.
# (There is no 64-bit ANSI Windows.)
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -D_WIN32_WINNT=0x0502")
SET(CMAKE_CREATE_WIN32_EXE "-Wl,--subsystem,windows:5.02")
SET(CMAKE_CREATE_CONSOLE_EXE "-Wl,--subsystem,console:5.02")
ELSE()
# 32-bit, Unicode Windows only.
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -D_WIN32_WINNT=0x0500")
SET(CMAKE_CREATE_WIN32_EXE "-Wl,--subsystem,windows:5.00")
SET(CMAKE_CREATE_CONSOLE_EXE "-Wl,--subsystem,console:5.00")
ENDIF()
SET(RP_EXE_LINKER_FLAGS_WIN32 "")
SET(RP_SHARED_LINKER_FLAGS_WIN32 "")
# Release build: Prefer static libraries.
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.
# NOTE: Technically, --tsaware is only valid for EXEs, not DLLs,
# but we should mark DLLs anyway.
# 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}")
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)
ENDFOREACH()
SET(RP_SHARED_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32}")
# Test for dynamicbase (ASLR) support.
# Simply enabling --dynamicbase won't work; we also need to
# tell `ld` to generate the .reloc section. Also, there's
# a bug in `ld` where if it generates the .reloc section,
# it conveniently forgets the entry point.
# Reference: https://lists.libav.org/pipermail/libav-devel/2014-October/063871.html
INCLUDE(CheckSystemX8632)
CHECK_SYSTEM_X86_32(MINGW_IS_CPU_X86_32)
# TODO: Does ARM Windows have a leading underscore?
IF(MINGW_IS_CPU_X86_32)
SET(ENTRY_POINT "_mainCRTStartup")
ELSE(MINGW_IS_CPU_X86_32)
SET(ENTRY_POINT "mainCRTStartup")
ENDIF(MINGW_IS_CPU_X86_32)
FOREACH(FLAG_TEST "-Wl,--dynamicbase,--pic-executable")
# CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
CHECK_C_COMPILER_FLAG("${FLAG_TEST}" LDFLAG_${FLAG_TEST_VARNAME})
IF(LDFLAG_${FLAG_TEST_VARNAME})
# Entry point is only set for EXEs.
# GNU `ld` always has the -e option.
SET(RP_EXE_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} ${FLAG_TEST} -Wl,-e,${ENTRY_POINT}")
SET(RP_SHARED_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32} ${FLAG_TEST}")
ENDIF(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(LDFLAG_${FLAG_TEST_VARNAME})
UNSET(FLAG_TEST_VARNAME)
ENDFOREACH()
# Enable windres support on MinGW.
# http://www.cmake.org/Bug/view.php?id=4068
SET(CMAKE_RC_COMPILER_INIT windres)
ENABLE_LANGUAGE(RC)
# NOTE: Setting CMAKE_RC_OUTPUT_EXTENSION doesn't seem to work.
# Force windres to output COFF, even though it'll use the .res extension.
SET(CMAKE_RC_OUTPUT_EXTENSION .obj)
SET(CMAKE_RC_COMPILE_OBJECT
"<CMAKE_RC_COMPILER> --output-format=coff <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>")
# Append the CFLAGS and LDFLAGS.
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_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_SHARED_LINKER_FLAGS_WIN32}")
# Unset temporary variables.
UNSET(RP_C_FLAGS_WIN32)
UNSET(RP_EXE_LINKER_FLAGS_WIN32)

View File

@ -0,0 +1,51 @@
# Win32-specific CFLAGS/CXXFLAGS.
# For Microsoft Visual C++ compilers.
# Basic platform flags for MSVC:
# - wchar_t should be a distinct type. (MSVC 2002+)
IF(MSVC_VERSION GREATER 1200)
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -Zc:wchar_t")
ENDIF()
# NOTE: This program is Unicode only on Windows.
# No ANSI support.
# Subsystem and minimum Windows version:
# - If 32-bit: 5.00
# - If 64-bit: 5.02
# NOTE: MSVC 2012 and later has a minimum subsystem value of 5.01.
# NOTE: CMAKE sets /subsystem:windows or /subsystem:console itself.
# It does not affect the subsystem version that's set here, though.
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit, Unicode Windows only.
# (There is no 64-bit ANSI Windows.)
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -D_WIN32_WINNT=0x0502")
SET(RP_EXE_LINKER_FLAGS_WIN32 "-subsystem:windows,5.02")
ELSE()
# 32-bit, Unicode Windows only.
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -D_WIN32_WINNT=0x0500")
IF(MSVC_VERSION GREATER 1600)
# MSVC 2012 or later.
# Minimum target version is Windows XP.
SET(RP_EXE_LINKER_FLAGS_WIN32 "-subsystem:windows,5.01")
ELSE()
# MSVC 2010 or earlier.
SET(RP_EXE_LINKER_FLAGS_WIN32 "-subsystem:windows,5.00")
ENDIF()
ENDIF()
SET(RP_SHARED_LINKER_FLAGS_WIN32 "${RP_EXE_LINKER_FLAGS_WIN32}")
# Release build: Prefer static libraries.
IF(CMAKE_BUILD_TYPE MATCHES ^release)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(CMAKE_BUILD_TYPE MATCHES ^release)
# Append the CFLAGS and LDFLAGS.
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_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}")
# Unset temporary variables.
UNSET(RP_C_FLAGS_WIN32)
UNSET(RP_EXE_LINKER_FLAGS_WIN32)

View File

@ -0,0 +1,24 @@
# Win32-specific CFLAGS/CXXFLAGS.
# Basic platform flags:
# - 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")
# 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")
# Compiler-specific Win32 flags.
IF(MSVC)
INCLUDE(cmake/platform/win32-msvc.cmake)
ELSE(MSVC)
INCLUDE(cmake/platform/win32-gcc.cmake)
ENDIF(MSVC)

View File

@ -1,6 +1,20 @@
PROJECT(src)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0)
# C++11 compatibility header.
# NOTE: This must be included regardless of C++11 support in the compiler.
# gcc-4.6 supports some C++11, but is missing explicit virtual overrides.
IF(MSVC)
SET(RP_CXX11_COMPAT_HEADER "-FI${CMAKE_CURRENT_SOURCE_DIR}/c++11-compat.h")
ELSE(MSVC)
SET(RP_CXX11_COMPAT_HEADER "-include ${CMAKE_CURRENT_SOURCE_DIR}/c++11-compat.h")
ENDIF(MSVC)
SET(RP_CXXFLAG_CXX11_COMPAT ${RP_CXX11_COMPAT_HEADER})
# Add the C++11 compatibility header to CFLAGS/CXXFLAGS.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RP_CXX11_COMPAT_HEADER}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RP_CXXFLAG_CXX11_COMPAT}")
# Source Code subdirectories.
ADD_SUBDIRECTORY(libromdata)
ADD_SUBDIRECTORY(kde)

80
src/c++11-compat.clang.h Normal file
View File

@ -0,0 +1,80 @@
/***************************************************************************
* c++11-compat.clang.h: C++ 2011 compatibility header. (clang) *
* *
* Copyright (c) 2011-2015 by David Korth. *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef __CXX11_COMPAT_GCC_H__
#define __CXX11_COMPAT_GCC_H__
#if !defined(__clang__)
#error c++11-compat.clang.h should only be included in LLVM/clang builds.
#endif
/**
* LLVM/clang defines __GNUC__ for compatibility, but the reported gcc
* version number doesn't match clang's featureset. For example,
* clang-3.7.0 claims to be gcc-4.2.1, which doesn't support any
* C++ 2011 functionality.
*
* A clang version matrix is available at:
* - http://clang.llvm.org/cxx_status.html#cxx11
*/
/** C++ 2011 **/
#ifdef __cplusplus
/**
* Enable compatibility for C++ 2011 features that aren't
* present in older versions of LLVM/clang.
*
* These are all automatically enabled when compiling C code.
*/
/* For clang-3.1+, make sure we're compiling with -std=c++11 or -std=gnu++11. */
/* Older versions didn't set the correct value for __cplusplus in order to */
/* maintain compatibility with gcc-4.6 and earlier. */
#if (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1))
#if __cplusplus < 201103L
#error Please compile with -std=c++11 or -std=gnu++11.
#endif /* __cplusplus */
#endif /* __clang_major__ */
/**
* clang-3.0 added the following:
* - nullptr
* - Explicit virtual override
*/
#if (__clang_major__ < 3)
#define CXX11_COMPAT_NULLPTR
#define CXX11_COMPAT_OVERRIDE
#endif
/**
* clang-2.9 added the following:
* - New character types
* - Static assertions
*/
#if (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 9))
#define CXX11_COMPAT_CHARTYPES
#define CXX11_COMPAT_STATIC_ASSERT
#endif
#endif /* __cplusplus */
#endif /* __CXX11_COMPAT_CLANG_H__ */

69
src/c++11-compat.gcc.h Normal file
View File

@ -0,0 +1,69 @@
/***************************************************************************
* c++11-compat.gcc.h: C++ 2011 compatibility header. (gcc) *
* *
* Copyright (c) 2011-2015 by David Korth. *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef __CXX11_COMPAT_GCC_H__
#define __CXX11_COMPAT_GCC_H__
#if !defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
#error c++11-compat.gcc.h should only be included in gcc builds.
#endif
/** C++ 2011 **/
#ifdef __cplusplus
/**
* Enable compatibility for C++ 2011 features that aren't
* present in older versions of gcc.
*
* These are all automatically enabled when compiling C code.
*/
/* For gcc-4.7+, make sure we're compiling with -std=c++11 or -std=gnu++11. */
/* Older versions didn't set the correct value for __cplusplus. */
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
#if __cplusplus < 201103L
#error Please compile with -std=c++11 or -std=gnu++11.
#endif /* __cplusplus */
#endif /* __GNUC__ */
/* Explicit virtual override: Added in gcc-4.7. */
#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7))
#define CXX11_COMPAT_OVERRIDE
#endif
/* nullptr: Added in gcc-4.6 */
#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6))
#define CXX11_COMPAT_NULLPTR
#endif
/* New character types: Added in gcc-4.4 */
#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
#define CXX11_COMPAT_CHARTYPES
#endif
/* Static assertions: Added in gcc-4.3 (first version to support C++11) */
#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3))
#define CXX11_COMPAT_STATIC_ASSERT
#endif
#endif /* __cplusplus */
#endif /* __CXX11_COMPAT_GCC_H__ */

103
src/c++11-compat.h Normal file
View File

@ -0,0 +1,103 @@
/***************************************************************************
* c++11-compat.h: C++ 2011 compatibility header. *
* *
* Copyright (c) 2011-2015 by David Korth. *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef __CXX11_COMPAT_H__
#define __CXX11_COMPAT_H__
#ifndef __cplusplus
/**
* We're compiling C code.
* Provide replacements for C++ 2011 functionality.
*/
#define CXX11_COMPAT_NULLPTR
#define CXX11_COMPAT_OVERRIDE
#define CXX11_COMPAT_CHARTYPES
#define CXX11_COMPAT_STATIC_ASSERT
#endif /* !__cplusplus */
/** Compiler-specific headers. **/
#if defined(__clang__)
#include "c++11-compat.clang.h"
#elif defined(__GNUC__)
#include "c++11-compat.gcc.h"
#elif defined(_MSC_VER)
#include "c++11-compat.msvc.h"
#else
#error Unknown compiler, please update c++11-compat.h.
#endif
/* nullptr: Represents a NULL pointer. NULL == 0 */
#ifdef CXX11_COMPAT_NULLPTR
#define nullptr 0
#endif
/* static_assert(): Compile-time assertions. */
#ifdef CXX11_COMPAT_STATIC_ASSERT
#define static_assert(expr, msg) switch (0) { case 0: case (expr): ; }
#endif
/* Unicode characters and strings. */
#ifdef CXX11_COMPAT_CHARTYPES
#include <stdint.h>
typedef uint16_t char16_t;
typedef uint32_t char32_t;
#ifdef __cplusplus
#include <string>
namespace std {
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
}
#endif /* __cplusplus */
#endif /* CXX11_COMPAT_CHARTYPES */
/* Explicit override/final. */
#ifdef CXX11_COMPAT_OVERRIDE
#define override
/* final may be defined as 'sealed' on older MSVC */
#ifndef final
#define final
#endif
#endif
/** Other compatibility stuff. **/
/**
* MSVC (and old gcc) doesn't have __func__.
* Reference: http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
*/
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
# if (defined(__GNUC__) && __GNUC__ >= 2) || defined(_MSC_VER)
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
/**
* MSVCRT prior to MSVC 2015 has a non-compliant _snprintf().
* Note that MinGW-w64 uses MSVCRT.
*/
#ifdef _WIN32
#include "c99-compat.msvcrt.h"
#endif
#endif /* __CXX11_COMPAT_H__ */

118
src/c++11-compat.msvc.h Normal file
View File

@ -0,0 +1,118 @@
/***************************************************************************
* c++11-compat.msvc.h: C++ 2011 compatibility header. (MSVC) *
* *
* Copyright (c) 2011-2015 by David Korth. *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef __CXX11_COMPAT_MSVC_H__
#define __CXX11_COMPAT_MSVC_H__
#ifndef _MSC_VER
#error c++11-compat.msvc.h should only be included in MSVC builds.
#endif
/** C++ 2011 **/
#ifdef __cplusplus
/**
* Enable compatibility for C++ 2011 features that aren't
* present in older versions of MSVC.
*
* These are all automatically enabled when compiling C code.
*/
#if (_MSC_VER < 1900)
/**
* MSVC 2015 (14.0) added support for Unicode character types.
* (char16_t, char32_t, related string types)
*/
#define CXX11_COMPAT_CHARTYPES
#endif
#if (_MSC_VER < 1700)
/**
* MSVC 2010 (10.0) does support override, but not final.
* However, it has a "sealed" keyword that works almost
* the same way as final.
*
* 'sealed' is available starting with MSVC 2005 (8.0).
* TODO: Verify MSVC 2002 and 2003.
*/
#if (_MSC_VER >= 1400)
#define final sealed
#endif
#endif
#if (_MSC_VER < 1600)
/**
* MSVC 2008 (9.0) and older: No C++ 2011 support at all.
* Probably won't compile at all due to lack of stdint.h.
*/
#define CXX11_COMPAT_NULLPTR
#define CXX11_COMPAT_OVERRIDE
#define CXX11_COMPAT_STATIC_ASSERT
#endif
#endif /* __cplusplus */
/** C99 **/
/**
* C library functions that have different names in MSVCRT
* compared to POSIX and C99.
*
* Note that later versions of MSVC (esp. 2013 and 2015)
* have added more C99 functionality, since C99 is included
* in C++ 2011.
*/
/** strcasecmp(), strncasecmp() **/
/**
* MSVC does not, and probably never will, define these functions.
* It has equivalent functions with different names, though.
*/
#define strcasecmp(s1, s2) _stricmp(s1, s2)
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
#define wcscasecmp(s1, s2) _wcsicmp(s1, s2)
#define wcsncasecmp(s1, s2, n) _wcsnicmp(s1, s2, n)
/** strtoll(), strtoull() **/
/**
* MSVC 2013 (12.0) added proper support for strtoll() and strtoull().
* Older verisons don't have these functions, but they do have
* the equivalent functions _strtoi64() and _strtoui64().
*/
#if _MSC_VER < 1800
#define strtoll(nptr, endptr, base) _strtoi64(nptr, endptr, base)
#define strtoull(nptr, endptr, base) _strtoui64(nptr, endptr, base)
#define wcstoll(nptr, endptr, base) _wcstoi64(nptr, endptr, base)
#define wcstoull(nptr, endptr, base) _wcstoui64(nptr, endptr, base)
#endif /* _MSC_VER < 1800 */
/**
* MSVC doesn't have typeof(), but as of MSVC 2010,
* it has decltype(), which is essentially the same thing.
* TODO: Handle older versions.
* Possible option for C++:
* - http://www.nedproductions.biz/blog/implementing-typeof-in-microsofts-c-compiler
*/
#define typeof(x) decltype(x)
#endif /* __CXX11_COMPAT_MSVC_H__ */

122
src/c99-compat.msvcrt.h Normal file
View File

@ -0,0 +1,122 @@
/***************************************************************************
* c99-compat.msvcrt.h: C99 compatibility header. (MSVC) *
* *
* Copyright (c) 2011-2016 by David Korth. *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef __C99_COMPAT_MSVCRT_H__
#define __C99_COMPAT_MSVCRT_H__
#ifndef _WIN32
#error c99-compat.msvcrt.h should only be included in Win32 builds.
#endif
#if defined(__GNUC__)
// MinGW-w64.
// TODO: Check standard MinGW?
#if !defined(__USE_MINGW_ANSI_STDIO)
// Using MSVCRT's snprintf().
#define ENABLE_C99_SNPRINTF_WRAPPERS 1
#endif
#elif defined(_MSC_VER)
/**
* MSVC 2015 added proper support for C99 snprintf().
* Older versions have _snprintf(), which isn't fully compatible.
* In addition, MSVC 2015 added support for 'inline' in C mode.
* Previous versions only support 'inline' in C++ mode, but they
* do support '__inline' in both C and C++.
*/
#if _MSC_VER < 1900
#define ENABLE_C99_SNPRINTF_WRAPPERS 1
#if !defined(__cplusplus)
#define inline __inline
#endif /* !defined(__cplusplus) */
#endif /* _MSC_VER < 1900 */
#endif /* __GNUC__, _MSC_VER */
#ifdef ENABLE_C99_SNPRINTF_WRAPPERS
#include <stdarg.h>
#include <stdio.h>
/**
* MSVC 2005 added support for variadic macros.
* https://msdn.microsoft.com/en-US/library/ms177415(v=vs.80).aspx
* TODO: Verify MSVC 2002 and 2003.
*/
#if defined(_MSC_VER) && _MSC_VER < 1400
/* MSVC 2003 and older. Don't use variadic macros. */
#define snprintf C99_snprintf
#define vsnprintf C99_vsnprintf
#else
/* MSVC 2005 or later, or gcc. Use variadic macros. */
#define snprintf(str, size, format, ...) C99_snprintf(str, size, format, __VA_ARGS__)
#define vsnprintf(str, size, format, ...) C99_vsnprintf(str, size, format, __VA_ARGS__)
#endif /* defined(_MSC_VER) && _MSC_VER < 1400 */
static
#if defined(_MSC_VER)
__forceinline
#elif defined(__GNUC__)
__inline
__attribute__ ((__format__ (gnu_printf, 3, 0)))
__attribute__ ((__nonnull__ (3)))
__attribute__ ((always_inline))
__attribute__ ((unused))
#endif
int C99_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int ret = _vsnprintf(str, size, format, ap);
if (ret >= (int)size) {
// Make sure the buffer is NULL-terminated.
str[size-1] = 0;
} else if (ret < 0) {
// Make sure the buffer is empty.
// MSVCRT *should* do this, but just in case...
str[0] = 0;
}
return ret;
}
static
#if defined(_MSC_VER)
__forceinline
#elif defined(__GNUC__)
__inline
__attribute__ ((__format__ (gnu_printf, 3, 0)))
__attribute__ ((__nonnull__ (3)))
/* NOTE: gcc complains that this function cannot be inlined
* becuase it uses variable argument lists.
__attribute__ ((always_inline))*/
__attribute__ ((unused))
#endif
int C99_snprintf(char *str, size_t size, const char *format, ...)
{
int ret;
va_list ap;
va_start(ap, format);
ret = C99_vsnprintf(str, size, format, ap);
va_end(ap);
return ret;
}
#endif /* ENABLE_C99_SNPRINTF_WRAPPERS */
#endif /* __C99_COMPAT_MSVCRT_H__ */