Initial import of RVT-H Tool.

This program will allow for managing Nintendo RVT-H Reader devkits,
including dumping existing images and installing new images.

The current version doesn't actually do anything. It's mostly a copy
of the infrastructure from rom-properties, with some changes. In
particular, we're using CMake's TARGET_COMPILE_FEATURES() instead of
manually detecting C99 support.
This commit is contained in:
David Korth 2018-01-15 06:58:54 -05:00
commit f321fe5e65
28 changed files with 2215 additions and 0 deletions

19
.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
# Filetypes.
*~
*.o
*.a
*.so
.directory
*.kate-swp
# Build directories.
/build*
# KDevelop project files.
*.kdev4
# CMake temproary files.
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
git_version.h

172
CMakeLists.txt Normal file
View File

@ -0,0 +1,172 @@
PROJECT(rvthtool-base)
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
LIST(APPEND CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/cmake/macros"
)
# If no build type is set, default to "Debug".
# TODO: Default to "Release"?
STRING(TOLOWER "${CMAKE_BUILD_TYPE}" TMP_BUILD_TYPE)
IF(TMP_BUILD_TYPE STREQUAL "")
SET(CMAKE_BUILD_TYPE "Release")
ELSEIF(TMP_BUILD_TYPE MATCHES "none")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF()
UNSET(TMP_BUILD_TYPE)
# Put all the binaries and libraries into a single directory.
# NOTE: CACHE INTERNAL is required in order to get this to work
# for KDE5 for some reason. (and maybe that's why KDE4 did this
# layout by default?)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE INTERNAL "Put all binaries in a single directory.")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE INTERNAL "Put all libraries in a single directory.")
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE INTERNAL "Put all archives in a single directory.")
# Check for platform-specific functionality.
INCLUDE(cmake/platform.cmake NO_POLICY_SCOPE)
# Program information.
SET(DESCRIPTION "RVT-H Tool")
SET(PACKAGE_NAME "rvthtool")
SET(AUTHOR "David Korth")
SET(VERSION_MAJOR 0)
SET(VERSION_MINOR 0)
SET(VERSION_PATCH 0)
SET(VERSION_DEVEL 1)
IF(VERSION_PATCH)
SET(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
ELSE(VERSION_PATCH)
SET(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}")
ENDIF(VERSION_PATCH)
IF(VERSION_DEVEL)
SET(VERSION_STRING "${VERSION_STRING}+")
ENDIF(VERSION_DEVEL)
SET(VERSION_STRING_WIN32 "${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_DEVEL}")
# Split Debug macro.
# Also sets the image version for Windows builds.
INCLUDE(Win32ImageVersionLinkerFlags)
MACRO(DO_SPLIT_DEBUG _target)
IF(TARGET ${_target})
# Split debug information.
INCLUDE(SetMSVCDebugPath)
SET_MSVC_DEBUG_PATH(${_target})
IF(SPLIT_DEBUG)
INCLUDE(SplitDebugInformation)
SPLIT_DEBUG_INFORMATION(${_target})
ENDIF(SPLIT_DEBUG)
# Set image version.
# Subprojects can override ${VERSION_MAJOR} and ${VERSION_MINOR}.
# FIXME: If minor version is e.g. "3", Windows interprets it as "03",
# so "1.3" will actually be "1.03".
WIN32_IMAGE_VERSION_LINKER_FLAGS(${VERSION_MAJOR} ${VERSION_MINOR})
ENDIF(TARGET ${_target})
ENDMACRO(DO_SPLIT_DEBUG)
# Git version information.
FIND_PROGRAM(POSIX_SH sh)
IF(POSIX_SH)
# sh is available.
# Run the git version script.
IF(WIN32)
SET(ENV{SHELLOPTS} igncr)
ENDIF(WIN32)
ADD_CUSTOM_TARGET(git_version ALL
${POSIX_SH} "${CMAKE_SOURCE_DIR}/git_version.sh"
-s "${CMAKE_SOURCE_DIR}"
-o "${CMAKE_BINARY_DIR}/git_version.h"
VERBATIM
)
ELSE(POSIX_SH)
# sh isn't available.
# Create a blank git_version.h.
FILE(WRITE "${CMAKE_BINARY_DIR}/git_version.h"
"/* dummy file; POSIX sh is not available */\n")
ENDIF(POSIX_SH)
# Make sure the file is deleted on `make clean`.
SET_PROPERTY(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_BINARY_DIR}/git_version.h")
# Reference: https://cmake.org/Wiki/RecipeAddUninstallTarget
########### Add uninstall target ###############
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake")
### Subdirectories. ###
# Project subdirectories.
ADD_SUBDIRECTORY(src)
# TODO: Print build summary indicating what plugins will be built.
# (Some other project had something like this...)
# TODO: Fail if no plugins are being built.
# CPack settings.
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${DESCRIPTION}")
SET(CPACK_PACKAGE_NAME "${PACKAGE_NAME}")
SET(CPACK_PACKAGE_VENDOR "${AUTHOR}")
SET(CPACK_PACKAGE_CONTACT "David Korth <gerbilsoft@gerbilsoft.com>")
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
SET(CPACK_PACKAGE_VERSION ${VERSION_STRING})
# TODO: DESCRIPTION and WELCOME files.
#SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/doc/DESCRIPTION.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
#SET(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/doc/WELCOME.txt")
# CPack: Source package settings.
# NOTE: Double-escape is required because the unescaped
# string # is written to CPackSourceConfig.cmake, which
# is then unescaped.
SET(CPACK_SOURCE_GENERATOR "TGZ")
SET(CPACK_SOURCE_IGNORE_FILES
"build.*/"
"build.*\\\\.sh"
"\\\\.git/"
"\\\\.gitignore"
"*\\\\.kate-swp"
)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.|x)86\$")
SET(CPACK_PACKAGE_SYSTEM_PROCESSOR "i386")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64\$")
SET(CPACK_PACKAGE_SYSTEM_PROCESSOR "amd64")
ELSE()
SET(CPACK_PACKAGE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR})
ENDIF()
IF(APPLE)
# TODO: Support for Mac OS X.
ELSEIF(WIN32)
IF(MSVC AND CMAKE_CL_64)
SET(WIN32_PACKAGE_SUFFIX "win64")
ELSEIF(NOT MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(WIN32_PACKAGE_SUFFIX "win64")
ELSE()
SET(WIN32_PACKAGE_SUFFIX "win32")
ENDIF()
SET(CPACK_GENERATOR "ZIP")
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}-${WIN32_PACKAGE_SUFFIX}")
SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
ENDIF()
# Components.
SET(CPACK_COMPONENTS_ALL dll program debug doc i18n)
SET(CPACK_COMPONENT_DLL_DISPLAY_NAME "DLLs")
SET(CPACK_COMPONENT_PROGRAM_DISPLAY_NAME "Programs")
SET(CPACK_COMPONENT_DEBUG_DISPLAY_NAME "Debugging Symbols")
SET(CPACK_COMPONENT_DOC_DISPLAY_NAME "Documents")
SET(CPACK_COMPONENT_I18N_DISPLAY_NAME "Internationalization")
# Initialize CPack.
INCLUDE(CPack)

2
LICENSE Normal file
View File

@ -0,0 +1,2 @@
GNU General Public License, version 2 or any later version.
See GPL-2 or GPL-3 for the full text of these licenses.

1
README.md Normal file
View File

@ -0,0 +1 @@
# RVT-H Tool

View File

@ -0,0 +1,23 @@
# Reference: https://cmake.org/Wiki/RecipeAddUninstallTarget
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE " " ";" files "${files}")
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling $ENV{DESTDIR}${file}")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove $ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSE(EXISTS "$ENV{DESTDIR}${file}")
MESSAGE(STATUS "File $ENV{DESTDIR}${file} does not exist.")
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
ENDFOREACH(file)

View File

@ -0,0 +1,18 @@
/**
* 64-bit time_t test code.
* Reference: https://github.com/Benjamin-Dobell/Heimdall/blob/master/cmake/LargeFiles.c
*/
#include <stdint.h>
#include <time.h>
/** static_assert() macro copied from c++11-compat.h **/
#define static_assert(expr, msg) switch (0) { case 0: case (expr): ; }
int main(int argc, char *argv[])
{
static_assert(sizeof(time_t) == sizeof(int64_t), "time_t is the wrong size");
int64_t tm64;
time_t tm = time(&tm64);
return 0;
}

View File

@ -0,0 +1,80 @@
# Check for 64-bit time support.
# Known cases:
# - Windows, MSVC: Supported as of MSVC 2005.
# - Windows, MinGW: Supported if -D__MINGW_USE_VC2005_COMPAT is defined.
# - 32-bit Linux: Supported in an upcoming glibc release.
# - 64-bit Linux: No macros are required.
# - 32-bit Mac OS X: Not supported.
# - 64-bit Mac OS X: No macros are required.
# Partially based on:
# https://github.com/Benjamin-Dobell/Heimdall/blob/master/cmake/LargeFiles.cmake
# This sets the following variables:
# - TIME64_FOUND: Set to 1 if 64-bit time_t is supported.
# - TIME64_FOUND_MINGW: Set to 1 if MinGW-w64's -D__MINGW_USE_VC2005_COMPAT is in use.
# - TIME64_FOUND_TIME_BITS: Set to 1 if glibc's -D_TIME_BITS=64 is in use.
# - TIME64_DEFINITIONS: Preprocessor macros required for large file support, if any.
FUNCTION(CHECK_64BIT_TIME_SUPPORT)
IF(NOT DEFINED TIME64_FOUND)
# NOTE: ${CMAKE_MODULE_PATH} has two directories, macros/ and libs/,
# so we have to configure this manually.
SET(TIME64_SOURCE_PATH "${CMAKE_SOURCE_DIR}/cmake/macros")
# Check for 64-bit time_t.
MESSAGE(STATUS "Checking if time_t is 64-bit")
IF(MSVC)
IF(MSVC_VERSION LESS 1310)
MESSAGE(STATUS "Checking if time_t is 64-bit - no")
MESSAGE(WARNING "MSVC 2005 (8.0) or later is required for 64-bit time_t.")
ELSE()
MESSAGE(STATUS "Checking if time_t is 64-bit - yes")
SET(TMP_TIME64_FOUND 1)
ENDIF()
ELSEIF(MINGW)
# MinGW should support 64-bit time_t if -D__MINGW_USE_VC2005_COMPAT is specified.
SET(TMP_TIME64_DEFINITIONS -D__MINGW_USE_VC2005_COMPAT)
TRY_COMPILE(TMP_TIME64_FOUND "${CMAKE_BINARY_DIR}"
"${TIME64_SOURCE_PATH}/64BitTimeSupport.c"
COMPILE_DEFINITIONS ${TMP_TIME64_DEFINITIONS})
IF(TMP_TIME64_FOUND)
MESSAGE(STATUS "Checking if time_t is 64-bit - yes, using -D__MINGW_USE_VC2005_COMPAT")
SET(TMP_TIME64_FOUND_MINGW 1)
ELSE(TMP_TIME64_FOUND)
MESSAGE(STATUS "Checking if time_t is 64-bit - no")
MESSAGE(WARNING "MinGW-w64 is required for 64-bit time_t.")
UNSET(TMP_TIME64_DEFINITIONS)
ENDIF(TMP_TIME64_FOUND)
ELSE()
# Check if the OS supports 64-bit time_t out of the box.
TRY_COMPILE(TMP_TIME64_FOUND "${CMAKE_BINARY_DIR}"
"${TIME64_SOURCE_PATH}/64BitTimeSupport.c")
IF(TMP_TIME64_FOUND)
# Supported out of the box.
MESSAGE(STATUS "Checking if time_t is 64-bit - yes")
ELSE()
# Try adding 64-bit time_t macros.
# Reference: https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=115
SET(TMP_TIME64_DEFINITIONS -D_TIME_BITS=64)
TRY_COMPILE(TMP_TIME64_FOUND "${CMAKE_BINARY_DIR}"
"${TIME64_SOURCE_PATH}/64BitTimeSupport.c"
COMPILE_DEFINITIONS ${TMP_TIME64_DEFINITIONS})
IF(TMP_TIME64_FOUND)
# TIME64 macros work.
MESSAGE(STATUS "Checking if time_t is 64-bit - yes, using -D_TIME_BITS=64")
SET(TMP_TIME64_FOUND_TIME_BITS 1)
ELSE()
# TIME64 macros failed.
MESSAGE(STATUS "Checking if time_t is 64-bit - no")
UNSET(TMP_TIME64_DEFINITIONS)
ENDIF()
ENDIF()
ENDIF()
SET(TIME64_FOUND ${TMP_TIME64_FOUND} CACHE INTERNAL "Is Large File Support available?")
SET(TIME64_FOUND_MINGW ${TMP_TIME64_FOUND_TIME_BITS} CACHE INTERNAL "64-bit time_t is available using -D__MINGW_USE_VC2005_COMPAT")
SET(TIME64_FOUND_TIME_BITS ${TMP_TIME64_FOUND_TIME_BITS} CACHE INTERNAL "64-bit time_t is available using -D_TIME_BITS=64")
SET(TIME64_DEFINITIONS "${TMP_TIME64_DEFINITIONS}" CACHE INTERNAL "Definitions required for 64-bit time_t")
ENDIF()
ENDFUNCTION(CHECK_64BIT_TIME_SUPPORT)

View File

@ -0,0 +1,27 @@
# Check what flags are needed for hidden visibility.
# Usage: CHECK_HIDDEN_VISIBILITY()
#
# NOTE: Do NOT use this for extlibs, since many extlibs, including
# zlib, don't work properly if symbols aren't visible by default.
MACRO(CHECK_HIDDEN_VISIBILITY)
# Check for visibility symbols.
IF(NOT CMAKE_VERSION VERSION_LESS 3.3.0)
# CMake 3.3: Use CMake predefined variables.
# NOTE: CMake 3.0-3.2 do not apply these settings
# to static libraries, so we have to fall back to the
# "deprecated" ADD_COMPILER_EXPORT_FLAGS().
CMAKE_POLICY(SET CMP0063 NEW)
SET(CMAKE_C_VISIBILITY_PRESET "hidden")
SET(CMAKE_CXX_VISIBILITY_PRESET "hidden")
SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
ELSE()
# CMake 2.x, 3.0-3.2: Use ADD_COMPILER_EXPORT_FLAGS().
# NOTE: 3.0+ will show a deprecation warning.
INCLUDE(GenerateExportHeader)
ADD_COMPILER_EXPORT_FLAGS(RP_COMPILER_EXPORT_FLAGS)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RP_COMPILER_EXPORT_FLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RP_COMPILER_EXPORT_FLAGS}")
UNSET(RP_COMPILER_EXPORT_FLAGS)
ENDIF()
ENDMACRO()

View File

@ -0,0 +1,78 @@
# Check for Large File Support.
# Known cases:
# - Windows, MSVC: No macros are needed, but 64-bit functions must be
# used explicitly, e.g. _fseeki64() and _ftelli64(). libW32U
# provides macro redefinitions for this.
# - Windows, MinGW: LFS functions fseeko() and ftello() are present.
# LFS Macros are required for large files.
# - 32-bit Linux: LFS macros are required.
# - 64-bit Linux: No macros are required.
# - All Mac OS X: No macros are required.
# Partially based on:
# https://github.com/Benjamin-Dobell/Heimdall/blob/master/cmake/LargeFiles.cmake
# This sets the following variables:
# - LFS_FOUND: Set to 1 if LFS is supported.
# - LFS_FOUND_FSEEKO: Set to 1 if LFS is supported using fseeko().
# - LFS_FOUND_FSEEKI64: Set to 1 if LFS is supported using _fseeki64().
# - LFS_DEFINITIONS: Preprocessor macros required for large file support, if any.
# TODO: Use _fseeki64() and _ftelli64() on MinGW to avoid
# the use of wrapper functions?
FUNCTION(CHECK_LARGE_FILE_SUPPORT)
IF(NOT DEFINED LFS_FOUND)
# NOTE: ${CMAKE_MODULE_PATH} has two directories, macros/ and libs/,
# so we have to configure this manually.
SET(LFS_SOURCE_PATH "${CMAKE_SOURCE_DIR}/cmake/macros")
# Check for LFS.
MESSAGE(STATUS "Checking if Large File Support is available")
IF(MSVC)
# Check if _fseeki64() and _ftelli64() are available.
TRY_COMPILE(TMP_LFS_FOUND "${CMAKE_BINARY_DIR}"
"${LFS_SOURCE_PATH}/LargeFileSupport_fseeki64.c")
IF(TMP_LFS_FOUND)
# _fseeki64() and _ftelli64() are available.
MESSAGE(STATUS "Checking if Large File Support is available - yes, using MSVC non-standard functions")
SET(TMP_LFS_FOUND_FSEEKI64 1)
ELSE()
# Not available...
MESSAGE(STATUS "Checking if Large File Support is available - no")
MESSAGE(WARNING "MSVC 2005 (8.0) or later is required for Large File Support.")
ENDIF()
ELSE()
# Check if the OS supports Large Files out of the box.
TRY_COMPILE(TMP_LFS_FOUND "${CMAKE_BINARY_DIR}"
"${LFS_SOURCE_PATH}/LargeFileSupport_fseeko.c")
IF(TMP_LFS_FOUND)
# Supported out of the box.
MESSAGE(STATUS "Checking if Large File Support is available - yes")
ELSE()
# Try adding LFS macros.
SET(TMP_LFS_DEFINITIONS -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64)
TRY_COMPILE(TMP_LFS_FOUND "${CMAKE_BINARY_DIR}"
"${LFS_SOURCE_PATH}/LargeFileSupport_fseeko.c"
COMPILE_DEFINITIONS ${TMP_LFS_DEFINITIONS})
IF(TMP_LFS_FOUND)
# LFS macros work.
MESSAGE(STATUS "Checking if Large File Support is available - yes, using LFS macros")
SET(TMP_LFS_FOUND_FSEEKO 1)
# NOTE: COMPILE_DEFINITIONS requires a semicolon-separated list;
# CFLAGS reqiures space-separated.
STRING(REPLACE ";" " " TMP_LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}")
ELSE()
# LFS macros failed.
MESSAGE(STATUS "Checking if Large File Support is available - no")
UNSET(TMP_LFS_DEFINITIONS)
ENDIF()
ENDIF()
ENDIF()
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_FSEEKI64 ${TMP_LFS_FOUND_FSEEKI64} CACHE INTERNAL "Large File Support is available using MSVC non-standard functions")
SET(LFS_DEFINITIONS "${TMP_LFS_DEFINITIONS}" CACHE INTERNAL "Definitions required for Large File Support")
ENDIF()
ENDFUNCTION(CHECK_LARGE_FILE_SUPPORT)

View File

@ -0,0 +1,116 @@
# - Check what flag is needed to enable stack smashing protection
# CHECK_STACK_PROTECTOR_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(CheckCSourceCompiles)
MACRO(CHECK_STACK_PROTECTOR_COMPILER_FLAG _RESULT)
UNSET(${_RESULT})
IF(MSVC)
# MSVC 2002 introduced the /GS option.
# MSVC 2005+ enables it by default.
IF(MSVC_VERSION GREATER 1399)
# MSVC 2005+.
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: none")
ELSEIF(MSVC_VERSION GREATER 1299)
# MSVC 2002 or 2003.
SET(${_RESULT} "/GS")
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${${_RESULT}}")
ELSE()
# MSVC 2002 or earlier.
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: not available")
ENDIF()
ELSE(MSVC)
# gcc-4.1: -fstack-protector, -fstack-protector-all
# gcc-4.9: -fstack-protector-strong
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection:")
FOREACH(CHECK_STACK_CFLAG "-fstack-protector-strong" "-fstack-protector-all" "-fstack-protector")
# CMake doesn't like "+" characters in variable names.
STRING(REPLACE "+" "_" CHECK_STACK_CFLAG_VARNAME "CHECK_CFLAG_${CHECK_STACK_CFLAG}")
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(SAFE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
SET(CMAKE_REQUIRED_DEFINITIONS "${CHECK_STACK_CFLAG}")
IF(WIN32)
SET(CMAKE_REQUIRED_LIBRARIES "-lkernel32")
ELSE(WIN32)
SET(CMAKE_REQUIRED_LIBRARIES "-lc")
ENDIF(WIN32)
# NOTE: We need a function that triggers stack smashing protection
# in order to determine if libssp is needed on MinGW-w64.
# Based on wrapper functions in c99-compat.msvcrt.h.
CHECK_C_SOURCE_COMPILES("
#include <stdio.h>
#include <stdarg.h>
#ifndef _MSC_VER
#define _vsnprintf vsnprintf
#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;
}
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;
}
int main(int argc, char *argv[])
{
char buf[128];
snprintf(buf, sizeof(buf), \"test: %s\", argv[0]);
puts(buf);
return 0;
}" ${CHECK_STACK_CFLAG_VARNAME})
SET(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_LIBRARIES "${SAFE_CMAKE_REQUIRED_LIBRARIES}")
IF(${${CHECK_STACK_CFLAG_VARNAME}})
SET(${_RESULT} ${CHECK_STACK_CFLAG})
UNSET(${CHECK_STACK_CFLAG_VARNAME})
UNSET(CHECK_STACK_CFLAG_VARNAME)
BREAK()
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()
IF(${_RESULT})
MESSAGE(STATUS "Checking what CFLAG is required for stack smashing protection: ${${_RESULT}}")
ELSE(${_RESULT})
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.")
ENDIF(${_RESULT})
ENDIF(MSVC)
ENDMACRO(CHECK_STACK_PROTECTOR_COMPILER_FLAG)

View File

@ -0,0 +1,77 @@
# Directory install paths.
# Files are installed in different directories depending
# on platform, e.g. Unix-style for Linux and most other
# Unix systems.
# NOTE: DIR_INSTALL_DOC_ROOT is for documents that should
# be in the root of the Windows ZIP file. On other platforms,
# it's the same as DIR_INSTALL_DOC.
IF(NOT PACKAGE_NAME)
MESSAGE(FATAL_ERROR "PACKAGE_NAME is not set.")
ENDIF(NOT PACKAGE_NAME)
# Architecture name for arch-specific paths.
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
IF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$")
# i386/amd64. Check sizeof(void*) for the actual architecture,
# since building 32-bit on 64-bit isn't considered "cross-compiling",
# so CMAKE_SYSTEM_PROCESSOR might not be accurate.
# NOTE: Checking CMAKE_CL_64 instead of sizeof(void*) for MSVC builds.
IF(MSVC AND CMAKE_CL_64)
SET(arch "amd64")
ELSEIF(NOT MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(arch "amd64")
ELSE()
SET(arch "i386")
ENDIF()
ENDIF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$")
INCLUDE(GNUInstallDirs)
IF(UNIX AND NOT APPLE)
# Unix-style install paths.
# NOTE: CMake doesn't use Debian-style multiarch for libexec,
# so we have to check for that.
IF(CMAKE_INSTALL_LIBDIR MATCHES .*gnu.*)
SET(CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}/libexec" CACHE "libexec override for Debian multi-arch" INTERNAL FORCE)
SET(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}/libexec" CACHE "libexec override for Debian multi-arch" INTERNAL FORCE)
ENDIF()
SET(DIR_INSTALL_EXE "${CMAKE_INSTALL_BINDIR}")
SET(DIR_INSTALL_DLL "${CMAKE_INSTALL_LIBDIR}")
SET(DIR_INSTALL_LIB "${CMAKE_INSTALL_LIBDIR}")
SET(DIR_INSTALL_LIBEXEC "${CMAKE_INSTALL_LIBEXECDIR}")
SET(DIR_INSTALL_LOCALE "share/locale")
SET(DIR_INSTALL_DOC "share/doc/${PACKAGE_NAME}")
SET(DIR_INSTALL_DOC_ROOT "${DIR_INSTALL_DOC}")
SET(DIR_INSTALL_EXE_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_EXE}")
SET(DIR_INSTALL_DLL_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_DLL}")
SET(DIR_INSTALL_LIB_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIB}")
SET(DIR_INSTALL_LIBEXEC_DEBUG "lib/debug/${CMAKE_INSTALL_PREFIX}/${DIR_INSTALL_LIBEXEC}")
ELSEIF(APPLE)
# Mac OS X-style install paths.
# Install should be relative to the application bundle.
# TODO: Not supported...
MESSAGE(STATUS "WARNING: Mac OS X is not officially supported yet.")
ELSEIF(WIN32)
# Win32-style install paths.
# Files are installed relative to root, since the
# program is run out of its own directory.
SET(DIR_INSTALL_EXE "${arch}")
SET(DIR_INSTALL_DLL "${arch}")
SET(DIR_INSTALL_LIB "${arch}")
SET(DIR_INSTALL_LIBEXEC "${arch}")
SET(DIR_INSTALL_LOCALE "locale")
SET(DIR_INSTALL_DOC "doc")
SET(DIR_INSTALL_DOC_ROOT ".")
SET(DIR_INSTALL_EXE_DEBUG "debug")
# Installing debug symbols for DLLs in the
# same directory as the DLL.
SET(DIR_INSTALL_EXE_DEBUG "${DIR_INSTALL_EXE}")
SET(DIR_INSTALL_DLL_DEBUG "${DIR_INSTALL_DLL}")
SET(DIR_INSTALL_LIB_DEBUG "${DIR_INSTALL_LIB}")
SET(DIR_INSTALL_LIBEXEC_DEBUG "${DIR_INSTALL_LIBEXEC}")
ELSE()
MESSAGE(WARNING "Installation paths have not been set up for this system.")
ENDIF()
UNSET(arch)

View File

@ -0,0 +1,15 @@
/**
* Large File Support test code: _fseeki64(), _ftelli64() [MSVC]
* Reference: https://github.com/Benjamin-Dobell/Heimdall/blob/master/cmake/LargeFilesWindows.c
*/
#include <stdio.h>
int main(int argc, const char **argv)
{
// _fseeki64() and _ftelli64() use __int64.
// NOTE: __int64 is an MSVC-proprietary type.
__int64 offset = _ftelli64(NULL);
_fseeki64(NULL, offset, SEEK_SET);
return 0;
}

View File

@ -0,0 +1,20 @@
/**
* Large File Support test code: fseeko(), ftello() [LFS]
* Reference: https://github.com/Benjamin-Dobell/Heimdall/blob/master/cmake/LargeFiles.c
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/** static_assert() macro copied from c++11-compat.h **/
#define static_assert(expr, msg) switch (0) { case 0: case (expr): ; }
int main(int argc, const char **argv)
{
static_assert(sizeof(off_t) == sizeof(int64_t), "off_t is the wrong size");
off_t offset = ftello(NULL);
fseeko(NULL, offset, SEEK_SET);
return 0;
}

View File

@ -0,0 +1,54 @@
# 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}")
# Handle target prefixes if not overridden.
# NOTE: Cannot easily use the TYPE property in a generator expression...
GET_PROPERTY(TARGET_TYPE TARGET ${_target} PROPERTY TYPE)
SET(PREFIX_EXPR_1 "$<$<STREQUAL:$<TARGET_PROPERTY:${_target},PREFIX>,>:${CMAKE_${TARGET_TYPE}_PREFIX}>")
SET(PREFIX_EXPR_2 "$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:${_target},PREFIX>,>>:$<TARGET_PROPERTY:${_target},PREFIX>>")
SET(PREFIX_EXPR_FULL "${PREFIX_EXPR_1}${PREFIX_EXPR_2}")
# If a custom OUTPUT_NAME was specified, use it.
SET(OUTPUT_NAME_EXPR_1 "$<$<STREQUAL:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>,>:${_target}>")
SET(OUTPUT_NAME_EXPR_2 "$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>,>>:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>>")
SET(OUTPUT_NAME_EXPR "${OUTPUT_NAME_EXPR_1}${OUTPUT_NAME_EXPR_2}")
SET(OUTPUT_NAME_FULL "${PREFIX_EXPR_FULL}${OUTPUT_NAME_EXPR}$<TARGET_PROPERTY:${_target},POSTFIX>")
SET(SPLITDEBUG_SOURCE "$<TARGET_FILE:${_target}>")
SET(SPLITDEBUG_TARGET "$<TARGET_FILE_DIR:${_target}>/${OUTPUT_NAME_FULL}.debug")
SET(OUTPUT_NAME_EXPR_1 "$<TARGET_PROPERTY:${_target},PREFIX>$<TARGET_PROPERTY:${_target},OUTPUT_NAME>$<TARGET_PROPERTY:${_target},POSTFIX>")
SET(OUTPUT_NAME_EXPR_2 "$<$<STREQUAL:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>,>:$<TARGET_PROPERTY:${_target},PREFIX>${_target}$<TARGET_PROPERTY:${_target},POSTFIX>>")
# Set the target PDB filename.
SET_TARGET_PROPERTIES(${_target}
PROPERTIES PDB "$<TARGET_FILE_DIR:${_target}>/${OUTPUT_NAME_EXPR_1}${OUTPUT_NAME_EXPR_2}.pdb"
)
UNSET(OUTPUT_NAME_EXPR_1)
UNSET(OUTPUT_NAME_EXPR_2)
ENDIF(MSVC)
ENDMACRO(SET_MSVC_DEBUG_PATH)

View File

@ -0,0 +1,78 @@
# 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)
INCLUDE(CMakeFindBinUtils)
IF(NOT CMAKE_OBJCOPY)
MESSAGE(WARNING "'objcopy' was not found; debug information will not be split.")
SET(INSTALL_DEBUG OFF CACHE "" INTERNAL FORCE)
ELSEIF(NOT CMAKE_STRIP)
MESSAGE(WARNING "'strip' was not found; debug information will not be split.")
SET(INSTALL_DEBUG OFF CACHE "" INTERNAL FORCE)
ENDIF()
ENDIF(NOT MSVC)
FUNCTION(SPLIT_DEBUG_INFORMATION _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)
# Handle target prefixes if not overridden.
# NOTE: Cannot easily use the TYPE property in a generator expression...
GET_PROPERTY(TARGET_TYPE TARGET ${_target} PROPERTY TYPE)
SET(PREFIX_EXPR_1 "$<$<STREQUAL:$<TARGET_PROPERTY:${_target},PREFIX>,>:${CMAKE_${TARGET_TYPE}_PREFIX}>")
SET(PREFIX_EXPR_2 "$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:${_target},PREFIX>,>>:$<TARGET_PROPERTY:${_target},PREFIX>>")
SET(PREFIX_EXPR_FULL "${PREFIX_EXPR_1}${PREFIX_EXPR_2}")
# If a custom OUTPUT_NAME was specified, use it.
SET(OUTPUT_NAME_EXPR_1 "$<$<STREQUAL:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>,>:${_target}>")
SET(OUTPUT_NAME_EXPR_2 "$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>,>>:$<TARGET_PROPERTY:${_target},OUTPUT_NAME>>")
SET(OUTPUT_NAME_EXPR "${OUTPUT_NAME_EXPR_1}${OUTPUT_NAME_EXPR_2}")
SET(OUTPUT_NAME_FULL "${PREFIX_EXPR_FULL}${OUTPUT_NAME_EXPR}$<TARGET_PROPERTY:${_target},POSTFIX>")
SET(SPLITDEBUG_SOURCE "$<TARGET_FILE:${_target}>")
SET(SPLITDEBUG_TARGET "$<TARGET_FILE_DIR:${_target}>/${OUTPUT_NAME_FULL}.debug")
# 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 ${_target} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug
${SPLITDEBUG_SOURCE} ${SPLITDEBUG_TARGET}
COMMAND ${CMAKE_STRIP}
${SPLITDEBUG_SOURCE}
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink="${SPLITDEBUG_TARGET}"
${SPLITDEBUG_SOURCE}
)
# Set the target property to allow installation.
SET_TARGET_PROPERTIES(${_target} PROPERTIES PDB ${SPLITDEBUG_TARGET})
# Make sure the file is deleted on `make clean`.
SET_PROPERTY(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SPLITDEBUG_TARGET})
ENDIF(SPLIT_OK)
ENDFUNCTION(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)

202
cmake/platform.cmake Normal file
View File

@ -0,0 +1,202 @@
# 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)
# stdint.h must be present.
INCLUDE(CheckIncludeFiles)
CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H)
IF(NOT HAVE_STDINT_H)
MESSAGE(FATAL_ERROR "stdint.h is required.")
ENDIF(NOT HAVE_STDINT_H)
# Common flag variables:
# [common]
# - RP_C_FLAGS_COMMON
# - RP_CXX_FLAGS_COMMON
# - RP_EXE_LINKER_FLAGS_COMMON
# - RP_SHARED_LINKER_FLAGS_COMMON
# - RP_MODULE_LINKER_FLAGS_COMMON
# [debug]
# - RP_C_FLAGS_DEBUG
# - RP_CXX_FLAGS_DEBUG
# - RP_EXE_LINKER_FLAGS_DEBUG
# - RP_SHARED_LINKER_FLAGS_DEBUG
# - RP_MODULE_LINKER_FLAGS_DEBUG
# [release]
# - RP_C_FLAGS_RELEASE
# - RP_CXX_FLAGS_RELEASE
# - RP_EXE_LINKER_FLAGS_RELEASE
# - RP_SHARED_LINKER_FLAGS_RELEASE
# - RP_MODULE_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)
# Check what flag is needed for stack smashing protection.
INCLUDE(CheckStackProtectorCompilerFlag)
CHECK_STACK_PROTECTOR_COMPILER_FLAG(RP_STACK_CFLAG)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_STACK_CFLAG}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_STACK_CFLAG}")
UNSET(RP_STACK_CFLAG)
# Check for Large File Support.
INCLUDE(CheckLargeFileSupport)
CHECK_LARGE_FILE_SUPPORT()
IF(NOT LFS_FOUND)
MESSAGE(FATAL_ERROR "Large File Support is required.")
ENDIF(NOT LFS_FOUND)
IF(LFS_DEFINITIONS)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${LFS_DEFINITIONS}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${LFS_DEFINITIONS}")
ENDIF(LFS_DEFINITIONS)
# Check for 64-bit time_t.
INCLUDE(Check64BitTimeSupport)
CHECK_64BIT_TIME_SUPPORT()
# NOTES:
# - glibc does not currently support 64-bit time_t on 32-bit.
# - Mac OS X does not (and won't) support 64-bit time_t on 32-bit.
IF(TIME64_DEFINITIONS)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${TIME64_DEFINITIONS}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${TIME64_DEFINITIONS}")
ENDIF(TIME64_DEFINITIONS)
# 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}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${RP_MODULE_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}")
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${RP_MODULE_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}")
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${RP_MODULE_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)
UNSET(RP_MODULE_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)
UNSET(RP_MODULE_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)
UNSET(RP_MODULE_LINKER_FLAGS_RELEASE)
###### Windows-specific CMake functions. ######
# Set Windows subsystem when building with MSVC.
FUNCTION(SET_WINDOWS_SUBSYSTEM _target _subsystem)
IF(WIN32 AND MSVC)
GET_TARGET_PROPERTY(TARGET_LINK_FLAGS ${_target} LINK_FLAGS)
IF(TARGET_LINK_FLAGS)
SET(TARGET_LINK_FLAGS "${TARGET_LINK_FLAGS} ${RP_LINKER_FLAGS_${_subsystem}_EXE}")
ELSE()
SET(TARGET_LINK_FLAGS "${RP_LINKER_FLAGS_${_subsystem}_EXE}")
ENDIF()
SET_TARGET_PROPERTIES(${_target} PROPERTIES LINK_FLAGS "${TARGET_LINK_FLAGS}")
ENDIF(WIN32 AND MSVC)
ENDFUNCTION()
# Disable automatic manifest generation when building with MSVC.
# Only use this if you have a custom manifest specified in the resource script.
FUNCTION(SET_WINDOWS_NO_MANIFEST _target)
IF(WIN32 AND MSVC)
GET_TARGET_PROPERTY(TARGET_LINK_FLAGS ${_target} LINK_FLAGS)
IF(TARGET_LINK_FLAGS)
SET(TARGET_LINK_FLAGS "${TARGET_LINK_FLAGS} /MANIFEST:NO")
ELSE()
SET(TARGET_LINK_FLAGS "/MANIFEST:NO")
ENDIF()
SET_TARGET_PROPERTIES(${_target} PROPERTIES LINK_FLAGS "${TARGET_LINK_FLAGS}")
ENDIF(WIN32 AND MSVC)
ENDFUNCTION()
# Set Windows entrypoint.
# _target: Target.
# _entrypoint: Entry point. (main, wmain, WinMain, wWinMain)
# _setargv: If true, link to setargv.obj/wsetargv.obj in MSVC builds.
FUNCTION(SET_WINDOWS_ENTRYPOINT _target _entrypoint _setargv)
IF(WIN32)
IF(MSVC)
# MSVC automatically prepends an underscore if necessary.
SET(ENTRY_POINT_FLAG "/ENTRY:${_entrypoint}CRTStartup")
IF(_setargv)
IF(_entrypoint MATCHES ^wmain OR _entrypoint MATCHES ^wWinMain)
SET(SETARGV_FLAG "wsetargv.obj")
ELSE()
SET(SETARGV_FLAG "setargv.obj")
ENDIF()
ENDIF(_setargv)
UNSET(UNICODE_FLAG)
ELSE(MSVC)
# MinGW does not automatically prepend an underscore.
# TODO: Does ARM Windows have a leading underscore?
# TODO: _setargv for MinGW.
# NOTE: MinGW uses separate crt*.o files for Unicode
# instead of a separate entry point.
IF(_entrypoint MATCHES "^w")
SET(UNICODE_FLAG "-municode")
STRING(SUBSTRING "${_entrypoint}" 1 -1 _entrypoint)
ENDIF()
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
IF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$")
IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(ENTRY_POINT "_${_entrypoint}CRTStartup")
ELSE()
SET(ENTRY_POINT "${_entrypoint}CRTStartup")
ENDIF()
ELSE()
SET(ENTRY_POINT "${_entrypoint}CRTStartup")
ENDIF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$")
SET(ENTRY_POINT_FLAG "-Wl,-e,${ENTRY_POINT}")
UNSET(SETARGV_FLAG)
ENDIF(MSVC)
GET_TARGET_PROPERTY(TARGET_LINK_FLAGS ${_target} LINK_FLAGS)
IF(TARGET_LINK_FLAGS)
SET(TARGET_LINK_FLAGS "${TARGET_LINK_FLAGS} ${UNICODE_FLAG} ${ENTRY_POINT_FLAG} ${SETARGV_FLAG}")
ELSE()
SET(TARGET_LINK_FLAGS "${UNICODE_FLAG} ${ENTRY_POINT_FLAG} ${SETARGV_FLAG}")
ENDIF()
SET_TARGET_PROPERTIES(${_target} PROPERTIES LINK_FLAGS "${TARGET_LINK_FLAGS}")
ENDIF(WIN32)
ENDFUNCTION()

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

@ -0,0 +1,191 @@
# gcc (and other Unix-like compilers, e.g. MinGW)
IF(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
# FIXME: May need later than 2.9.
IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "2.9")
MESSAGE(FATAL_ERROR "clang-2.9 or later is required.")
ENDIF()
ELSEIF(CMAKE_COMPILER_IS_GNUCXX)
IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.5")
MESSAGE(FATAL_ERROR "gcc-4.5 or later is required.")
ENDIF()
ENDIF()
# Compiler flag modules.
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCXXCompilerFlag)
SET(RP_C_FLAGS_COMMON "-D_GNU_SOURCE=1")
SET(RP_CXX_FLAGS_COMMON "-D_GNU_SOURCE=1")
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)
UNSET(RP_STACK_CFLAG)
# Test for common CFLAGS and CXXFLAGS.
FOREACH(FLAG_TEST "-Wall" "-Wextra" "-fstrict-aliasing" "-Wno-multichar")
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()
# Code coverage checking.
IF(ENABLE_COVERAGE)
# Partially based on:
# https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake
# (commit 59f8ab8dded56b490dec388ac6ad449318de8779)
IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
# CMake 3.0.0 added code coverage support.
IF("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
MESSAGE(FATAL_ERROR "clang-3.0.0 or later is required for code coverage testing.")
ENDIF()
ELSEIF(NOT CMAKE_COMPILER_IS_GNUCXX)
MESSAGE(FATAL_ERROR "Code coverage testing is currently only supported on gcc and clang.")
ENDIF()
# Don't bother checking for the coverage options.
# We're assuming they're always supported.
SET(RP_C_FLAGS_COVERAGE "--coverage -fprofile-arcs -ftest-coverage")
SET(RP_C_FLAGS_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 "-lgcov")
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)
# Create a code coverage target.
FOREACH(_program gcov lcov genhtml)
FIND_PROGRAM(${_program}_PATH ${_program})
IF(NOT ${_program}_PATH)
MESSAGE(FATAL_ERROR "${_program} not found; cannot enable code coverage testing.")
ENDIF(NOT ${_program}_PATH)
UNSET(${_program}_PATH)
ENDFOREACH(_program)
ADD_CUSTOM_TARGET(coverage
WORKING_DIRECTORY "${CMAKE_BUILD_DIR}"
COMMAND ${POSIX_SH} "${CMAKE_SOURCE_DIR}/scripts/lcov.sh" "${CMAKE_BUILD_TYPE}" "rom-properties" "coverage"
)
ENDIF(ENABLE_COVERAGE)
# 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" "-Wl,-Bsymbolic-functions")
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()
IF(NOT WIN32)
# Bsymbolic-functions doesn't make sense on Windows.
FOREACH(FLAG_TEST "-Wl,-Bsymbolic-functions")
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 WIN32)
ENDIF(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.
# 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)
# Check for link-time optimization. (Release builds only.)
# FIXME: Running CMake with -DENABLE_LTO=ON, then -DENABLE_LTO=OFF
# doesn't seem to work right... (The flags aren't removed properly.)
# [Kubuntu 17.04, cmake-3.7.2]
IF(ENABLE_LTO)
# We need two wrappers in order for LTO to work properly:
# - gcc-ar: static library archiver
# - gcc-ranlib: static library indexer
# Without these wrappers, all sorts of undefined refernce errors
# occur in gcc-4.9 due to "slim" LTO objects, and possibly
# earlier versions for various reasons.
MESSAGE(STATUS "Checking if the gcc LTO wrappers are available:")
IF("${CMAKE_AR}" MATCHES "gcc-ar$")
# Already using the gcc-ar wrapper.
SET(GCC_WRAPPER_AR "${CMAKE_AR}")
ELSE()
# Replace ar with gcc-ar.
STRING(REGEX REPLACE "ar$" "gcc-ar" GCC_WRAPPER_AR "${CMAKE_AR}")
ENDIF()
IF("${CMAKE_RANLIB}" MATCHES "gcc-ranlib$")
# Already using the gcc-ranlib wrapper.
SET(GCC_WRAPPER_RANLIB "${CMAKE_RANLIB}")
ELSE()
# Replace ranlib with gcc-ranlib.
STRING(REGEX REPLACE "ranlib$" "gcc-ranlib" GCC_WRAPPER_RANLIB "${CMAKE_RANLIB}")
ENDIF()
IF(EXISTS "${GCC_WRAPPER_AR}" AND EXISTS "${GCC_WRAPPER_RANLIB}")
# Found gcc binutils wrappers.
SET(CMAKE_AR "${GCC_WRAPPER_AR}")
SET(CMAKE_RANLIB "${GCC_WRAPPER_RANLIB}")
MESSAGE(STATUS "Checking if the gcc LTO wrappers are available: yes")
# Check for the LTO compiler flag.
CHECK_C_COMPILER_FLAG("-flto" CFLAG_LTO)
IF(CFLAG_LTO)
SET(RP_C_FLAGS_RELEASE "${RP_C_FLAGS_RELEASE} -flto")
SET(RP_CXX_FLAGS_RELEASE "${RP_CXX_FLAGS_RELEASE} -flto")
SET(RP_EXE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_SHARED_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
ELSE(CFLAG_LTO)
MESSAGE(FATAL_ERROR "LTO optimization requested but -flto is not supported.")
ENDIF(CFLAG_LTO)
UNSET(CFLAG_LTO)
ELSE()
MESSAGE(STATUS "Checking if the gcc LTO wrappers are available: no")
MESSAGE(FATAL_ERROR "gcc binutils wrappers not found; cannot enable LTO.")
ENDIF()
ENDIF(ENABLE_LTO)
# Use thin archives on Linux.
# References:
# - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5967db9af51a84f5e181600954714a9e4c69f1f
# - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9a6cfca4f4130444cb02536a4fdf7b6e285c713e
# - https://bugs.webkit.org/show_bug.cgi?id=108330
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")

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

@ -0,0 +1,121 @@
# Microsoft Visual C++
IF(MSVC_VERSION LESS 1600)
MESSAGE(FATAL_ERROR "MSVC 2010 (10.0) or later is required.")
ENDIF()
# Disable useless warnings:
# - MSVC "logo" messages
# - C4355: 'this' used in base member initializer list (used for Qt Dpointer pattern)
# - MSVCRT "deprecated" functions
# Increase some warnings to errors:
# - C4013: function undefined; this is allowed in C, but will
# probably cause a linker error.
SET(RP_C_FLAGS_COMMON "/nologo /wd4355 /wd4482 /we4013 -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE")
SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON}")
# NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003)
# NOTE 2: /TSAWARE is not applicable for DLLs.
SET(RP_EXE_LINKER_FLAGS_COMMON "/NOLOGO /DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE")
SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}")
# Test for "/sdl" and "/guard:cf".
INCLUDE(CheckCCompilerFlag)
FOREACH(FLAG_TEST "/sdl" "/guard:cf")
# CMake doesn't like certain characters in variable names.
STRING(REGEX REPLACE "/|:" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME})
IF(CFLAG_${FLAG_TEST_VARNAME})
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}")
IF(FLAG_TEST STREQUAL "/guard:cf")
# "/guard:cf" must be added to linker flags as well.
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")
ENDIF(CFLAG_${FLAG_TEST_VARNAME})
UNSET(CFLAG_${FLAG_TEST_VARNAME})
ENDFOREACH()
# Disable warning C4996 (deprecated), then re-enable it.
# Otherwise, it gets handled as an error due to /sdl.
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4996 /w34996")
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)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /Zc:threadSafeInit-")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Zc:threadSafeInit-")
ENDIF()
# Disable the RC and MASM "logo".
# FIXME: Setting CMAKE_RC_FLAGS causes msbuild to fail,
# since CMake already sets /NOLOGO there.
# - Also disabling /NOLOGO for MASM just in case.
#SET(CMAKE_RC_FLAGS "/NOLOGO")
#SET(CMAKE_ASM_MASM_FLAGS "/NOLOGO")
# FIXME: MSVC 2015's 32-bit masm has problems when using msbuild:
# - The default /W3 fails for seemingly no reason. /W0 fixes it.
# - Compilation fails due to no SAFESEH handlers in inffas32.asm.
# NOTE: We're enabling these for all MSVC platforms, not just 32-bit.
# NOTE 2: We need to cache this in order to prevent random build failures
# caused by an empty string being cached instead.
SET(CMAKE_ASM_MASM_FLAGS "/W0 /safeseh" CACHE STRING
"Flags used by the assembler during all build types.")
# CPU architecture.
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
# 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.
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()
ENDIF(NOT CMAKE_SIZEOF_VOID_P)
# Use stdcall on i386.
# Applies to unexported functions only.
# Exported functions must have explicit calling conventions.
IF(arch MATCHES "^(i.|x)86$|^x86_64$|^amd64$|^ia64$" AND NOT CMAKE_CL_64)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /Gz")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Gz")
ENDIF()
UNSET(arch)
# TODO: Code coverage checking for MSVC?
IF(ENABLE_COVERAGE)
MESSAGE(FATAL_ERROR "Code coverage testing is currently only supported on gcc and clang.")
ENDIF(ENABLE_COVERAGE)
# Debug/release flags.
SET(RP_C_FLAGS_DEBUG "/Zi")
SET(RP_CXX_FLAGS_DEBUG "/Zi")
SET(RP_EXE_LINKER_FLAGS_DEBUG "/DEBUG /INCREMENTAL")
SET(RP_SHARED_LINKER_FLAGS_DEBUG "${RP_EXE_LINKER_FLAGS_DEBUG}")
SET(RP_MODULE_LINKER_FLAGS_DEBUG "${RP_EXE_LINKER_FLAGS_DEBUG}")
SET(RP_C_FLAGS_RELEASE "/Zi")
SET(RP_CXX_FLAGS_RELEASE "/Zi")
SET(RP_EXE_LINKER_FLAGS_RELEASE "/DEBUG /INCREMENTAL:NO /OPT:ICF,REF")
SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE}")
# Check for link-time optimization. (Release builds only.)
IF(ENABLE_LTO)
SET(RP_C_FLAGS_RELEASE "${RP_C_FLAGS_RELEASE} /GL")
SET(RP_CXX_FLAGS_RELEASE "${RP_CXX_FLAGS_RELEASE} /GL")
SET(RP_EXE_LINKER_FLAGS_RELEASE "${RP_EXE_LINKER_FLAGS_RELEASE} /LTCG")
SET(RP_SHARED_LINKER_FLAGS_RELEASE "${RP_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
SET(RP_MODULE_LINKER_FLAGS_RELEASE "${RP_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
ENDIF(ENABLE_LTO)

View File

@ -0,0 +1,105 @@
# Win32-specific CFLAGS/CXXFLAGS.
# For MinGW compilers.
# Enable "secure" API functions: *_s()
SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} -DMINGW_HAS_SECURE_API")
# Subsystem and minimum Windows version:
# - If 32-bit: 5.01
# - If 64-bit: 5.02
# NOTE: MS_ENH_RSA_AES_PROV is only available starting with
# Windows XP. Because we're actually using some XP-specific
# functionality now, the minimum version is now Windows XP.
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit, Unicode Windows only.
# (There is no 64-bit ANSI Windows.)
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(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 "")
SET(RP_MODULE_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: --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}")
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}")
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}")
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()
# 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
# NOTE: Entry point is set using SET_WINDOWS_ENTRYPOINT()
# in platform.cmake due to ANSI/Unicode differences.
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}")
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}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} ${RP_MODULE_LINKER_FLAGS_WIN32}")
# Unset temporary variables.
UNSET(RP_C_FLAGS_WIN32)
UNSET(RP_EXE_LINKER_FLAGS_WIN32)
UNSET(RP_SHARED_LINKER_FLAGS_WIN32)
UNSET(RP_MODULE_LINKER_FLAGS_WIN32)

View File

@ -0,0 +1,64 @@
# 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
# ROM Properties does NOT support ANSI Windows.
# MSVC 2010's minimum supported target OS is XP SP2.
# MSVC 2012 and later has a minimum subsystem value of 5.01.
# NOTE: CMake sets /subsystem:windows or /subsystem:console itself,
# but with the MSBUILD generator, that's *before* this one, which
# results in console programs being linked as Windows.
# Use the SET_WINDOWS_SUBSYSTEM(_target _subsystem) function defined in
# platform.cmake. That macro will only do anything if building with
# MSVC, since the variables won't be defined anywhere else.
# NOTE: MS_ENH_RSA_AES_PROV is only available starting with
# Windows XP. Because we're actually using some XP-specific
# functionality now, the minimum version is now Windows XP.
IF(MSVC AND CMAKE_CL_64)
# 64-bit, Unicode Windows only. (MSVC)
# (There is no 64-bit ANSI Windows.)
# Minimum target version is Windows Server 2003 / XP 64-bit.
SET(RP_WIN32_SUBSYSTEM_VERSION "5.02")
ELSEIF(NOT MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
# 64-bit, Unicode Windows only. (MinGW)
# (There is no 64-bit ANSI Windows.)
# Minimum target version is Windows Server 2003 / XP 64-bit.
SET(RP_WIN32_SUBSYSTEM_VERSION "5.02")
ELSE()
# 32-bit, Unicode Windows only.
IF(MSVC_VERSION GREATER 1600)
# MSVC 2012 or later.
# Minimum target version is Windows XP.
SET(MCRECOVER_LINKER_FLAGS_WIN32_EXE "/SUBSYSTEM:WINDOWS,5.01")
SET(MCRECOVER_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,5.01")
ELSE()
# MSVC 2010 or earlier.
SET(MCRECOVER_LINKER_FLAGS_WIN32_EXE "/SUBSYSTEM:WINDOWS,5.00")
SET(MCRECOVER_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,5.00")
ENDIF()
ENDIF()
SET(RP_LINKER_FLAGS_WIN32_EXE "/SUBSYSTEM:WINDOWS,${RP_WIN32_SUBSYSTEM_VERSION}")
SET(RP_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,${RP_WIN32_SUBSYSTEM_VERSION}")
UNSET(RP_WIN32_SUBSYSTEM_VERSION)
# 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}")
SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_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,44 @@
# 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")
# 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")
# 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")
# 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")
# Determine the processorArchitecture for the manifest files.
STRING(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch)
IF(arch MATCHES "^x86_64$|^amd64$")
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "amd64")
ELSEIF(arch MATCHES "^ia64$")
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "ia64")
ELSEIF(arch MATCHES "^(i.|x)86$")
SET(WIN32_MANIFEST_PROCESSOR_ARCHITECTURE "x86")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported CPU architecture, please fix!")
ENDIF()
UNSET(arch)
# Compiler-specific Win32 flags.
IF(MSVC)
INCLUDE(cmake/platform/win32-msvc.cmake)
ELSE(MSVC)
INCLUDE(cmake/platform/win32-gcc.cmake)
ENDIF(MSVC)

373
git_version.sh Executable file
View File

@ -0,0 +1,373 @@
#!/bin/sh
#
# Generate some basic versioning information which can be piped to a header.
#
# Copyright (c) 2006-2007 Luc Verhaegen <libv@skynet.be>
# Copyright (C) 2007-2008 Hans Ulrich Niedermann <hun@n-dimensional.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# This script is based on the one written for xf86-video-unichrome by
# Luc Verhaegen, but was rewritten almost completely by Hans Ulrich
# Niedermann. The script contains a few bug fixes from Egbert Eich,
# Matthias Hopf, Joerg Sonnenberger, and possibly others.
#
# The author thanks the nice people on #git for the assistance.
#
# Simple testing of this script:
# /sbin/busybox sh git_version.sh --example > moo.c \
# && gcc -Wall -Wextra -Wno-unused -o moo moo.c \
# && ./moo
# (bash should also do)
#
# For how to hook this up to your automake- and/or imake-based build
# system, best take a look at how the RadeonHD.am and/or RadeonHD.tmpl
# work in the xf86-video-radeonhd build system. For non-recursive make,
# you can probably make things a little bit simpler.
#
# Requires git >= 1.3.0 for the 'git foo' (with space) syntax,
# and git >= 1.4 for some specific commands.
# Help messages
USAGE="[<option>...]"
LONG_USAGE="\
Options:
-h, --help Print this help message.
-k, --keep-if-no-repo Keep old output file if no git repo found.
-o, --output FILENAME Set output file name.
-q, --quiet Quiet output.
-s, --srcdir DIRNAME Set source tree dir name.
-x, --example Print complete example program."
# The caller may have set these for us
SED="${SED-sed}"
GIT="${GIT-git}"
# Initialize
working_dir=`pwd`
# Who am I?
self=`basename "$0"`
# Defaults
ifndef_symbol="GIT_VERSION_H"
outfile="-"
print_example=false
keep_if_no_repo=no
quiet=false
srcdir=`pwd`
# Parse command line parameter, affecting defaults
while [ "x$1" != "x" ]
do
case "$1" in
-x|--example)
print_example=:
;;
-o|--output)
if shift; then
outfile="$1"
if [ "x$outfile" = "x-" ]; then
: # keep default ifndef_symbol
else
ifndef_symbol=`basename "$outfile" | $SED 's|\.|_|g; s|[^A-Za-z0-9_]||g' | tr a-z A-Z`
fi
else
echo "$self: Fatal: \"$1\" option requires parameter." >&2
exit 1
fi
;;
-q|--quiet)
quiet=:
;;
-h|--help)
echo "Usage: ${self} $USAGE"
[ -n "$LONG_USAGE" ] && echo "$LONG_USAGE"
exit
;;
-k|--keep-if-no-repo)
keep_if_no_repo=yes
;;
-s|--srcdir)
if shift; then
if test -d "$1"; then
srcdir="$1"
else
echo "$self: Fatal: \"$1\" not a directory." >&2
exit 1
fi
else
echo "$self: Fatal: \"$1\" option requires directory parameter." >&2
exit 1
fi
;;
*)
echo "$self: Fatal: Invalid command line paramenter: \"$1\"" >&2
exit 1
;;
esac
shift
done
# If not printing to stdout, redirect stdout to output file?
rename_new_output=false
if [ "x$outfile" = "x-" ]
then
: # keep using stdout
else
exec 1> "${outfile}.new"
fi
# Done with creating output files, so we can change to source dir
abs_srcdir=`cd "$srcdir" && pwd`
cd "$srcdir"
# Write program header
cat<<EOF
/*
* Basic versioning gathered from the git repository.
* Automatically generated by $0.
*/
#ifndef ${ifndef_symbol}
#define ${ifndef_symbol} 1
/* whether this is a dist tarball or not */
#undef GIT_IS_DIST
EOF
# Detect git tool (should work with old and new git versions)
git_found=yes
if [ "x$GIT" = "xgit" ] && [ "x`which $GIT 2>/dev/null`" = "x" ]; then
git_found="'$GIT' not found"
break
fi
# If git_found=yes, we can now use $() substitutions (as git does). Hooray!
# Determine git specific defines
unset git_errors ||:
if [ "x$git_found" = "xyes" ]; then
git_version=`$GIT --version`
if [ "x$git_version" = "x" ]; then
git_errors="${git_errors+${git_errors}; }error running '$GIT --version'"
fi
fi
git_repo=no
# "git-rev-parse --git-dir" since git-0.99.7
git_repo_dir="$($GIT rev-parse --git-dir 2> /dev/null || true)"
abs_repo_dir="$(cd "$git_repo_dir" && pwd)"
# Only accept the found git repo iff it is in our top srcdir, as determined
# by comparing absolute pathnames created by running pwd in the respective dir.
if [ "x$git_repo_dir" != "x" ] && [ "x${abs_repo_dir}" = "x${abs_srcdir}/.git" ]; then
git_repo=yes
if [ "x$git_found" = "xyes" ]; then
# git-1.4 and probably earlier understand "git-rev-parse HEAD"
git_shaid=`$GIT rev-parse HEAD | $SED -n 's/^\(.\{8\}\).*/\1/p'`
if [ "x$git_shaid" = "x" ]; then
git_errors="${git_errors+${git_errors}; }error running '$GIT rev-parse HEAD'"
fi
# git-1.4 and probably earlier understand "git-symbolic-ref HEAD"
git_branch=`$GIT symbolic-ref HEAD | $SED -n 's|^refs/heads/||p'`
if [ "x$git_branch" = "x" ]; then
# This happens, is OK, and "(no branch)" is what "git branch" prints.
git_branch="(no branch)"
fi
git_dirty=yes
# git-1.4 does not understand "git-diff-files --quiet"
# git-1.4 does not understand "git-diff-index --cached --quiet HEAD"
if [ "x$($GIT diff-files)" = "x" ] && [ "x$($GIT diff-index --cached HEAD)" = "x" ]; then
git_dirty=no
fi
# dkorth changes [2013/07/21 10:18 AM EDT]
# Get the current git description.
# (String will be empty if no description is available or if git is too old.)
git_describe=`$GIT describe --abbrev=8`
fi
fi
# Write git specific defines
if [ "x$git_errors" = "x" ]; then
echo "/* No errors occured while running git */"
echo "#undef GIT_ERRORS"
else
echo "/* Some errors occured while running git */"
echo "#define GIT_ERRORS \"${git_errors}\""
fi
echo ""
if [ "x$git_found" = "xyes" ]; then
echo "/* git utilities found */"
echo "#undef GIT_NOT_FOUND"
echo "#define GIT_VERSION \"${git_version}\""
else
echo "/* git utilities not found */"
echo "#define GIT_NOT_FOUND \"${git_found}\""
echo "#undef GIT_VERSION"
fi
echo ""
if :; then # debug output
cat<<EOF
/* The following helps debug why we sometimes do not find ".git/":
* abs_repo_dir="${abs_repo_dir}" (should be "/path/to/.git")
* abs_srcdir="${abs_srcdir}" (absolute top source dir "/path/to")
* git_repo_dir="${git_repo_dir}" (usually ".git" or "/path/to/.git")
* PWD="${PWD}"
* srcdir="${srcdir}"
* working_dir="${working_dir}"
*/
EOF
fi
if [ "x$git_repo" = "xno" ]; then
echo "/* No git repo found, probably building from dist tarball */"
echo "#undef GIT_REPO"
else
echo "/* git repo found */"
echo "#define GIT_REPO 1"
echo ""
if [ "x$git_found" = "xyes" ]; then
echo "/* Git SHA ID of last commit */"
echo "#define GIT_SHAID \"${git_shaid}\""
echo ""
echo "/* Branch this tree is on */"
echo "#define GIT_BRANCH \"$git_branch\""
echo ""
if [ "x$git_describe" = "x" ]; then
echo "/* git-describe: no description available (no tag?) */"
echo "#undef GIT_DESCRIBE"
else
echo "/* git-describe (e.g. tag, number of commits since tag) */"
echo "#define GIT_DESCRIBE \"${git_describe}\""
fi
echo ""
# Any uncommitted changes we should know about?
# Or technically: Are the working tree or index dirty?
if [ "x$git_dirty" = "xno" ]; then
echo "/* SHA-ID uniquely defines the state of this code */"
echo "#undef GIT_DIRTY"
else
echo "/* Local changes might be breaking things */"
echo "#define GIT_DIRTY 1"
fi
fi
fi
# Define a few immediately useful message strings
cat<<EOF
/* Define GIT_MESSAGE such that
* printf("%s: built from %s", argv[0], GIT_MESSAGE);
* forms a proper sentence.
*/
#ifdef GIT_DIRTY
# define GIT_DIRTY_MSG " + changes"
#else /* !GIT_DIRTY */
# define GIT_DIRTY_MSG ""
#endif /* GIT_DIRTY */
#ifdef GIT_ERRORS
# define GIT_ERROR_MSG " with error: " GIT_ERRORS
#else /* !GIT_ERRORS */
# define GIT_ERROR_MSG ""
#endif /* GIT_ERRORS */
#ifdef GIT_IS_DIST
# define GIT_DIST_MSG "dist of "
#else /* !GIT_IS_DIST */
# define GIT_DIST_MSG ""
#endif /* GIT_IS_DIST */
#ifdef GIT_REPO
# ifdef GIT_NOT_FOUND
# define GIT_MESSAGE GIT_DIST_MSG "git sources without git: " GIT_NOT_FOUND
# else /* !GIT_NOT_FOUND */
# define GIT_MESSAGE \\
GIT_DIST_MSG \\
"git branch " GIT_BRANCH ", " \\
"commit " GIT_SHAID GIT_DIRTY_MSG \\
GIT_ERROR_MSG
# endif /* GIT_NOT_FOUND */
#else /* !GIT_REPO */
# define GIT_MESSAGE GIT_DIST_MSG "non-git sources" GIT_ERROR_MSG
#endif /* GIT_REPO */
#endif /* ${ifndef_symbol} */
EOF
# Example program
if "$print_example"
then
cat<<EOF
/* example program demonstrating the use of git_version.sh output */
#include <stdio.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
int main(int argc, char *argv[])
{
const char *const idx = strrchr(argv[0], '/');
const char *const prog = (idx)?(idx+1):(argv[0]);
#ifdef PACKAGE_VERSION
printf("%s: version %s, built from %s\n", prog, PACKAGE_VERSION, GIT_MESSAGE);
#elif defined(GIT_MESSAGE)
printf("%s: built from %s\n", prog, GIT_MESSAGE);
#endif
return 0;
}
EOF
fi
# Change back to working dir for the remaining output file manipulations.
cd "$working_dir"
# If necessary, overwrite outdated output file with new one
if [ "x$outfile" != "x-" ]
then
if [ -f "$outfile" ]; then
if [ "x$keep_if_no_repo" = "xyes" ] && [ "x$git_repo" = "xno" ]; then
"$quiet" || echo "$self: Not a git repo, keeping existing $outfile" >&2
rm -f "$outfile.new"
elif cmp "$outfile" "$outfile.new" > /dev/null; then
"$quiet" || echo "$self: Output is unchanged, keeping $outfile" >&2
rm -f "$outfile.new"
else
echo "$self: Output has changed, updating $outfile" >&2
mv -f "$outfile.new" "$outfile"
fi
else
echo "$self: Output is new file, creating $outfile" >&2
mv -f "$outfile.new" "$outfile"
fi
fi
# THE END.

18
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
PROJECT(src)
# C99 compatibility header for MSVC.
IF(MSVC)
SET(C99_COMPAT_HEADER "-FI${CMAKE_CURRENT_SOURCE_DIR}/c99-compat.msvcrt.h")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C99_COMPAT_HEADER}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C99_COMPAT_HEADER}")
ENDIF(MSVC)
# Check for hidden visibility flags.
INCLUDE(CheckHiddenVisibility)
CHECK_HIDDEN_VISIBILITY()
# Write the version number to config.version.h.
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/config.version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.version.h")
# Source Code subdirectories.
ADD_SUBDIRECTORY(rvthtool)

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

@ -0,0 +1,135 @@
/***************************************************************************
* c99-compat.msvcrt.h: C99 compatibility header. (MSVC) *
* *
* Copyright (c) 2011-2018 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, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#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
/**
* MSVC 2015 added proper support for C99 snprintf().
* Older versions have _snprintf(), which isn't fully compatible,
* but works fine in most cases. The only incompatibility is the
* return value, which is -1 if the string doesn't fit instead of
* the number of characters (minus NULL terminator) required.
*/
/** snprintf(), vsnprintf() **/
#ifdef _MSC_VER
# if _MSC_VER < 1400
/* MSVC 2003 and older. Don't use variadic macros. */
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# elif _MSC_VER < 1900
/* MSVC 2005 through MSVC 2013. Use variadic macros. */
# define snprintf(str, size, format, ...) _snprintf(str, size, format, __VA_ARGS__)
# define vsnprintf(str, size, format, ...) _vsnprintf(str, size, format, __VA_ARGS__)
# endif
#endif /* _MSC_VER */
/**
* 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 defined(_MSC_VER) && _MSC_VER < 1900
# if !defined(__cplusplus)
# define inline __inline
# endif /* !defined(__cplusplus) */
#endif /* defined(_MSC_VER) && _MSC_VER < 1900 */
/** fseeko(), ftello() **/
// On Linux, Large File Support redefines fseeko() and ftello()
// to fseeko64() and ftello64(). fseek() and ftell() are left as-is.
// MSVCRT doesn't have fseeko() or ftello(), so we'll define them
// as _fseeki64() and _ftelli64().
// (NOTE: MinGW-w64 does have fseeko(), ftello(), fseeko64() and
// ftello64(), and it uses the FILE_OFFSET_BITS macro. LFS appears
// to be required on both 32-bit and 64-bit Windows, unlike on Linux
// where it's only required on 32-bit.)
// TODO: Use _fseeki64() and _ftelli64() on MinGW-w64 to avoid
// use of wrapper functions?
#ifdef _MSC_VER
# define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin)
# define ftello(stream) _ftelli64(stream)
#endif /* _MSC_VER */
/** 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.
*/
/** 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 defined(_MSC_VER) && _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 /* defined(_MSC_VER) && _MSC_VER < 1800 */
/** strcasecmp() and related **/
/**
* MSVCRT case-insensitive string comparison functions.
* MinGW-w64 has the ANSI versions, but not the Unicode versions.
*/
#ifdef _MSC_VER
# ifndef strcasecmp
# define strcasecmp(s1, s2) _stricmp(s1, s2)
# endif
# ifndef strncasecmp
# define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
# endif
#endif /* _MSC_VER */
#ifndef wcscasecmp
# define wcscasecmp(s1, s2) _wcsicmp(s1, s2)
#endif
#ifndef wcsncasecmp
# define wcsncasecmp(s1, s2, n) _wcsnicmp(s1, s2, n)
#endif
/** timegm() **/
/**
* Linux, Mac OS X, and other Unix-like operating systems have a
* function timegm() that converts `struct tm` to `time_t`.
*
* MSVCRT's equivalent function is _mkgmtime().
*
* NOTE: timegm() is NOT part of *any* standard!
*/
#ifndef timegm
# define timegm(tm) _mkgmtime(tm)
#endif
#endif /* __C99_COMPAT_MSVCRT_H__ */

43
src/config.version.h.in Normal file
View File

@ -0,0 +1,43 @@
/***************************************************************************
* RVT-H Tool *
* config.version.h.in: Version information. (source file) *
* *
* Copyright (c) 2018 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, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef __RVTHTOOL_CONFIG_VERSION_H__
#define __RVTHTOOL_CONFIG_VERSION_H__
/* Program version. */
#define VERSION_MAJOR @VERSION_MAJOR@
#define VERSION_MINOR @VERSION_MINOR@
#define VERSION_PATCH @VERSION_PATCH@
#define VERSION_DEVEL @VERSION_DEVEL@
#define VERSION_STRING "@VERSION_STRING@"
/* Package dscription. */
#define DESCRIPTION "@DESCRIPTION@"
/* Package name. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Author. */
#define AUTHOR "@AUTHOR@"
/* Installation prefix. */
#define CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#endif /* __RVTHTOOL_CONFIG_VERSION_H__ */

View File

@ -0,0 +1,70 @@
PROJECT(rvthtool)
# Sources and headers.
SET(rvthtool_SRCS main.c)
SET(rvthtool_H)
#########################
# Build the executable. #
#########################
ADD_EXECUTABLE(rvthtool
${rvthtool_SRCS}
${rvthtool_H}
)
IF(NOT MSVC)
TARGET_COMPILE_FEATURES(rvthtool PUBLIC c_std_99)
ENDIF(NOT MSVC)
SET_TARGET_PROPERTIES(rvthtool PROPERTIES PREFIX "")
DO_SPLIT_DEBUG(rvthtool)
SET_WINDOWS_SUBSYSTEM(rvthtool CONSOLE)
SET_WINDOWS_NO_MANIFEST(rvthtool)
# FIXME: setargv isn't necessarily sorted...
# TODO: Implement our own setargv function?
# TODO: Use wmain and Unicode on Windows.
SET_WINDOWS_ENTRYPOINT(rvthtool main ON)
# Include paths:
# - Public: Current source and binary directories.
# - Private: Parent source and binary directories,
# and top-level binary directory for git_version.h.
TARGET_INCLUDE_DIRECTORIES(rvthtool
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
)
# CMake-3.7.2 doesn't add include paths to windres.
IF(MINGW)
SET(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -I \"${CMAKE_CURRENT_SOURCE_DIR}/..\"")
SET(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -I \"${CMAKE_CURRENT_BINARY_DIR}/..\"")
SET(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -I \"${CMAKE_BINARY_DIR}\"")
ENDIF(MINGW)
#################
# Installation. #
#################
INCLUDE(DirInstallPaths)
# NOTE: Don't install libraries.
# That installs the import library, which isn't used
# for shell extensions.
INSTALL(TARGETS rvthtool
RUNTIME DESTINATION "${DIR_INSTALL_EXE}"
LIBRARY DESTINATION "${DIR_INSTALL_DLL}"
#ARCHIVE DESTINATION "${DIR_INSTALL_LIB}"
COMPONENT "program"
)
IF(INSTALL_DEBUG)
# FIXME: Generator expression $<TARGET_PROPERTY:${_target},PDB> didn't work with CPack-3.6.1.
GET_TARGET_PROPERTY(DEBUG_FILENAME rvthtool PDB)
INSTALL(FILES "${DEBUG_FILENAME}"
DESTINATION "${DIR_INSTALL_EXE_DEBUG}"
COMPONENT "debug"
)
UNSET(DEBUG_FILENAME)
ENDIF(INSTALL_DEBUG)

34
src/rvthtool/main.c Normal file
View File

@ -0,0 +1,34 @@
/***************************************************************************
* RVT-H Tool *
* main.c: Main program file. *
* *
* Copyright (c) 2018 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, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "config.version.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
((void)argc);
((void)argv);
printf("RVT-H Tool v" VERSION_STRING "\n"
"Copyright (c) 2018 by David Korth.\n\n");
return EXIT_SUCCESS;
}