diff options
author | Brad King <brad.king@kitware.com> | 2005-10-03 18:44:27 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2005-10-03 18:44:27 (GMT) |
commit | d937de494a87b7d113ac2f16732cde3bbfa0dffd (patch) | |
tree | 466834e43cdaf97955ad6fbf259d793767df8ab1 /Source | |
parent | b9e088dcfa4f7e075b809914a95dfa465f00617a (diff) | |
download | CMake-d937de494a87b7d113ac2f16732cde3bbfa0dffd.zip CMake-d937de494a87b7d113ac2f16732cde3bbfa0dffd.tar.gz CMake-d937de494a87b7d113ac2f16732cde3bbfa0dffd.tar.bz2 |
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.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/kwsys/CMakeLists.txt | 84 | ||||
-rw-r--r-- | Source/kwsys/kwsysPlatformCxxTests.cxx | 87 |
2 files changed, 137 insertions, 34 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index bdb3fb3..2ff2740 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -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$") diff --git a/Source/kwsys/kwsysPlatformCxxTests.cxx b/Source/kwsys/kwsysPlatformCxxTests.cxx index 4187bcc..77e0d1c 100644 --- a/Source/kwsys/kwsysPlatformCxxTests.cxx +++ b/Source/kwsys/kwsysPlatformCxxTests.cxx @@ -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 |