TestBigEndian.cmake 4.5 KB

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