CMakeDetermineCXXCompiler.cmake 8.04 KB
Newer Older
1

2
3
4
5
6
7
8
9
10
11
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
12
# (To distribute this file outside of CMake, substitute the full
13
14
#  License text for the above reference.)

Bill Hoffman's avatar
Bill Hoffman committed
15
16
17
# determine the compiler to use for C++ programs
# NOTE, a generator may set CMAKE_CXX_COMPILER before
# loading this file to force a compiler.
18
19
20
# use environment variable CXX first if defined by user, next use 
# the cmake variable CMAKE_GENERATOR_CXX which can be defined by a generator
# as a default compiler
Alexander Neundorf's avatar
 
Alexander Neundorf committed
21
22
# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used 
# as prefix for the tools (e.g. arm-elf-g++, arm-elf-ar etc.)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
23
24
25
26
27
28
#
# Sets the following variables:
#   CMAKE_CXX_COMPILER
#   CMAKE_COMPILER_IS_GNUCXX
#   CMAKE_AR
#   CMAKE_RANLIB
Alexander Neundorf's avatar
 
Alexander Neundorf committed
29
30
31
#
# If not already set before, it also sets
#   _CMAKE_TOOLCHAIN_PREFIX
Bill Hoffman's avatar
Bill Hoffman committed
32

Bill Hoffman's avatar
Bill Hoffman committed
33
IF(NOT CMAKE_CXX_COMPILER)
34
35
  SET(CMAKE_CXX_COMPILER_INIT NOTFOUND)

Bill Hoffman's avatar
Bill Hoffman committed
36
  # prefer the environment variable CXX
Bill Hoffman's avatar
Bill Hoffman committed
37
  IF($ENV{CXX} MATCHES ".+")
38
    GET_FILENAME_COMPONENT(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
39
    IF(CMAKE_CXX_FLAGS_ENV_INIT)
40
      SET(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
41
    ENDIF(CMAKE_CXX_FLAGS_ENV_INIT)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
42
    IF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
43
      MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
Alexander Neundorf's avatar
 
Alexander Neundorf committed
44
    ENDIF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
45
46
  ENDIF($ENV{CXX} MATCHES ".+")

Bill Hoffman's avatar
Bill Hoffman committed
47
  # next prefer the generator specified compiler
48
49
50
51
52
53
  IF(CMAKE_GENERATOR_CXX)
    IF(NOT CMAKE_CXX_COMPILER_INIT)
      SET(CMAKE_CXX_COMPILER_INIT ${CMAKE_GENERATOR_CXX})
    ENDIF(NOT CMAKE_CXX_COMPILER_INIT)
  ENDIF(CMAKE_GENERATOR_CXX)

54
55
56
57
  # finally list compilers to try
  IF(CMAKE_CXX_COMPILER_INIT)
    SET(CMAKE_CXX_COMPILER_LIST ${CMAKE_CXX_COMPILER_INIT})
  ELSE(CMAKE_CXX_COMPILER_INIT)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
58
    SET(CMAKE_CXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl bcc xlC)
59
60
61
  ENDIF(CMAKE_CXX_COMPILER_INIT)

  # Find the compiler.
Alexander Neundorf's avatar
 
Alexander Neundorf committed
62
63
64
  IF (_CMAKE_USER_C_COMPILER_PATH)
    FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} PATHS ${_CMAKE_USER_C_COMPILER_PATH} DOC "C++ compiler" NO_DEFAULT_PATH)
  ENDIF (_CMAKE_USER_C_COMPILER_PATH)
65
  FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} DOC "C++ compiler")
Alexander Neundorf's avatar
 
Alexander Neundorf committed
66
  
67
68
69
  IF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
    SET(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER_INIT}" CACHE FILEPATH "C++ compiler" FORCE)
  ENDIF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
70
71
ELSE(NOT CMAKE_CXX_COMPILER)

Alexander Neundorf's avatar
 
Alexander Neundorf committed
72
73
74
# we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
# (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
#
Alexander Neundorf's avatar
 
Alexander Neundorf committed
75
76
77
78
79
80
81
82
83
# if CMAKE_CXX_COMPILER is a list of length 2, use the first item as 
# CMAKE_CXX_COMPILER and the 2nd one as CMAKE_CXX_COMPILER_ARG1

  LIST(LENGTH CMAKE_CXX_COMPILER _CMAKE_CXX_COMPILER_LIST_LENGTH)
  IF("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)
    LIST(GET CMAKE_CXX_COMPILER 1 CMAKE_CXX_COMPILER_ARG1)
    LIST(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER)
  ENDIF("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)

Alexander Neundorf's avatar
 
Alexander Neundorf committed
84
# if a compiler was specified by the user but without path, 
Alexander Neundorf's avatar
 
Alexander Neundorf committed
85
86
87
88
# now try to find it with the full path
# if it is found, force it into the cache, 
# if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
# if the CXX compiler already had a path, reuse it for searching the C compiler
Alexander Neundorf's avatar
 
Alexander Neundorf committed
89
90
91
92
  GET_FILENAME_COMPONENT(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
  IF(NOT _CMAKE_USER_CXX_COMPILER_PATH)
    FIND_PROGRAM(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER})
    MARK_AS_ADVANCED(CMAKE_CXX_COMPILER_WITH_PATH)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
93
    IF(CMAKE_CXX_COMPILER_WITH_PATH)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
94
      SET(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE STRING "CXX compiler" FORCE)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
95
    ENDIF(CMAKE_CXX_COMPILER_WITH_PATH)
Alexander Neundorf's avatar
 
Alexander Neundorf committed
96
  ENDIF(NOT _CMAKE_USER_CXX_COMPILER_PATH)
Bill Hoffman's avatar
Bill Hoffman committed
97
98
ENDIF(NOT CMAKE_CXX_COMPILER)
MARK_AS_ADVANCED(CMAKE_CXX_COMPILER)
Bill Hoffman's avatar
Bill Hoffman committed
99

Alexander Neundorf's avatar
 
Alexander Neundorf committed
100
101
102
103
IF (NOT _CMAKE_TOOLCHAIN_LOCATION)
  GET_FILENAME_COMPONENT(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
ENDIF (NOT _CMAKE_TOOLCHAIN_LOCATION)

104
105
106
107
# This block was used before the compiler was identified by building a
# source file.  Unless g++ crashes when building a small C++
# executable this should no longer be needed.
#
108
109
110
# The g++ that comes with BeOS 5 segfaults if you run "g++ -E"
#  ("gcc -E" is fine), which throws up a system dialog box that hangs cmake
#  until the user clicks "OK"...so for now, we just assume it's g++.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# IF(BEOS)
#   SET(CMAKE_COMPILER_IS_GNUCXX 1)
#   SET(CMAKE_COMPILER_IS_GNUCXX_RUN 1)
# ENDIF(BEOS)

# Build a small source file to identify the compiler.
IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
  SET(CMAKE_CXX_COMPILER_ID_RUN 1)
  SET(CMAKE_CXX_PLATFORM_ID "Windows")

  # TODO: Set the compiler id.  It is probably MSVC but
  # the user may be using an integrated Intel compiler.
  # SET(CMAKE_CXX_COMPILER_ID "MSVC")
ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
IF(NOT CMAKE_CXX_COMPILER_ID_RUN)
  SET(CMAKE_CXX_COMPILER_ID_RUN 1)

128
129
130
131
132
133
134
135
  # Each entry in this list is a set of extra flags to try
  # adding to the compile line to see if it helps produce
  # a valid identification file.
  SET(CMAKE_CXX_COMPILER_ID_TEST_FLAGS
    # Try compiling to an object file only.
    "-c"
    )

136
137
  # Try to identify the compiler.
  SET(CMAKE_CXX_COMPILER_ID)
138
139
  FILE(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
    CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
140
  INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
141
  CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
142
143
144
145
146
147
148
149
150
151
152

  # Set old compiler and platform id variables.
  IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
    SET(CMAKE_COMPILER_IS_GNUCXX 1)
  ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
  IF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
    SET(CMAKE_COMPILER_IS_MINGW 1)
  ELSEIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "Cygwin")
    SET(CMAKE_COMPILER_IS_CYGWIN 1)
  ENDIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
ENDIF(NOT CMAKE_CXX_COMPILER_ID_RUN)
Bill Hoffman's avatar
Bill Hoffman committed
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# if we have a g++ cross compiler, they have usually some prefix, like 
# e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++
# the other tools of the toolchain usually have the same prefix
# NAME_WE cannot be used since then this test will fail for names lile
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be 
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
IF (CMAKE_CROSSCOMPILING  
    AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"
    AND NOT _CMAKE_TOOLCHAIN_PREFIX)
  GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
  IF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(\\.exe)?$")
    SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
  ENDIF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(\\.exe)?$")

  # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
  # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
  IF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
    SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
  ENDIF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")

ENDIF (CMAKE_CROSSCOMPILING  
    AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"
    AND NOT _CMAKE_TOOLCHAIN_PREFIX)

Alexander Neundorf's avatar
 
Alexander Neundorf committed
178
INCLUDE(CMakeFindBinUtils)
179
180
181
182
IF(MSVC_CXX_ARCHITECTURE_ID)
  SET(SET_MSVC_CXX_ARCHITECTURE_ID
    "SET(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
ENDIF(MSVC_CXX_ARCHITECTURE_ID)
Bill Hoffman's avatar
Bill Hoffman committed
183
# configure all variables set in this file
184
CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
185
186
187
  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake
  @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
  )
188

189
SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")