From 74750610cf29e5c0b92feb1f7b8c030e1f0e8448 Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Mon, 4 Jun 2007 17:08:46 -0400 Subject: [PATCH] ENH: determine typesize by compiling a file and reading strings from the compiled output. Tested with various gcc, XCode, MSVC7, sdcc For OSX when doing TRY_COMPILE() CMAKE_OSX_ARCHITECTURES is used, if there are different results an error is generated. CMAKE_OSX_ARCHITECTURES can be overwritten for the TRY_COMPILES with CMAKE_TRY_COMPILE_OSX_ARCHITECTURES. Alex --- Modules/CheckTypeSize.cmake | 126 +++++++++++++++++++--------------- Modules/CheckTypeSizeC.c.in | 46 +++++++++++++ Modules/Platform/Darwin.cmake | 5 -- Source/cmCoreTryCompile.cxx | 27 ++++++-- Source/cmLocalGenerator.cxx | 3 +- 5 files changed, 142 insertions(+), 65 deletions(-) create mode 100644 Modules/CheckTypeSizeC.c.in diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake index a4869a613..7bbc6d214 100644 --- a/Modules/CheckTypeSize.cmake +++ b/Modules/CheckTypeSize.cmake @@ -13,58 +13,76 @@ # CMAKE_REQUIRED_LIBRARIES = list of libraries to link MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) - SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS 1) - IF(NOT DEFINED ${VARIABLE}) - IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") - SET(CHECK_TYPE_SIZE_TYPE "${TYPE}") - SET(MACRO_CHECK_TYPE_SIZE_FLAGS - "${CMAKE_REQUIRED_FLAGS}") - FOREACH(def HAVE_SYS_TYPES_H HAVE_STDINT_H HAVE_STDDEF_H) - IF("${def}") - SET(MACRO_CHECK_TYPE_SIZE_FLAGS - "${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}") - ENDIF("${def}") - ENDFOREACH(def) - SET(CHECK_TYPE_SIZE_PREINCLUDE) - SET(CHECK_TYPE_SIZE_PREMAIN) - FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) - SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n") - ENDFOREACH(def) - CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CheckTypeSize.c.in" - "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" IMMEDIATE @ONLY) - FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" - CHECK_TYPE_SIZE_FILE_CONTENT) - MESSAGE(STATUS "Check size of ${TYPE}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_TYPE_SIZE_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ELSE(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_TYPE_SIZE_ADD_LIBRARIES) - ENDIF(CMAKE_REQUIRED_LIBRARIES) - IF(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_TYPE_SIZE_ADD_INCLUDES - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") - ELSE(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_TYPE_SIZE_ADD_INCLUDES) - ENDIF(CMAKE_REQUIRED_INCLUDES) - TRY_RUN(${VARIABLE} HAVE_${VARIABLE} - ${CMAKE_BINARY_DIR} - "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS} - "${CHECK_TYPE_SIZE_ADD_LIBRARIES}" - "${CHECK_TYPE_SIZE_ADD_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) - IF(HAVE_${VARIABLE}) - MESSAGE(STATUS "Check size of ${TYPE} - done") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n") - ELSE(HAVE_${VARIABLE}) - MESSAGE(STATUS "Check size of ${TYPE} - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n") - ENDIF(HAVE_${VARIABLE}) - ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") - ENDIF(NOT DEFINED ${VARIABLE}) - SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS ) + IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") + MESSAGE(STATUS "Check size of ${TYPE}") + SET(CHECK_TYPE_SIZE_TYPE "${TYPE}") + SET(MACRO_CHECK_TYPE_SIZE_FLAGS + "${CMAKE_REQUIRED_FLAGS}") + FOREACH(def HAVE_SYS_TYPES_H HAVE_STDINT_H HAVE_STDDEF_H) + IF("${def}") + SET(MACRO_CHECK_TYPE_SIZE_FLAGS + "${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}") + ENDIF("${def}") + ENDFOREACH(def) + SET(CHECK_TYPE_SIZE_PREINCLUDE) + SET(CHECK_TYPE_SIZE_PREMAIN) + SET(CHECK_TYPE_SIZE_ADD_LIBRARIES) + SET(CHECK_TYPE_SIZE_ADD_INCLUDES) + + FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) + SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n") + ENDFOREACH(def) + IF(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_TYPE_SIZE_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ENDIF(CMAKE_REQUIRED_LIBRARIES) + IF(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_TYPE_SIZE_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + ENDIF(CMAKE_REQUIRED_INCLUDES) + + CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CheckTypeSizeC.c.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c" IMMEDIATE @ONLY) + FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c" + CHECK_TYPE_SIZE_FILE_CONTENT) + TRY_COMPILE(HAVE_${VARIABLE} + ${CMAKE_BINARY_DIR} + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS} + "${CHECK_TYPE_SIZE_ADD_LIBRARIES}" + "${CHECK_TYPE_SIZE_ADD_INCLUDES}" + OUTPUT_VARIABLE OUTPUT + COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin" ) + + IF(HAVE_${VARIABLE}) +# FILE(HEX_TO_BIN "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin" +# "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.even_more_bin") + FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin" + CMAKE_CHECKTYPESIZE_STRINGS LIMIT_COUNT 2 REGEX "INFO:sizeof") + + SET(CMAKE_CHECKTYPESIZE_FIRST_RESULT "FIRST_LOOP") + FOREACH(info ${CMAKE_CHECKTYPESIZE_STRINGS}) + IF("${info}" MATCHES ".*INFO:sizeof\\[0*([^]]*)\\].*") + STRING(REGEX REPLACE ".*INFO:sizeof\\[0*([^]]*)\\].*" "\\1" ${VARIABLE} "${info}") + ENDIF("${info}" MATCHES ".*INFO:sizeof\\[0*([^]]*)\\].*") + IF("${CMAKE_CHECKTYPESIZE_FIRST_RESULT}" STREQUAL "FIRST_LOOP") + SET(CMAKE_CHECKTYPESIZE_FIRST_RESULT "${${VARIABLE}}") + ENDIF("${CMAKE_CHECKTYPESIZE_FIRST_RESULT}" STREQUAL "FIRST_LOOP") + IF(NOT "${CMAKE_CHECKTYPESIZE_FIRST_RESULT}" STREQUAL "${${VARIABLE}}") + MESSAGE(SEND_ERROR "CHECK_TYPE_SIZE found different results, consider setting CMAKE_OSX_ARCHITECTURES or CMAKE_TRY_COMPILE_OSX_ARCHITECTURES to one or no architecture !") + ENDIF(NOT "${CMAKE_CHECKTYPESIZE_FIRST_RESULT}" STREQUAL "${${VARIABLE}}") + + ENDFOREACH(info ${CMAKE_CHECKTYPESIZE_STRINGS}) + MESSAGE(STATUS "Check size of ${TYPE} - done") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n") + ELSE(HAVE_${VARIABLE}) + MESSAGE(STATUS "Check size of ${TYPE} - failed") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n") + SET(${VARIABLE}) + ENDIF(HAVE_${VARIABLE}) + SET(${VARIABLE} "${${VARIABLE}}" CACHE INTERNAL "Result of CHECK_TYPE_SIZE" FORCE) + ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") ENDMACRO(CHECK_TYPE_SIZE) diff --git a/Modules/CheckTypeSizeC.c.in b/Modules/CheckTypeSizeC.c.in new file mode 100644 index 000000000..f9ff2e72f --- /dev/null +++ b/Modules/CheckTypeSizeC.c.in @@ -0,0 +1,46 @@ +#cmakedefine CHECK_TYPE_SIZE_TYPE @CHECK_TYPE_SIZE_TYPE@ +#ifdef CHECK_TYPE_SIZE_TYPE + +@CHECK_TYPE_SIZE_PREINCLUDE@ +#ifdef HAVE_SYS_TYPES_H +# include +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_STDINT_H +# include +#endif /* HAVE_STDINT_H */ + +#ifdef HAVE_STDDEF_H +# include +#endif /* HAVE_STDDEF_H */ + +@CHECK_TYPE_SIZE_PREMAIN@ + +#include + +#define SIZE (sizeof(@CHECK_TYPE_SIZE_TYPE@)) +const char info_sizeof[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','o','f','[', + ('0' + ((SIZE / 10000)%10)), + ('0' + ((SIZE / 1000)%10)), + ('0' + ((SIZE / 100)%10)), + ('0' + ((SIZE / 10)%10)), + ('0' + (SIZE % 10)), + ']','\0'}; + + +#ifdef __CLASSIC_C__ +int main(){ + int ac; + char*av[]; +#else +int main(int ac, char*av[]){ +#endif + printf("sizeinfo: -%s-\n", info_sizeof); + return (&info_sizeof[0] != &info_sizeof[0]); +} + +#else /* CHECK_TYPE_SIZE_TYPE */ + +# error "CHECK_TYPE_SIZE_TYPE has to specify the type" + +#endif /* CHECK_TYPE_SIZE_TYPE */ diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index 8e5e94964..9aa36af83 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -113,8 +113,3 @@ SET(CMAKE_SYSTEM_APPBUNDLE_PATH INCLUDE(Platform/UnixPaths) SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /sw/include) SET(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} /sw/lib) - -IF(CMAKE_OSX_ARCHITECTURES) - SET(CMAKE_TRY_COMPILE_PLATFORM_OPTIONS "${CMAKE_TRY_COMPILE_PLATFORM_OPTIONS} - SET(CMAKE_OSX_ARCHITECTURES \"${CMAKE_OSX_ARCHITECTURES}\")") -ENDIF(CMAKE_OSX_ARCHITECTURES) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index ee4fe97fb..8abd6905a 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -225,13 +225,30 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv) } fprintf(fout, ")\n"); } - const char* platformOptions = - this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_PLATFORM_OPTIONS"); - if ( platformOptions ) + + /* for the TRY_COMPILEs we want to be able to specify the architecture. + So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set + CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to + have the tests run for each specific architecture. Since + cmLocalGenerator doesn't allow building for "the other" + architecture only via CMAKE_OSX_ARCHITECTURES,use to CMAKE_DO_TRY_COMPILE + to enforce it for this case here. + */ + cmakeFlags.push_back("-DCMAKE_DO_TRY_COMPILE=TRUE"); + if(this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_OSX_ARCHITECTURES")!=0) { - fprintf(fout, "%s\n", platformOptions); + std::string flag="-DCMAKE_OSX_ARCHITECTURES="; + flag += this->Makefile->GetSafeDefinition( + "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES"); + cmakeFlags.push_back(flag); } - + else if (this->Makefile->GetDefinition("CMAKE_OSX_ARCHITECTURES")!=0) + { + std::string flag="-DCMAKE_OSX_ARCHITECTURES="; + flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES"); + cmakeFlags.push_back(flag); + } + fprintf(fout, "ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",source.c_str()); fprintf(fout, "TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n"); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index f831282fe..8f2bcca9b 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1927,7 +1927,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, std::vector archs; cmSystemTools::ExpandListArgument(std::string(osxArch), archs); - if(archs.size() > 1) + if((archs.size() > 1) + || ((archs.size()== 1) && this->Makefile->IsOn("CMAKE_DO_TRY_COMPILE"))) { for( std::vector::iterator i = archs.begin(); i != archs.end(); ++i)