ENH: Generalize the check for sizeof void* to detect more ABI information.

This commit is contained in:
Brad King 2008-01-21 18:30:17 -05:00
parent 19d22f6105
commit a28b197b11
9 changed files with 188 additions and 14 deletions

View File

@ -23,6 +23,14 @@ SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
SET(CMAKE_C_LINKER_PREFERENCE 10)
# save the size of void* in case where cache is removed
# and the this file is still around
SET(CMAKE_SIZEOF_VOID_P @CMAKE_SIZEOF_VOID_P@)
# Save compiler ABI information.
SET(CMAKE_C_SIZEOF_DATA_PTR "@CMAKE_C_SIZEOF_DATA_PTR@")
SET(CMAKE_C_COMPILER_ABI "@CMAKE_C_COMPILER_ABI@")
IF(CMAKE_C_SIZEOF_DATA_PTR)
SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
ENDIF(CMAKE_C_SIZEOF_DATA_PTR)
IF(CMAKE_C_COMPILER_ABI)
SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
ENDIF(CMAKE_C_COMPILER_ABI)

View File

@ -0,0 +1,28 @@
#ifdef __cplusplus
# error "A C++ compiler has been selected for C."
#endif
#ifdef __CLASSIC_C__
# define const
#endif
/*--------------------------------------------------------------------------*/
#include "CMakeCompilerABI.h"
/*--------------------------------------------------------------------------*/
/* Make sure the information strings are referenced. */
#define REQUIRE(x) (&x[0] != &require)
int main()
{
const char require = 0;
return
(
REQUIRE(info_sizeof_dptr)
#if defined(ABI_ID)
&& REQUIRE(info_abi)
#endif
);
}

View File

@ -23,6 +23,14 @@ SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;H;o;O;obj;OBJ;def;DEF;rc;RC)
SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm)
SET(CMAKE_CXX_LINKER_PREFERENCE 30)
# save the size of void* in case where cache is removed
# and the this file is still around
SET(CMAKE_SIZEOF_VOID_P @CMAKE_SIZEOF_VOID_P@)
# Save compiler ABI information.
SET(CMAKE_CXX_SIZEOF_DATA_PTR "@CMAKE_CXX_SIZEOF_DATA_PTR@")
SET(CMAKE_CXX_COMPILER_ABI "@CMAKE_CXX_COMPILER_ABI@")
IF(CMAKE_CXX_SIZEOF_DATA_PTR)
SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR)
IF(CMAKE_CXX_COMPILER_ABI)
SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
ENDIF(CMAKE_CXX_COMPILER_ABI)

View File

@ -0,0 +1,24 @@
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
/*--------------------------------------------------------------------------*/
#include "CMakeCompilerABI.h"
/*--------------------------------------------------------------------------*/
/* Make sure the information strings are referenced. */
#define REQUIRE(x) (&x[0] != &require)
int main()
{
const char require = 0;
return
(
REQUIRE(info_sizeof_dptr)
#if defined(ABI_ID)
&& REQUIRE(info_abi)
#endif
);
}

View File

@ -0,0 +1,26 @@
/*--------------------------------------------------------------------------*/
/* Size of a pointer-to-data in bytes. */
#define SIZEOF_DPTR (sizeof(void*))
const char info_sizeof_dptr[] = {
'I', 'N', 'F', 'O', ':', 's', 'i', 'z', 'e', 'o', 'f', '_', 'd', 'p', 't', 'r', '[',
('0' + ((SIZEOF_DPTR / 10)%10)),
('0' + (SIZEOF_DPTR % 10)),
']','\0'};
/*--------------------------------------------------------------------------*/
/* Application Binary Interface. */
#if defined(__sgi) && defined(_ABIO32)
# define ABI_ID "ELF O32"
#elif defined(__sgi) && defined(_ABIN32)
# define ABI_ID "ELF N32"
#elif defined(__sgi) && defined(_ABI64)
# define ABI_ID "ELF 64"
#elif defined(__ELF__)
# define ABI_ID "ELF"
#endif
#if defined(ABI_ID)
static char const info_abi[] = "INFO:abi[" ABI_ID "]";
#endif

View File

@ -0,0 +1,49 @@
# Function to compile a source file to identify the compiler ABI.
# This is used internally by CMake and should not be included by user
# code.
FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
IF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
MESSAGE(STATUS "Detecting ${lang} compiler info")
# Compile the ABI identification source.
SET(BIN "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeDetermineCompilerABI_${lang}.bin")
TRY_COMPILE(CMAKE_DETERMINE_${lang}_ABI_COMPILED
${CMAKE_BINARY_DIR} ${src}
OUTPUT_VARIABLE OUTPUT
COPY_FILE "${BIN}"
)
# Load the resulting information strings.
IF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
MESSAGE(STATUS "Detecting ${lang} compiler info - done")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Detecting ${lang} compiler info compiled with the following output:\n${OUTPUT}\n\n")
FILE(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[^[]*\\[")
FOREACH(info ${ABI_STRINGS})
IF("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
STRING(REGEX REPLACE ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*" "\\1" ABI_SIZEOF_DPTR "${info}")
ENDIF("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
IF("${info}" MATCHES ".*INFO:abi\\[([^]]*)\\].*")
STRING(REGEX REPLACE ".*INFO:abi\\[([^]]*)\\].*" "\\1" ABI_NAME "${info}")
ENDIF("${info}" MATCHES ".*INFO:abi\\[([^]]*)\\].*")
ENDFOREACH(info)
IF(ABI_SIZEOF_DPTR)
SET(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
SET(CMAKE_SIZEOF_VOID_P "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
ENDIF(ABI_SIZEOF_DPTR)
IF(ABI_NAME)
SET(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
SET(CMAKE_INTERNAL_PLATFORM_ABI "${ABI_NAME}" PARENT_SCOPE)
ENDIF(ABI_NAME)
ELSE(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
MESSAGE(STATUS "Detecting ${lang} compiler info - failed")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting ${lang} compiler info failed to compile with the following output:\n${OUTPUT}\n\n")
ENDIF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
ENDIF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ABI)

View File

@ -40,14 +40,15 @@ ELSE(NOT CMAKE_C_COMPILER_WORKS)
"Determining if the C compiler works passed with "
"the following output:\n${OUTPUT}\n\n")
ENDIF(C_TEST_WAS_RUN)
INCLUDE (${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)
# Check the size of void*. This used to be "void *" but icc expands the *.
CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P)
SET(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "")
# re-configure this file CMakeCCompiler.cmake so that it gets
# the value for CMAKE_SIZEOF_VOID_P
# configure variables set in this file for fast reload later on
CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake IMMEDIATE)
# Try to identify the ABI and configure it into CMakeCCompiler.cmake
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
CONFIGURE_FILE(
${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake
@ONLY
)
ENDIF(NOT CMAKE_C_COMPILER_WORKS)

View File

@ -34,4 +34,13 @@ ELSE(NOT CMAKE_CXX_COMPILER_WORKS)
"the following output:\n${OUTPUT}\n\n")
ENDIF(CXX_TEST_WAS_RUN)
SET(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "")
# Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
CONFIGURE_FILE(
${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake
@ONLY
)
ENDIF(NOT CMAKE_CXX_COMPILER_WORKS)

View File

@ -839,6 +839,27 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
false,
"Variables for Languages");
cm->DefineProperty
("CMAKE_<LANG>_COMPILER_ABI", cmProperty::VARIABLE,
"An internal variable subject to change.",
"This is used in determining the compiler ABI and is subject to change.",
false,
"Variables for Languages");
cm->DefineProperty
("CMAKE_INTERNAL_PLATFORM_ABI", cmProperty::VARIABLE,
"An internal variable subject to change.",
"This is used in determining the compiler ABI and is subject to change.",
false,
"Variables for Languages");
cm->DefineProperty
("CMAKE_<LANG>_SIZEOF_DATA_PTR", cmProperty::VARIABLE,
"An internal variable subject to change.",
"This is used in determining the architecture and is subject to change.",
false,
"Variables for Languages");
cm->DefineProperty
("CMAKE_COMPILER_IS_GNU<LANG>", cmProperty::VARIABLE,
"True if the compiler is GNU.",