summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2005-10-03 18:44:27 (GMT)
committerBrad King <brad.king@kitware.com>2005-10-03 18:44:27 (GMT)
commitd937de494a87b7d113ac2f16732cde3bbfa0dffd (patch)
tree466834e43cdaf97955ad6fbf259d793767df8ab1 /Source
parentb9e088dcfa4f7e075b809914a95dfa465f00617a (diff)
downloadCMake-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.txt84
-rw-r--r--Source/kwsys/kwsysPlatformCxxTests.cxx87
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