Skip to content
Snippets Groups Projects
Commit f7e092fa authored by Brad King's avatar Brad King
Browse files

ENH: Converting FundamentalType try-compiles into a single try-run. All the...

ENH: Converting FundamentalType try-compiles into a single try-run.  All the information about the existence, size, and signedness of types can be determined in one program thanks to limits.h.
parent e6200f67
No related branches found
No related tags found
No related merge requests found
......@@ -254,20 +254,56 @@ IF(UNIX)
ENDIF(UNIX)
IF(KWSYS_USE_FundamentalType)
# Determine type sizes.
INCLUDE(CheckTypeSize)
CHECK_TYPE_SIZE("char" KWSYS_SIZEOF_CHAR)
CHECK_TYPE_SIZE("short" KWSYS_SIZEOF_SHORT)
CHECK_TYPE_SIZE("int" KWSYS_SIZEOF_INT)
CHECK_TYPE_SIZE("long" KWSYS_SIZEOF_LONG)
CHECK_TYPE_SIZE("long long" KWSYS_SIZEOF_LONG_LONG)
CHECK_TYPE_SIZE("__int64" KWSYS_SIZEOF___INT64)
IF(NOT KWSYS_SIZEOF_LONG_LONG)
SET(KWSYS_SIZEOF_LONG_LONG 0)
ENDIF(NOT KWSYS_SIZEOF_LONG_LONG)
IF(NOT KWSYS_SIZEOF___INT64)
SET(KWSYS_SIZEOF___INT64 0)
ENDIF(NOT KWSYS_SIZEOF___INT64)
# Load fundamental type information generated by the below try-run.
IF(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
# The file already exists. Load it now.
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
ELSE(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
# The file does not exist. Try to generate it. All the type
# information can be detected by a single try-run because the
# available types can be determined at compile time. This
# significantly reduces the number of try-compiles and try-runs needed
# to collect this information.
MESSAGE(STATUS "Checking C++ fundamental types")
# Pass the output directory in KWSYS_CXX_TYPE_INFO_DIR as a cache
# entry to work-around some CMake parsing problems when there are
# spaces in the path (for CMake 2.2.1 and lower). Do not quote
# the definition for VS 7 or 8 to work-around a CMake 2.2.1 and
# lower generator bug.
SET(DOLLAR "$")
IF(CMAKE_GENERATOR MATCHES "Visual Studio [78]")
SET(QUOTE "")
ELSE(CMAKE_GENERATOR MATCHES "Visual Studio [78]")
SET(QUOTE "\"")
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio [78]")
TRY_RUN(KWSYS_CXX_TYPE_INFO KWSYS_CXX_TYPE_INFO_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformCxxTests.cxx
CMAKE_FLAGS
"-DKWSYS_CXX_TYPE_INFO_DIR:STRING=${CMAKE_CURRENT_BINARY_DIR}"
COMPILE_DEFINITIONS
-DTEST_KWSYS_CXX_TYPE_INFO
"-DKWSYS_CXX_TYPE_INFO_FILE=${QUOTE}${DOLLAR}{KWSYS_CXX_TYPE_INFO_DIR}/FundamentalTypeInfo.cmake${QUOTE}"
OUTPUT_VARIABLE OUTPUT
)
# Check if the file now exists.
IF(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
# The file exists. Report success and load it.
MESSAGE(STATUS "Checking C++ fundamental types -- success")
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeOutput.log
"Checking C++ fundamental types compiled with the following output:\n${OUTPUT}\n\n")
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
ELSE(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
# The file does not exist. Report failure.
MESSAGE(STATUS "Checking C++ fundamental types -- failure")
FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeError.log
"Checking C++ fundamental types failed to compile with the following output:\n${OUTPUT}\n\n")
MESSAGE(FATAL_ERROR "Checking C++ fundamental type information failed. "
"Check \"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeError.log\" for more information.")
ENDIF(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
ENDIF(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
# Check uniqueness of types.
IF(KWSYS_SIZEOF___INT64)
......@@ -303,26 +339,6 @@ IF(KWSYS_USE_FundamentalType)
ELSE(KWSYS_USE___INT64)
SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1)
ENDIF(KWSYS_USE___INT64)
# Check signedness of "char" type.
IF("KWSYS_CHAR_IS_SIGNED" MATCHES "^KWSYS_CHAR_IS_SIGNED$")
MESSAGE(STATUS "Checking signedness of char")
TRY_RUN(KWSYS_CHAR_IS_SIGNED KWSYS_CHAR_IS_SIGNED_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformCxxTests.cxx
COMPILE_DEFINITIONS -DTEST_KWSYS_CHAR_IS_SIGNED)
IF(KWSYS_CHAR_IS_SIGNED_COMPILED)
IF(KWSYS_CHAR_IS_SIGNED)
MESSAGE(STATUS "Checking signedness of char -- signed")
SET(KWSYS_CHAR_IS_SIGNED 1 CACHE INTERNAL "Whether char is signed.")
ELSE(KWSYS_CHAR_IS_SIGNED)
MESSAGE(STATUS "Checking signedness of char -- unsigned")
SET(KWSYS_CHAR_IS_SIGNED 0 CACHE INTERNAL "Whether char is signed.")
ENDIF(KWSYS_CHAR_IS_SIGNED)
ELSE(KWSYS_CHAR_IS_SIGNED_COMPILED)
MESSAGE(FATAL_ERROR "Checking signedness of char -- failed")
ENDIF(KWSYS_CHAR_IS_SIGNED_COMPILED)
ENDIF("KWSYS_CHAR_IS_SIGNED" MATCHES "^KWSYS_CHAR_IS_SIGNED$")
ENDIF(KWSYS_USE_FundamentalType)
IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
......
......@@ -265,3 +265,90 @@ int main()
return (*reinterpret_cast<char*>(&uc) < 0)?1:0;
}
#endif
#ifdef TEST_KWSYS_CXX_TYPE_INFO
/* Collect fundamental type information and save it to a CMake script. */
/* Include limits.h to get macros indicating long long and __int64.
Note that certain compilers need special macros to define these
macros in limits.h. */
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
# define _MSC_EXTENSIONS
#endif
#if defined(__GNUC__) && __GNUC__ < 3
# define _GNU_SOURCE
#endif
#include <limits.h>
#include <stdio.h>
#include <string.h>
/* Due to shell differences and limitations of ADD_DEFINITIONS the
KWSYS_CXX_TYPE_INFO_FILE macro will sometimes have double quotes
and sometimes not. This macro will make sure the value is treated
as a double-quoted string. */
#define TO_STRING(x) TO_STRING0(x)
#define TO_STRING0(x) TO_STRING1(x)
#define TO_STRING1(x) #x
void f() {}
int main()
{
/* Construct the output file name. Some preprocessors will add an
extra level of double quotes, so strip them. */
char fbuf[] = TO_STRING(KWSYS_CXX_TYPE_INFO_FILE);
char* fname = fbuf;
if(fname[0] == '"')
{
++fname;
int len = static_cast<int>(strlen(fname));
if(len > 0 && fname[len-1] == '"')
{
fname[len-1] = 0;
}
}
/* Try to open the output file. */
if(FILE* fout = fopen(fname, "w"))
{
/* Set the size of standard types. */
fprintf(fout, "SET(KWSYS_SIZEOF_CHAR %d)\n", static_cast<int>(sizeof(char)));
fprintf(fout, "SET(KWSYS_SIZEOF_SHORT %d)\n", static_cast<int>(sizeof(short)));
fprintf(fout, "SET(KWSYS_SIZEOF_INT %d)\n", static_cast<int>(sizeof(int)));
fprintf(fout, "SET(KWSYS_SIZEOF_LONG %d)\n", static_cast<int>(sizeof(long)));
/* Set the size of some non-standard but common types. */
/* Check for a limits.h macro for long long to see if the type exists. */
#if defined(LLONG_MAX) || defined(LONG_LONG_MAX) || defined(LONGLONG_MAX)
fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG %d)\n", static_cast<int>(sizeof(long long)));
#else
fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG 0) # No long long available.\n");
#endif
/* Check for a limits.h macro for __int64 to see if the type exists. */
#if defined(_I64_MIN)
fprintf(fout, "SET(KWSYS_SIZEOF___INT64 %d)\n", static_cast<int>(sizeof(__int64)));
#else
fprintf(fout, "SET(KWSYS_SIZEOF___INT64 0) # No __int64 available.\n");
#endif
/* Set the size of some pointer types. */
fprintf(fout, "SET(KWSYS_SIZEOF_PDATA %d)\n", static_cast<int>(sizeof(void*)));
fprintf(fout, "SET(KWSYS_SIZEOF_PFUNC %d)\n", static_cast<int>(sizeof(&f)));
/* Set whether the native type "char" is signed or unsigned. */
unsigned char uc = 255;
fprintf(fout, "SET(KWSYS_CHAR_IS_SIGNED %d)\n",
(*reinterpret_cast<char*>(&uc) < 0)?1:0);
fclose(fout);
return 0;
}
else
{
fprintf(stderr, "Failed to write fundamental type info to \"%s\".\n",
fname);
return 1;
}
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment