It's safer not to use an unofficial CMake script.
include(CheckTypeSize)
include(CheckCXXSourceCompiles)
include(TestBigEndian)
-include(TestFloatFormat)
# Check if the size of numeric types are suitable.
set(SYSTEM_BYTEORDER 2)
endif()
-# Check if the format of floating point types are suitable.
-
-test_float_format(FP_IEEE754)
-if(${FP_IEEE754} EQUAL 1)
- set(FLOAT_BYTEORDER 1)
-elseif(${FP_IEEE754} EQUAL 2)
- set(FLOAT_BYTEORDER 2)
-else()
- message(FATAL_ERROR "TagLib requires that floating point types are IEEE754 compliant.")
-endif()
-
# Determine which kind of atomic operations your compiler supports.
check_cxx_source_compiles("
+++ /dev/null
-int main(int argc, char **argv)
-{
- int ret = 0;
-
- double bin1[] = {
- // "*TAGLIB*" encoded as a little-endian floating-point number
- (double)3.9865557444897601e-105, (double)0.0
- };
- float bin2[] = {
- // "*TL*" encoded as a little-endian floating-point number
- (float)1.81480400e-013, (float)0.0
- };
- ret += ((int*)bin1)[argc];
- ret += ((int*)bin2)[argc];
-
- return ret;
-}
+++ /dev/null
-# Returns 1 if IEEE754 little-endian, 2 if IEEE754 big-endian, otherwise 0.
-
-MACRO(TEST_FLOAT_FORMAT FP_IEEE754)
- IF(NOT FP_IEEE754)
- TRY_COMPILE(HAVE_FLOAT_FORMAT_BIN
- "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/TestFloatFormat.c"
- COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestFloatFormat.bin")
-
- SET(FP_IEEE754 0)
-
- IF(HAVE_FLOAT_FORMAT_BIN)
-
- # dont match first/last letter because of string rounding errors :-)
- FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestFloatFormat.bin"
- DOUBLE_IEEE754_LE LIMIT_COUNT 1 REGEX "TAGLIB")
- FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestFloatFormat.bin"
- DOUBLE_IEEE754_BE LIMIT_COUNT 1 REGEX "BILGAT")
- FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestFloatFormat.bin"
- FLOAT_IEEE754_LE LIMIT_COUNT 1 REGEX "TL")
- FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestFloatFormat.bin"
- FLOAT_IEEE754_BE LIMIT_COUNT 1 REGEX "LT")
-
- IF(DOUBLE_IEEE754_LE AND FLOAT_IEEE754_LE)
- SET(FP_IEEE754_LE 1)
- ENDIF()
-
- IF(DOUBLE_IEEE754_BE AND FLOAT_IEEE754_BE)
- SET(FP_IEEE754_BE 1)
- ENDIF()
-
- # OS X Universal binaries will contain both strings, set it to the host
- IF(FP_IEEE754_LE AND FP_IEEE754_BE)
- IF(CMAKE_SYSTEM_PROCESSOR MATCHES powerpc)
- SET(FP_IEEE754_LE FALSE)
- SET(FP_IEEE754_BE TRUE)
- ELSE()
- SET(FP_IEEE754_LE TRUE)
- SET(FP_IEEE754_BE FALSE)
- ENDIF()
- ENDIF()
-
- IF(FP_IEEE754_LE)
- SET(FP_IEEE754 1)
- ELSEIF(FP_IEEE754_BE)
- SET(FP_IEEE754 2)
- ENDIF()
- ENDIF()
-
- # just some informational output for the user
- IF(FP_IEEE754_LE)
- MESSAGE(STATUS "Checking the floating point format - IEEE754 (LittleEndian)")
- ELSEIF(FP_IEEE754_BE)
- MESSAGE(STATUS "Checking the floating point format - IEEE754 (BigEndian)")
- ELSE()
- MESSAGE(STATUS "Checking the floating point format - Not IEEE754 or failed to detect.")
- ENDIF()
-
- SET(FP_IEEE754 "${${FP_IEEE754}}" CACHE INTERNAL "Result of TEST_FLOAT_FORMAT" FORCE)
- ENDIF()
-ENDMACRO(TEST_FLOAT_FORMAT FP_IEEE754)
-
/* 1 if little-endian, 2 if big-endian. */
#cmakedefine SYSTEM_BYTEORDER ${SYSTEM_BYTEORDER}
-/* IEEE754 byte order of your target system. */
-/* 1 if little-endian, 2 if big-endian. */
-#cmakedefine FLOAT_BYTEORDER ${FLOAT_BYTEORDER}
-
/* Defined if your compiler supports some byte swap functions */
#cmakedefine HAVE_GCC_BYTESWAP_16 1
#cmakedefine HAVE_GCC_BYTESWAP_32 1
} tmp;
::memcpy(&tmp, v.data() + offset, sizeof(TInt));
- if(ENDIAN != Utils::FloatByteOrder)
+ if(ENDIAN != Utils::floatByteOrder())
tmp.i = Utils::byteSwap(tmp.i);
return tmp.f;
} tmp;
tmp.f = value;
- if(ENDIAN != Utils::FloatByteOrder)
+ if(ENDIAN != Utils::floatByteOrder())
tmp.i = Utils::byteSwap(tmp.i);
return ByteVector(reinterpret_cast<char *>(&tmp), sizeof(TInt));
#endif
-#ifdef FLOAT_BYTEORDER
-
-# if FLOAT_BYTEORDER == 1
-
- const ByteOrder FloatByteOrder = LittleEndian;
-
-# else
-
- const ByteOrder FloatByteOrder = BigEndian;
-
-# endif
-
-#else
-
+ /*!
+ * Returns the IEEE754 byte order of the system.
+ */
inline ByteOrder floatByteOrder()
{
- double bin[] = {
- // "*TAGLIB*" encoded as a little-endian floating-point number
- (double) 3.9865557444897601e-105, (double) 0.0
- };
-
- char *str = (char*)&bin[0];
- if(strncmp(&str[1], "TAGLIB", 6) == 0)
- return LittleEndian;
- else
- return BigEndian;
- }
+ union {
+ double d;
+ char c;
+ } u;
- const ByteOrder FloatByteOrder = floatByteOrder();
+ // 1.0 is stored in memory like 0x3FF0000000000000 in canonical form.
+ // So the first byte is zero if little endian.
+
+ u.d = 1.0;
+ if(u.c == 0)
+ return LittleEndian;
+ else
+ return BigEndian;
+ }
-#endif
}
}