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
This commit is contained in:
parent
e40c51dddf
commit
74750610cf
|
@ -13,58 +13,76 @@
|
||||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||||
|
|
||||||
MACRO(CHECK_TYPE_SIZE TYPE VARIABLE)
|
MACRO(CHECK_TYPE_SIZE TYPE VARIABLE)
|
||||||
SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS 1)
|
IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
||||||
IF(NOT DEFINED ${VARIABLE})
|
MESSAGE(STATUS "Check size of ${TYPE}")
|
||||||
IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
SET(CHECK_TYPE_SIZE_TYPE "${TYPE}")
|
||||||
SET(CHECK_TYPE_SIZE_TYPE "${TYPE}")
|
SET(MACRO_CHECK_TYPE_SIZE_FLAGS
|
||||||
SET(MACRO_CHECK_TYPE_SIZE_FLAGS
|
"${CMAKE_REQUIRED_FLAGS}")
|
||||||
"${CMAKE_REQUIRED_FLAGS}")
|
FOREACH(def HAVE_SYS_TYPES_H HAVE_STDINT_H HAVE_STDDEF_H)
|
||||||
FOREACH(def HAVE_SYS_TYPES_H HAVE_STDINT_H HAVE_STDDEF_H)
|
IF("${def}")
|
||||||
IF("${def}")
|
SET(MACRO_CHECK_TYPE_SIZE_FLAGS
|
||||||
SET(MACRO_CHECK_TYPE_SIZE_FLAGS
|
"${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}")
|
||||||
"${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}")
|
ENDIF("${def}")
|
||||||
ENDIF("${def}")
|
ENDFOREACH(def)
|
||||||
ENDFOREACH(def)
|
SET(CHECK_TYPE_SIZE_PREINCLUDE)
|
||||||
SET(CHECK_TYPE_SIZE_PREINCLUDE)
|
SET(CHECK_TYPE_SIZE_PREMAIN)
|
||||||
SET(CHECK_TYPE_SIZE_PREMAIN)
|
SET(CHECK_TYPE_SIZE_ADD_LIBRARIES)
|
||||||
FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES})
|
SET(CHECK_TYPE_SIZE_ADD_INCLUDES)
|
||||||
SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n")
|
|
||||||
ENDFOREACH(def)
|
FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES})
|
||||||
CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CheckTypeSize.c.in"
|
SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n")
|
||||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" IMMEDIATE @ONLY)
|
ENDFOREACH(def)
|
||||||
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c"
|
IF(CMAKE_REQUIRED_LIBRARIES)
|
||||||
CHECK_TYPE_SIZE_FILE_CONTENT)
|
SET(CHECK_TYPE_SIZE_ADD_LIBRARIES
|
||||||
MESSAGE(STATUS "Check size of ${TYPE}")
|
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||||
IF(CMAKE_REQUIRED_LIBRARIES)
|
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
||||||
SET(CHECK_TYPE_SIZE_ADD_LIBRARIES
|
IF(CMAKE_REQUIRED_INCLUDES)
|
||||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
SET(CHECK_TYPE_SIZE_ADD_INCLUDES
|
||||||
ELSE(CMAKE_REQUIRED_LIBRARIES)
|
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||||
SET(CHECK_TYPE_SIZE_ADD_LIBRARIES)
|
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
||||||
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
IF(CMAKE_REQUIRED_INCLUDES)
|
CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CheckTypeSizeC.c.in"
|
||||||
SET(CHECK_TYPE_SIZE_ADD_INCLUDES
|
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c" IMMEDIATE @ONLY)
|
||||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c"
|
||||||
ELSE(CMAKE_REQUIRED_INCLUDES)
|
CHECK_TYPE_SIZE_FILE_CONTENT)
|
||||||
SET(CHECK_TYPE_SIZE_ADD_INCLUDES)
|
TRY_COMPILE(HAVE_${VARIABLE}
|
||||||
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
${CMAKE_BINARY_DIR}
|
||||||
TRY_RUN(${VARIABLE} HAVE_${VARIABLE}
|
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c"
|
||||||
${CMAKE_BINARY_DIR}
|
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c"
|
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS}
|
||||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
"${CHECK_TYPE_SIZE_ADD_LIBRARIES}"
|
||||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS}
|
"${CHECK_TYPE_SIZE_ADD_INCLUDES}"
|
||||||
"${CHECK_TYPE_SIZE_ADD_LIBRARIES}"
|
OUTPUT_VARIABLE OUTPUT
|
||||||
"${CHECK_TYPE_SIZE_ADD_INCLUDES}"
|
COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin" )
|
||||||
OUTPUT_VARIABLE OUTPUT)
|
|
||||||
IF(HAVE_${VARIABLE})
|
IF(HAVE_${VARIABLE})
|
||||||
MESSAGE(STATUS "Check size of ${TYPE} - done")
|
# FILE(HEX_TO_BIN "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin"
|
||||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
# "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.even_more_bin")
|
||||||
"Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n")
|
FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize.bin"
|
||||||
ELSE(HAVE_${VARIABLE})
|
CMAKE_CHECKTYPESIZE_STRINGS LIMIT_COUNT 2 REGEX "INFO:sizeof")
|
||||||
MESSAGE(STATUS "Check size of ${TYPE} - failed")
|
|
||||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
SET(CMAKE_CHECKTYPESIZE_FIRST_RESULT "FIRST_LOOP")
|
||||||
"Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n")
|
FOREACH(info ${CMAKE_CHECKTYPESIZE_STRINGS})
|
||||||
ENDIF(HAVE_${VARIABLE})
|
IF("${info}" MATCHES ".*INFO:sizeof\\[0*([^]]*)\\].*")
|
||||||
ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
STRING(REGEX REPLACE ".*INFO:sizeof\\[0*([^]]*)\\].*" "\\1" ${VARIABLE} "${info}")
|
||||||
ENDIF(NOT DEFINED ${VARIABLE})
|
ENDIF("${info}" MATCHES ".*INFO:sizeof\\[0*([^]]*)\\].*")
|
||||||
SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS )
|
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)
|
ENDMACRO(CHECK_TYPE_SIZE)
|
||||||
|
|
|
@ -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 <sys/types.h>
|
||||||
|
#endif /* HAVE_SYS_TYPES_H */
|
||||||
|
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
|
# include <stdint.h>
|
||||||
|
#endif /* HAVE_STDINT_H */
|
||||||
|
|
||||||
|
#ifdef HAVE_STDDEF_H
|
||||||
|
# include <stddef.h>
|
||||||
|
#endif /* HAVE_STDDEF_H */
|
||||||
|
|
||||||
|
@CHECK_TYPE_SIZE_PREMAIN@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#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 */
|
|
@ -113,8 +113,3 @@ SET(CMAKE_SYSTEM_APPBUNDLE_PATH
|
||||||
INCLUDE(Platform/UnixPaths)
|
INCLUDE(Platform/UnixPaths)
|
||||||
SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /sw/include)
|
SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /sw/include)
|
||||||
SET(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} /sw/lib)
|
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)
|
|
||||||
|
|
|
@ -225,13 +225,30 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
||||||
}
|
}
|
||||||
fprintf(fout, ")\n");
|
fprintf(fout, ")\n");
|
||||||
}
|
}
|
||||||
const char* platformOptions =
|
|
||||||
this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_PLATFORM_OPTIONS");
|
/* for the TRY_COMPILEs we want to be able to specify the architecture.
|
||||||
if ( platformOptions )
|
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, "ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",source.c_str());
|
||||||
fprintf(fout,
|
fprintf(fout,
|
||||||
"TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n");
|
"TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n");
|
||||||
|
|
|
@ -1927,7 +1927,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
|
||||||
std::vector<std::string> archs;
|
std::vector<std::string> archs;
|
||||||
cmSystemTools::ExpandListArgument(std::string(osxArch),
|
cmSystemTools::ExpandListArgument(std::string(osxArch),
|
||||||
archs);
|
archs);
|
||||||
if(archs.size() > 1)
|
if((archs.size() > 1)
|
||||||
|
|| ((archs.size()== 1) && this->Makefile->IsOn("CMAKE_DO_TRY_COMPILE")))
|
||||||
{
|
{
|
||||||
for( std::vector<std::string>::iterator i = archs.begin();
|
for( std::vector<std::string>::iterator i = archs.begin();
|
||||||
i != archs.end(); ++i)
|
i != archs.end(); ++i)
|
||||||
|
|
Loading…
Reference in New Issue