Factor common code out of CMakeDetermine(ASM|C|CXX|Fortran)Compiler

The compiler candidate list selection and search code for C, C++, ASM,
and Fortran languages was duplicated across four modules.  To look for
compilers adjacent to already-enabled languages the C and CXX modules
each used _CMAKE_USER_(C|CXX)_COMPILER_PATH and the ASM module used
_CMAKE_TOOLCHAIN_LOCATION.  Since commit 4debb7ac (Bias Fortran compiler
search with C/C++ compilers, 2009-09-09) CMake prefers Fortran compilers
matching the vendor and directory of an enabled C or C++ compiler.

Factor out the common functionality among the four languages into a new
CMakeDetermineCompiler module.  Generalize the Fortran implementation so
that all languages may each use the vendor and directory of the other
languages that have already been enabled.  For now do not list any
vendor-specific names for C, C++, or ASM so that only the directory
preference is used for these languages (existing behavior).
This commit is contained in:
Brad King 2012-08-02 11:08:55 -04:00
parent b708f1a2b9
commit 796e33734d
5 changed files with 93 additions and 86 deletions

View File

@ -14,6 +14,8 @@
# determine the compiler to use for ASM programs
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
# prefer the environment variable ASM
IF($ENV{ASM${ASM_DIALECT}} MATCHES ".+")
@ -22,42 +24,27 @@ IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
# finally list compilers to try
IF("ASM${ASM_DIALECT}" STREQUAL "ASM") # the generic assembler support
IF(CMAKE_ASM_COMPILER_INIT)
SET(CMAKE_ASM_COMPILER_LIST ${CMAKE_ASM_COMPILER_INIT})
ELSE(CMAKE_ASM_COMPILER_INIT)
IF(NOT CMAKE_ASM_COMPILER_INIT)
IF(CMAKE_C_COMPILER)
SET(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "The ASM compiler")
SET(CMAKE_ASM_COMPILER_ID "${CMAKE_C_COMPILER_ID}")
ELSEIF(CMAKE_CXX_COMPILER)
SET(CMAKE_ASM_COMPILER "${CMAKE_CXX_COMPILER}" CACHE FILEPATH "The ASM compiler")
SET(CMAKE_ASM_COMPILER_ID "${CMAKE_CXX_COMPILER_ID}")
ELSE(CMAKE_CXX_COMPILER)
ELSE()
# List all default C and CXX compilers
SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gcc ${_CMAKE_TOOLCHAIN_PREFIX}cc cl bcc xlc
${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl bcc xlC)
ENDIF(CMAKE_C_COMPILER)
ENDIF(CMAKE_ASM_COMPILER_INIT)
ELSE("ASM${ASM_DIALECT}" STREQUAL "ASM") # some specific assembler "dialect"
IF(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT})
ELSE(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
ENDIF()
ENDIF()
ELSE() # some specific assembler "dialect"
IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
MESSAGE(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT must be preset !")
ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
ENDIF("ASM${ASM_DIALECT}" STREQUAL "ASM")
ENDIF()
ENDIF()
# Find the compiler.
IF (_CMAKE_USER_CXX_COMPILER_PATH OR _CMAKE_USER_C_COMPILER_PATH)
FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST} PATHS ${_CMAKE_USER_C_COMPILER_PATH} ${_CMAKE_USER_CXX_COMPILER_PATH} DOC "Assembler" NO_DEFAULT_PATH)
ENDIF (_CMAKE_USER_CXX_COMPILER_PATH OR _CMAKE_USER_C_COMPILER_PATH)
FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST} PATHS ${_CMAKE_TOOLCHAIN_LOCATION} DOC "Assembler")
_cmake_find_compiler(ASM${ASM_DIALECT})
ELSE(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)

View File

@ -31,6 +31,8 @@
# If not already set before, it also sets
# _CMAKE_TOOLCHAIN_PREFIX
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
IF(NOT CMAKE_C_COMPILER)
SET(CMAKE_C_COMPILER_INIT NOTFOUND)
@ -53,21 +55,12 @@ IF(NOT CMAKE_C_COMPILER)
ENDIF(CMAKE_GENERATOR_CC)
# finally list compilers to try
IF(CMAKE_C_COMPILER_INIT)
SET(CMAKE_C_COMPILER_LIST ${CMAKE_C_COMPILER_INIT})
ELSE(CMAKE_C_COMPILER_INIT)
IF(NOT CMAKE_C_COMPILER_INIT)
SET(CMAKE_C_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gcc ${_CMAKE_TOOLCHAIN_PREFIX}cc cl bcc xlc clang)
ENDIF(CMAKE_C_COMPILER_INIT)
ENDIF()
# Find the compiler.
IF (_CMAKE_USER_CXX_COMPILER_PATH)
FIND_PROGRAM(CMAKE_C_COMPILER NAMES ${CMAKE_C_COMPILER_LIST} PATHS ${_CMAKE_USER_CXX_COMPILER_PATH} DOC "C compiler" NO_DEFAULT_PATH)
ENDIF (_CMAKE_USER_CXX_COMPILER_PATH)
FIND_PROGRAM(CMAKE_C_COMPILER NAMES ${CMAKE_C_COMPILER_LIST} DOC "C compiler")
_cmake_find_compiler(C)
IF(CMAKE_C_COMPILER_INIT AND NOT CMAKE_C_COMPILER)
SET(CMAKE_C_COMPILER "${CMAKE_C_COMPILER_INIT}" CACHE FILEPATH "C compiler" FORCE)
ENDIF(CMAKE_C_COMPILER_INIT AND NOT CMAKE_C_COMPILER)
ELSE(NOT CMAKE_C_COMPILER)
# we only get here if CMAKE_C_COMPILER was specified using -D or a pre-made CMakeCache.txt

View File

@ -30,6 +30,8 @@
# If not already set before, it also sets
# _CMAKE_TOOLCHAIN_PREFIX
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
IF(NOT CMAKE_CXX_COMPILER)
SET(CMAKE_CXX_COMPILER_INIT NOTFOUND)
@ -52,21 +54,11 @@ IF(NOT CMAKE_CXX_COMPILER)
ENDIF(CMAKE_GENERATOR_CXX)
# finally list compilers to try
IF(CMAKE_CXX_COMPILER_INIT)
SET(CMAKE_CXX_COMPILER_LIST ${CMAKE_CXX_COMPILER_INIT})
ELSE(CMAKE_CXX_COMPILER_INIT)
IF(NOT CMAKE_CXX_COMPILER_INIT)
SET(CMAKE_CXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl bcc xlC clang++)
ENDIF(CMAKE_CXX_COMPILER_INIT)
ENDIF()
# Find the compiler.
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)
FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} DOC "C++ compiler")
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)
_cmake_find_compiler(CXX)
ELSE(NOT CMAKE_CXX_COMPILER)
# we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt

View File

@ -0,0 +1,66 @@
#=============================================================================
# Copyright 2004-2012 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.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
macro(_cmake_find_compiler lang)
# Use already-enabled languages for reference.
get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
list(REMOVE_ITEM _languages "${lang}")
if(CMAKE_${lang}_COMPILER_INIT)
# Search only for the specified compiler.
set(CMAKE_${lang}_COMPILER_LIST "${CMAKE_${lang}_COMPILER_INIT}")
else()
# Re-order the compiler list with preferred vendors first.
set(_${lang}_COMPILER_LIST "${CMAKE_${lang}_COMPILER_LIST}")
set(CMAKE_${lang}_COMPILER_LIST "")
# Prefer vendors of compilers from reference languages.
foreach(l ${_languages})
list(APPEND CMAKE_${lang}_COMPILER_LIST
${_${lang}_COMPILER_NAMES_${CMAKE_${l}_COMPILER_ID}})
endforeach()
# Append the rest of the list and remove duplicates.
list(APPEND CMAKE_${lang}_COMPILER_LIST ${_${lang}_COMPILER_LIST})
unset(_${lang}_COMPILER_LIST)
list(REMOVE_DUPLICATES CMAKE_${lang}_COMPILER_LIST)
endif()
# Look for directories containing compilers of reference languages.
set(_${lang}_COMPILER_HINTS)
foreach(l ${_languages})
if(CMAKE_${l}_COMPILER AND IS_ABSOLUTE "${CMAKE_${l}_COMPILER}")
get_filename_component(_hint "${CMAKE_${l}_COMPILER}" PATH)
if(IS_DIRECTORY "${_hint}")
list(APPEND _${lang}_COMPILER_HINTS "${_hint}")
endif()
unset(_hint)
endif()
endforeach()
# Find the compiler.
if(_${lang}_COMPILER_HINTS)
# Prefer directories containing compilers of reference languages.
list(REMOVE_DUPLICATES _${lang}_COMPILER_HINTS)
find_program(CMAKE_${lang}_COMPILER
NAMES ${CMAKE_${lang}_COMPILER_LIST}
PATHS ${_${lang}_COMPILER_HINTS}
NO_DEFAULT_PATH
DOC "${lang} compiler")
endif()
find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler")
if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER)
set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_INIT}" CACHE FILEPATH "${lang} compiler" FORCE)
endif()
unset(_${lang}_COMPILER_HINTS)
unset(_languages)
endmacro()

View File

@ -19,6 +19,8 @@
# the cmake variable CMAKE_GENERATOR_FC which can be defined by a generator
# as a default compiler
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
IF(NOT CMAKE_Fortran_COMPILER)
# prefer the environment variable CC
IF($ENV{FC} MATCHES ".+")
@ -40,9 +42,7 @@ IF(NOT CMAKE_Fortran_COMPILER)
ENDIF(CMAKE_GENERATOR_FC)
# finally list compilers to try
IF(CMAKE_Fortran_COMPILER_INIT)
SET(CMAKE_Fortran_COMPILER_LIST ${CMAKE_Fortran_COMPILER_INIT})
ELSE(CMAKE_Fortran_COMPILER_INIT)
IF(NOT CMAKE_Fortran_COMPILER_INIT)
# Known compilers:
# f77/f90/f95: generic compiler names
# g77: GNU Fortran 77 compiler
@ -77,41 +77,10 @@ IF(NOT CMAKE_Fortran_COMPILER)
SET(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
SET(_Fortran_COMPILER_NAMES_XL xlf)
SET(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf)
# Prefer vendors matching the C and C++ compilers.
SET(CMAKE_Fortran_COMPILER_LIST
${_Fortran_COMPILER_NAMES_${CMAKE_C_COMPILER_ID}}
${_Fortran_COMPILER_NAMES_${CMAKE_CXX_COMPILER_ID}}
${CMAKE_Fortran_COMPILER_LIST})
LIST(REMOVE_DUPLICATES CMAKE_Fortran_COMPILER_LIST)
ENDIF(CMAKE_Fortran_COMPILER_INIT)
# Look for directories containing the C and C++ compilers.
SET(_Fortran_COMPILER_HINTS)
FOREACH(lang C CXX)
IF(CMAKE_${lang}_COMPILER AND IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}")
GET_FILENAME_COMPONENT(_hint "${CMAKE_${lang}_COMPILER}" PATH)
IF(IS_DIRECTORY "${_hint}")
LIST(APPEND _Fortran_COMPILER_HINTS "${_hint}")
ENDIF()
SET(_hint)
ENDIF()
ENDFOREACH()
# Find the compiler.
IF(_Fortran_COMPILER_HINTS)
# Prefer directories containing C and C++ compilers.
LIST(REMOVE_DUPLICATES _Fortran_COMPILER_HINTS)
FIND_PROGRAM(CMAKE_Fortran_COMPILER
NAMES ${CMAKE_Fortran_COMPILER_LIST}
PATHS ${_Fortran_COMPILER_HINTS}
NO_DEFAULT_PATH
DOC "Fortran compiler")
ENDIF()
FIND_PROGRAM(CMAKE_Fortran_COMPILER NAMES ${CMAKE_Fortran_COMPILER_LIST} DOC "Fortran compiler")
IF(CMAKE_Fortran_COMPILER_INIT AND NOT CMAKE_Fortran_COMPILER)
SET(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER_INIT}" CACHE FILEPATH "Fortran compiler" FORCE)
ENDIF(CMAKE_Fortran_COMPILER_INIT AND NOT CMAKE_Fortran_COMPILER)
_cmake_find_compiler(Fortran)
ELSE(NOT CMAKE_Fortran_COMPILER)
# we only get here if CMAKE_Fortran_COMPILER was specified using -D or a pre-made CMakeCache.txt
# (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE