CMakeDetermineCXXCompiler.cmake 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # determine the compiler to use for C++ programs
  2. # NOTE, a generator may set CMAKE_CXX_COMPILER before
  3. # loading this file to force a compiler.
  4. # use environment variable CXX first if defined by user, next use
  5. # the cmake variable CMAKE_GENERATOR_CXX which can be defined by a generator
  6. # as a default compiler
  7. # If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used
  8. # as prefix for the tools (e.g. arm-elf-g++, arm-elf-ar etc.)
  9. # It also tries to detect a MS crosscompiler and find out its
  10. # suffix (clarm.exe), which will be stored in _CMAKE_TOOLCHAIN_SUFFIX and
  11. # reused for the C compiler.
  12. #
  13. # Sets the following variables:
  14. # CMAKE_CXX_COMPILER
  15. # CMAKE_COMPILER_IS_GNUCXX
  16. # CMAKE_AR
  17. # CMAKE_RANLIB
  18. #
  19. # If not already set before, it also sets
  20. # _CMAKE_TOOLCHAIN_PREFIX
  21. # _CMAKE_TOOLCHAIN_SUFFIX
  22. IF(NOT CMAKE_CXX_COMPILER)
  23. SET(CMAKE_CXX_COMPILER_INIT NOTFOUND)
  24. # prefer the environment variable CXX
  25. IF($ENV{CXX} MATCHES ".+")
  26. GET_FILENAME_COMPONENT(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
  27. IF(CMAKE_CXX_FLAGS_ENV_INIT)
  28. SET(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
  29. ENDIF(CMAKE_CXX_FLAGS_ENV_INIT)
  30. IF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
  31. MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
  32. ENDIF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
  33. ENDIF($ENV{CXX} MATCHES ".+")
  34. # next prefer the generator specified compiler
  35. IF(CMAKE_GENERATOR_CXX)
  36. IF(NOT CMAKE_CXX_COMPILER_INIT)
  37. SET(CMAKE_CXX_COMPILER_INIT ${CMAKE_GENERATOR_CXX})
  38. ENDIF(NOT CMAKE_CXX_COMPILER_INIT)
  39. ENDIF(CMAKE_GENERATOR_CXX)
  40. # finally list compilers to try
  41. IF(CMAKE_CXX_COMPILER_INIT)
  42. SET(CMAKE_CXX_COMPILER_LIST ${CMAKE_CXX_COMPILER_INIT})
  43. ELSE(CMAKE_CXX_COMPILER_INIT)
  44. SET(CMAKE_CXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl${_CMAKE_TOOLCHAIN_SUFFIX} bcc xlC)
  45. ENDIF(CMAKE_CXX_COMPILER_INIT)
  46. # Find the compiler.
  47. IF (_CMAKE_USER_C_COMPILER_PATH)
  48. FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} PATHS ${_CMAKE_USER_C_COMPILER_PATH} DOC "C++ compiler" NO_DEFAULT_PATH)
  49. ENDIF (_CMAKE_USER_C_COMPILER_PATH)
  50. FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} DOC "C++ compiler")
  51. IF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
  52. SET(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER_INIT}" CACHE FILEPATH "C++ compiler" FORCE)
  53. ENDIF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
  54. ELSE(NOT CMAKE_CXX_COMPILER)
  55. # we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
  56. # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
  57. #
  58. # if a compiler was specified by the user but without path,
  59. # now try to find it with the full path
  60. # if it is found, force it into the cache,
  61. # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
  62. # if the CXX compiler already had a path, reuse it for searching the C compiler
  63. GET_FILENAME_COMPONENT(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
  64. IF(NOT _CMAKE_USER_CXX_COMPILER_PATH)
  65. FIND_PROGRAM(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER})
  66. MARK_AS_ADVANCED(CMAKE_CXX_COMPILER_WITH_PATH)
  67. IF(CMAKE_CXX_COMPILER_WITH_PATH)
  68. SET(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE FILEPATH "CXX compiler" FORCE)
  69. ENDIF(CMAKE_CXX_COMPILER_WITH_PATH)
  70. ENDIF(NOT _CMAKE_USER_CXX_COMPILER_PATH)
  71. ENDIF(NOT CMAKE_CXX_COMPILER)
  72. MARK_AS_ADVANCED(CMAKE_CXX_COMPILER)
  73. IF (NOT _CMAKE_TOOLCHAIN_LOCATION)
  74. GET_FILENAME_COMPONENT(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
  75. ENDIF (NOT _CMAKE_TOOLCHAIN_LOCATION)
  76. # if we have a g++ cross compiler, they have usually some prefix, like
  77. # e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++
  78. # the other tools of the toolchain usually have the same prefix
  79. IF (NOT _CMAKE_TOOLCHAIN_PREFIX)
  80. GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME_WE)
  81. IF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+")
  82. STRING(REGEX REPLACE "^(.+-)[gc]\\+\\+" "\\1" _CMAKE_TOOLCHAIN_PREFIX "${COMPILER_BASENAME}")
  83. ENDIF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+")
  84. ENDIF (NOT _CMAKE_TOOLCHAIN_PREFIX)
  85. # if we have a MS cross compiler, it usually has a suffix, like
  86. # e.g. clarm.exe or clmips.exe. Use this suffix for the CXX compiler too.
  87. IF (NOT _CMAKE_TOOLCHAIN_SUFFIX)
  88. GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
  89. IF (COMPILER_BASENAME MATCHES "^cl(.+)\\.exe$")
  90. STRING(REGEX REPLACE "^cl(.+)\\.exe$" "\\1" _CMAKE_TOOLCHAIN_SUFFIX "${COMPILER_BASENAME}")
  91. ENDIF (COMPILER_BASENAME MATCHES "^cl(.+)\\.exe$")
  92. ENDIF (NOT _CMAKE_TOOLCHAIN_SUFFIX)
  93. # some exotic compilers have different extensions (e.g. sdcc uses .rel)
  94. # so don't overwrite it if it has been already defined by the user
  95. IF(NOT CMAKE_CXX_OUTPUT_EXTENSION)
  96. IF(UNIX)
  97. SET(CMAKE_CXX_OUTPUT_EXTENSION .o)
  98. ELSE(UNIX)
  99. SET(CMAKE_CXX_OUTPUT_EXTENSION .obj)
  100. ENDIF(UNIX)
  101. ENDIF(NOT CMAKE_CXX_OUTPUT_EXTENSION)
  102. # This block was used before the compiler was identified by building a
  103. # source file. Unless g++ crashes when building a small C++
  104. # executable this should no longer be needed.
  105. #
  106. # The g++ that comes with BeOS 5 segfaults if you run "g++ -E"
  107. # ("gcc -E" is fine), which throws up a system dialog box that hangs cmake
  108. # until the user clicks "OK"...so for now, we just assume it's g++.
  109. # IF(BEOS)
  110. # SET(CMAKE_COMPILER_IS_GNUCXX 1)
  111. # SET(CMAKE_COMPILER_IS_GNUCXX_RUN 1)
  112. # ENDIF(BEOS)
  113. # Build a small source file to identify the compiler.
  114. IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
  115. SET(CMAKE_CXX_COMPILER_ID_RUN 1)
  116. SET(CMAKE_CXX_PLATFORM_ID "Windows")
  117. # TODO: Set the compiler id. It is probably MSVC but
  118. # the user may be using an integrated Intel compiler.
  119. # SET(CMAKE_CXX_COMPILER_ID "MSVC")
  120. ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
  121. IF(NOT CMAKE_CXX_COMPILER_ID_RUN)
  122. SET(CMAKE_CXX_COMPILER_ID_RUN 1)
  123. # Try to identify the compiler.
  124. SET(CMAKE_CXX_COMPILER_ID)
  125. INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
  126. CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS ${CMAKE_ROOT}/Modules/CMakeCXXCompilerId.cpp)
  127. # Set old compiler and platform id variables.
  128. IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
  129. SET(CMAKE_COMPILER_IS_GNUCXX 1)
  130. ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
  131. IF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
  132. SET(CMAKE_COMPILER_IS_MINGW 1)
  133. ELSEIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "Cygwin")
  134. SET(CMAKE_COMPILER_IS_CYGWIN 1)
  135. ENDIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
  136. ENDIF(NOT CMAKE_CXX_COMPILER_ID_RUN)
  137. INCLUDE(CMakeFindBinUtils)
  138. # configure all variables set in this file
  139. CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
  140. ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake IMMEDIATE)
  141. SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")