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.
This commit is contained in:
parent
b9e088dcfa
commit
d937de494a
|
@ -254,20 +254,56 @@ IF(UNIX)
|
||||||
ENDIF(UNIX)
|
ENDIF(UNIX)
|
||||||
|
|
||||||
IF(KWSYS_USE_FundamentalType)
|
IF(KWSYS_USE_FundamentalType)
|
||||||
# Determine type sizes.
|
# Load fundamental type information generated by the below try-run.
|
||||||
INCLUDE(CheckTypeSize)
|
IF(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
|
||||||
CHECK_TYPE_SIZE("char" KWSYS_SIZEOF_CHAR)
|
# The file already exists. Load it now.
|
||||||
CHECK_TYPE_SIZE("short" KWSYS_SIZEOF_SHORT)
|
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
|
||||||
CHECK_TYPE_SIZE("int" KWSYS_SIZEOF_INT)
|
ELSE(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FundamentalTypeInfo.cmake)
|
||||||
CHECK_TYPE_SIZE("long" KWSYS_SIZEOF_LONG)
|
# The file does not exist. Try to generate it. All the type
|
||||||
CHECK_TYPE_SIZE("long long" KWSYS_SIZEOF_LONG_LONG)
|
# information can be detected by a single try-run because the
|
||||||
CHECK_TYPE_SIZE("__int64" KWSYS_SIZEOF___INT64)
|
# available types can be determined at compile time. This
|
||||||
IF(NOT KWSYS_SIZEOF_LONG_LONG)
|
# significantly reduces the number of try-compiles and try-runs needed
|
||||||
SET(KWSYS_SIZEOF_LONG_LONG 0)
|
# to collect this information.
|
||||||
ENDIF(NOT KWSYS_SIZEOF_LONG_LONG)
|
MESSAGE(STATUS "Checking C++ fundamental types")
|
||||||
IF(NOT KWSYS_SIZEOF___INT64)
|
|
||||||
SET(KWSYS_SIZEOF___INT64 0)
|
# Pass the output directory in KWSYS_CXX_TYPE_INFO_DIR as a cache
|
||||||
ENDIF(NOT KWSYS_SIZEOF___INT64)
|
# 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.
|
# Check uniqueness of types.
|
||||||
IF(KWSYS_SIZEOF___INT64)
|
IF(KWSYS_SIZEOF___INT64)
|
||||||
|
@ -303,26 +339,6 @@ IF(KWSYS_USE_FundamentalType)
|
||||||
ELSE(KWSYS_USE___INT64)
|
ELSE(KWSYS_USE___INT64)
|
||||||
SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1)
|
SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1)
|
||||||
ENDIF(KWSYS_USE___INT64)
|
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)
|
ENDIF(KWSYS_USE_FundamentalType)
|
||||||
|
|
||||||
IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
|
IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
|
||||||
|
|
|
@ -265,3 +265,90 @@ int main()
|
||||||
return (*reinterpret_cast<char*>(&uc) < 0)?1:0;
|
return (*reinterpret_cast<char*>(&uc) < 0)?1:0;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
|
Loading…
Reference in New Issue