TestBigEndian.cmake 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. TestBigEndian
  5. -------------
  6. Define macro to determine endian type
  7. Check if the system is big endian or little endian
  8. ::
  9. TEST_BIG_ENDIAN(VARIABLE)
  10. VARIABLE - variable to store the result to
  11. #]=======================================================================]
  12. include(CheckTypeSize)
  13. macro(TEST_BIG_ENDIAN VARIABLE)
  14. if(NOT DEFINED HAVE_${VARIABLE})
  15. message(STATUS "Check if the system is big endian")
  16. message(STATUS "Searching 16 bit integer")
  17. if(CMAKE_C_COMPILER_LOADED)
  18. set(_test_language "C")
  19. elseif(CMAKE_CXX_COMPILER_LOADED)
  20. set(_test_language "CXX")
  21. else()
  22. message(FATAL_ERROR "TEST_BIG_ENDIAN needs either C or CXX language enabled")
  23. endif()
  24. CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT LANGUAGE ${_test_language})
  25. if(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
  26. message(STATUS "Using unsigned short")
  27. set(CMAKE_16BIT_TYPE "unsigned short")
  28. else()
  29. CHECK_TYPE_SIZE("unsigned int" CMAKE_SIZEOF_UNSIGNED_INT LANGUAGE ${_test_language})
  30. if(CMAKE_SIZEOF_UNSIGNED_INT)
  31. message(STATUS "Using unsigned int")
  32. set(CMAKE_16BIT_TYPE "unsigned int")
  33. else()
  34. CHECK_TYPE_SIZE("unsigned long" CMAKE_SIZEOF_UNSIGNED_LONG LANGUAGE ${_test_language})
  35. if(CMAKE_SIZEOF_UNSIGNED_LONG)
  36. message(STATUS "Using unsigned long")
  37. set(CMAKE_16BIT_TYPE "unsigned long")
  38. else()
  39. message(FATAL_ERROR "no suitable type found")
  40. endif()
  41. endif()
  42. endif()
  43. if(_test_language STREQUAL "CXX")
  44. set(_test_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.cpp")
  45. else()
  46. set(_test_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c")
  47. endif()
  48. configure_file("${CMAKE_ROOT}/Modules/TestEndianess.c.in"
  49. ${_test_file}
  50. @ONLY)
  51. file(READ ${_test_file} TEST_ENDIANESS_FILE_CONTENT)
  52. try_compile(HAVE_${VARIABLE}
  53. "${CMAKE_BINARY_DIR}"
  54. ${_test_file}
  55. OUTPUT_VARIABLE OUTPUT
  56. COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin" )
  57. if(HAVE_${VARIABLE})
  58. file(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin"
  59. CMAKE_TEST_ENDIANESS_STRINGS_LE LIMIT_COUNT 1 REGEX "THIS IS LITTLE ENDIAN")
  60. file(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin"
  61. CMAKE_TEST_ENDIANESS_STRINGS_BE LIMIT_COUNT 1 REGEX "THIS IS BIG ENDIAN")
  62. # on mac, if there are universal binaries built both will be true
  63. # return the result depending on the machine on which cmake runs
  64. if(CMAKE_TEST_ENDIANESS_STRINGS_BE AND CMAKE_TEST_ENDIANESS_STRINGS_LE)
  65. if(CMAKE_SYSTEM_PROCESSOR MATCHES powerpc)
  66. set(CMAKE_TEST_ENDIANESS_STRINGS_BE TRUE)
  67. set(CMAKE_TEST_ENDIANESS_STRINGS_LE FALSE)
  68. else()
  69. set(CMAKE_TEST_ENDIANESS_STRINGS_BE FALSE)
  70. set(CMAKE_TEST_ENDIANESS_STRINGS_LE TRUE)
  71. endif()
  72. message(STATUS "TEST_BIG_ENDIAN found different results, consider setting CMAKE_OSX_ARCHITECTURES or CMAKE_TRY_COMPILE_OSX_ARCHITECTURES to one or no architecture !")
  73. endif()
  74. if(CMAKE_TEST_ENDIANESS_STRINGS_LE)
  75. set(${VARIABLE} 0 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
  76. message(STATUS "Check if the system is big endian - little endian")
  77. endif()
  78. if(CMAKE_TEST_ENDIANESS_STRINGS_BE)
  79. set(${VARIABLE} 1 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
  80. message(STATUS "Check if the system is big endian - big endian")
  81. endif()
  82. if(NOT CMAKE_TEST_ENDIANESS_STRINGS_BE AND NOT CMAKE_TEST_ENDIANESS_STRINGS_LE)
  83. message(SEND_ERROR "TEST_BIG_ENDIAN found no result!")
  84. endif()
  85. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  86. "Determining if the system is big endian passed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
  87. else()
  88. message(STATUS "Check if the system is big endian - failed")
  89. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
  90. "Determining if the system is big endian failed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
  91. set(${VARIABLE})
  92. endif()
  93. endif()
  94. endmacro()