From 2bc4103ea9ec76b53b4674efadf2240928f7dbf4 Mon Sep 17 00:00:00 2001 From: Brian Sidebotham Date: Sun, 4 Aug 2013 21:31:14 +0100 Subject: [PATCH] * Added modified CMake FindPython... modules to support using Python-a-mingw-us distribution when building Windows scripting support using MinGW --- CMakeLists.txt | 2 +- CMakeModules/CMakeFindFrameworks.cmake | 32 ++ .../FindPackageHandleStandardArgs.cmake | 260 ++++++++++++++ CMakeModules/FindPythonInterp.cmake | 175 +++++++++ CMakeModules/FindPythonLibs.cmake | 338 ++++++++++++++++++ CMakeModules/PerformFeatureChecks.cmake | 12 + .../SelectLibraryConfigurations.cmake | 87 +++++ 7 files changed, 905 insertions(+), 1 deletion(-) create mode 100644 CMakeModules/CMakeFindFrameworks.cmake create mode 100644 CMakeModules/FindPackageHandleStandardArgs.cmake create mode 100644 CMakeModules/FindPythonInterp.cmake create mode 100644 CMakeModules/FindPythonLibs.cmake create mode 100644 CMakeModules/SelectLibraryConfigurations.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 559397b60b..0dbf597ebf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,7 +323,7 @@ if(KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) mark_as_advanced(PYTHON_DEST) message( STATUS "Python module install path: ${PYTHON_DEST}") find_package(PythonLibs) - include_directories(${PYTHON_INCLUDE_PATH} + include_directories(${PYTHON_INCLUDE_DIRS} ./scripting) endif(KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) diff --git a/CMakeModules/CMakeFindFrameworks.cmake b/CMakeModules/CMakeFindFrameworks.cmake new file mode 100644 index 0000000000..7fdeb84bef --- /dev/null +++ b/CMakeModules/CMakeFindFrameworks.cmake @@ -0,0 +1,32 @@ +# - helper module to find OSX frameworks + +#============================================================================= +# Copyright 2003-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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED) + set(CMAKE_FIND_FRAMEWORKS_INCLUDED 1) + macro(CMAKE_FIND_FRAMEWORKS fwk) + set(${fwk}_FRAMEWORKS) + if(APPLE) + foreach(dir + ~/Library/Frameworks/${fwk}.framework + /Library/Frameworks/${fwk}.framework + /System/Library/Frameworks/${fwk}.framework + /Network/Library/Frameworks/${fwk}.framework) + if(EXISTS ${dir}) + set(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir}) + endif() + endforeach() + endif() + endmacro() +endif() diff --git a/CMakeModules/FindPackageHandleStandardArgs.cmake b/CMakeModules/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000000..1acb021e80 --- /dev/null +++ b/CMakeModules/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,260 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) +# +# This function is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE(). +# It also sets the _FOUND variable. +# The package is considered found if all variables ... listed contain +# valid results, e.g. valid filepaths. +# +# There are two modes of this function. The first argument in both modes is +# the name of the Find-module where it is called (in original casing). +# +# The first simple mode looks like this: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( (DEFAULT_MSG|"Custom failure message") ... ) +# If the variables to are all valid, then _FOUND +# will be set to TRUE. +# If DEFAULT_MSG is given as second argument, then the function will generate +# itself useful success and error messages. You can also supply a custom error message +# for the failure case. This is not recommended. +# +# The second mode is more powerful and also supports version checking: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS ...] +# [VERSION_VAR +# [CONFIG_MODE] +# [FAIL_MESSAGE "Custom failure message"] ) +# +# As above, if through are all valid, _FOUND +# will be set to TRUE. +# After REQUIRED_VARS the variables which are required for this package are listed. +# Following VERSION_VAR the name of the variable can be specified which holds +# the version of the package which has been found. If this is done, this version +# will be checked against the (potentially) specified required version used +# in the find_package() call. The EXACT keyword is also handled. The default +# messages include information about the required version and the version +# which has been actually found, both if the version is ok or not. +# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for +# a find_package(... NO_MODULE) call, in this case all the information +# provided by the config-mode of find_package() will be evaluated +# automatically. +# Via FAIL_MESSAGE a custom failure message can be specified, if this is not +# used, the default message will be displayed. +# +# Example for mode 1: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, success will be reported, including the content of . +# On repeated Cmake runs, the same message won't be printed again. +# +# Example for mode 2: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE +# VERSION_VAR BISON_VERSION) +# In this case, BISON is considered to be found if the variable(s) listed +# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. +# Also the version of BISON will be checked by using the version contained +# in BISON_VERSION. +# Since no FAIL_MESSAGE is given, the default messages will be printed. +# +# Another example for mode 2: +# +# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) +# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE) +# and adds an additional search directory for automoc4. +# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper +# success/error message. + +#============================================================================= +# Copyright 2007-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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +INCLUDE(FindPackageMessage) +INCLUDE(CMakeParseArguments) + +# internal helper macro +MACRO(_FPHSA_FAILURE_MESSAGE _msg) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_msg}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_msg}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) +ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg) + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + IF(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + ELSE(${_NAME}_CONFIG) + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + IF(${_NAME}_CONSIDERED_CONFIGS) + SET(configsText "") + LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + MATH(EXPR configsCount "${configsCount} - 1") + FOREACH(currentConfigIndex RANGE ${configsCount}) + LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + SET(configsText "${configsText} ${filename} (version ${version})\n") + ENDFOREACH(currentConfigIndex) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + ELSE(${_NAME}_CONSIDERED_CONFIGS) + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + ENDIF(${_NAME}_CONSIDERED_CONFIGS) + ENDIF(${_NAME}_CONFIG) +ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + + +FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + SET(options CONFIG_MODE) + SET(oneValueArgs FAIL_MESSAGE VERSION_VAR) + SET(multiValueArgs REQUIRED_VARS) + SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + IF(${INDEX} EQUAL -1) + SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + SET(FPHSA_REQUIRED_VARS ${ARGN}) + SET(FPHSA_VERSION_VAR) + ELSE(${INDEX} EQUAL -1) + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + IF(FPHSA_UNPARSED_ARGUMENTS) + MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + ENDIF(FPHSA_UNPARSED_ARGUMENTS) + + IF(NOT FPHSA_FAIL_MESSAGE) + SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + ENDIF(NOT FPHSA_FAIL_MESSAGE) + ENDIF(${INDEX} EQUAL -1) + +# now that we collected all arguments, process them + + IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + IF(FPHSA_CONFIG_MODE) + LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + SET(FPHSA_VERSION_VAR ${_NAME}_VERSION) + ENDIF(FPHSA_CONFIG_MODE) + + IF(NOT FPHSA_REQUIRED_VARS) + MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + ENDIF(NOT FPHSA_REQUIRED_VARS) + + LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + STRING(TOLOWER ${_NAME} _NAME_LOWER) + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + SET(MISSING_VARS "") + SET(DETAILS "") + SET(${_NAME_UPPER}_FOUND TRUE) + # check if all passed variables are valid + FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") + ELSE(NOT ${_CURRENT_VAR}) + SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + + # version handling: + SET(VERSION_MSG "") + SET(VERSION_OK TRUE) + SET(VERSION ${${FPHSA_VERSION_VAR}} ) + IF (${_NAME}_FIND_VERSION) + + IF(VERSION) + + IF(${_NAME}_FIND_VERSION_EXACT) # exact version required + IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + SET(VERSION_OK FALSE) + ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + + ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified: + IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + SET(VERSION_OK FALSE) + ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")") + ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + ENDIF(${_NAME}_FIND_VERSION_EXACT) + + ELSE(VERSION) + + # if the package was not found, but a version was given, add that to the output: + IF(${_NAME}_FIND_VERSION_EXACT) + SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + ELSE(${_NAME}_FIND_VERSION_EXACT) + SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + ENDIF(${_NAME}_FIND_VERSION_EXACT) + + ENDIF(VERSION) + ELSE (${_NAME}_FIND_VERSION) + IF(VERSION) + SET(VERSION_MSG "(found version \"${VERSION}\")") + ENDIF(VERSION) + ENDIF (${_NAME}_FIND_VERSION) + + IF(VERSION_OK) + SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") + ELSE(VERSION_OK) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(VERSION_OK) + + + # print the result: + IF (${_NAME_UPPER}_FOUND) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}") + ELSE (${_NAME_UPPER}_FOUND) + + IF(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + ELSE(FPHSA_CONFIG_MODE) + IF(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + ELSE(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") + ENDIF(NOT VERSION_OK) + ENDIF(FPHSA_CONFIG_MODE) + + ENDIF (${_NAME_UPPER}_FOUND) + + SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) + +ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG) diff --git a/CMakeModules/FindPythonInterp.cmake b/CMakeModules/FindPythonInterp.cmake new file mode 100644 index 0000000000..b2261f1466 --- /dev/null +++ b/CMakeModules/FindPythonInterp.cmake @@ -0,0 +1,175 @@ +# - Find python interpreter +# This module finds if Python interpreter is installed and determines where the +# executables are. This code sets the following variables: +# +# PYTHONINTERP_FOUND - Was the Python executable found +# PYTHON_EXECUTABLE - path to the Python interpreter +# +# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2 +# PYTHON_VERSION_MAJOR - Python major version found e.g. 2 +# PYTHON_VERSION_MINOR - Python minor version found e.g. 5 +# PYTHON_VERSION_PATCH - Python patch version found e.g. 2 +# +# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of +# version numbers that should be taken into account when searching for Python. +# You need to set this variable before calling find_package(PythonInterp). +# +# You can point to a preferred python install to use by setting the following +# to the point at the root directory of the python install: +# +# PYTHON_ROOT_DIR - The root directory of the python install +#============================================================================= +# Copyright 2005-2010 Kitware, Inc. +# Copyright 2011 Bjoern Ricks +# Copyright 2012 Rolf Eike Beer +# +# 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.) + +unset(_Python_NAMES) + +set(_PYTHON1_VERSIONS 1.6 1.5) +set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) +set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0) + +if(PythonInterp_FIND_VERSION) + if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") + string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION}") + string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}") + list(APPEND _Python_NAMES python${_PYTHON_FIND_MAJ_MIN} python${_PYTHON_FIND_MAJ}) + unset(_PYTHON_FIND_OTHER_VERSIONS) + if(NOT PythonInterp_FIND_VERSION_EXACT) + foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS}) + if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) + list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) + endif() + endforeach() + endif() + unset(_PYTHON_FIND_MAJ_MIN) + unset(_PYTHON_FIND_MAJ) + else() + list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION}) + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS}) + endif() +else() + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) +endif() + +list(APPEND _Python_NAMES python) + +# Search for the preferred executable first +if( ${PYTHON_ROOT_DIR} ) + # Search for any of the executable names solely in the directory we've + # been pointed to. Failure to find the python executable here is a fatal + # fail. + find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES} + PATHS ${PYTHON_ROOT_DIR} + NO_DEFAULT_PATH ) +else() + # If there is no specific path given, look for python in the path + find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES}) +endif() + +# Set up the versions we know about, in the order we will search. Always add +# the user supplied additional versions to the front. +set(_Python_VERSIONS + ${Python_ADDITIONAL_VERSIONS} + ${_PYTHON_FIND_OTHER_VERSIONS} + ) + +unset(_PYTHON_FIND_OTHER_VERSIONS) +unset(_PYTHON1_VERSIONS) +unset(_PYTHON2_VERSIONS) +unset(_PYTHON3_VERSIONS) + +# Search for newest python version if python executable isn't found +if(NOT PYTHON_EXECUTABLE) + + # If using the MINGW compiler, we mustn't find the standard python + # distribution because of multiple C-Runtime errors. We must instead + # use the Python-a-mingw-us distribution + if(MINGW) + list( APPEND _Python_PPATHS ${PYTHON_ROOT_DIR} ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.9" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.8" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.7" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.6" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.5" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.4" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.3" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.2" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.1" ) + list( APPEND _Python_PPATHS "C:/python/${_CURRENT_VERSION}.0" ) + else() + list( APPEND _Python_PPATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath] ) + endif() + + foreach(_CURRENT_VERSION ${_Python_VERSIONS}) + set(_Python_NAMES python${_CURRENT_VERSION}) + if(WIN32) + list(APPEND _Python_NAMES python) + endif() + find_program(PYTHON_EXECUTABLE + NAMES ${_Python_NAMES} + PATHS ${_Python_PPATHS} + ) + endforeach() +endif() + +# determine python version string +if(PYTHON_EXECUTABLE) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}") + list(GET _VERSION 0 PYTHON_VERSION_MAJOR) + list(GET _VERSION 1 PYTHON_VERSION_MINOR) + list(GET _VERSION 2 PYTHON_VERSION_PATCH) + if(PYTHON_VERSION_PATCH EQUAL 0) + # it's called "Python 2.7", not "2.7.0" + string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}") + endif() + else() + # sys.version predates sys.version_info, so use that + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}") + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}") + if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}") + else() + set(PYTHON_VERSION_PATCH "0") + endif() + else() + # sys.version was first documented for Python 1.5, so assume + # this is older. + set(PYTHON_VERSION_STRING "1.4") + set(PYTHON_VERSION_MAJOR "1") + set(PYTHON_VERSION_MAJOR "4") + set(PYTHON_VERSION_MAJOR "0") + endif() + endif() + unset(_PYTHON_VERSION_RESULT) + unset(_VERSION) +endif() + +# handle the QUIETLY and REQUIRED arguments and set PYTHONINTERP_FOUND to TRUE if +# all listed variables are TRUE +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING) + +mark_as_advanced(PYTHON_EXECUTABLE) diff --git a/CMakeModules/FindPythonLibs.cmake b/CMakeModules/FindPythonLibs.cmake new file mode 100644 index 0000000000..e2f73d8ea4 --- /dev/null +++ b/CMakeModules/FindPythonLibs.cmake @@ -0,0 +1,338 @@ +# - Find python libraries +# This module finds if Python is installed and determines where the +# include files and libraries are. It also determines what the name of +# the library is. This code sets the following variables: +# +# PYTHONLIBS_FOUND - have the Python libs been found +# PYTHON_LIBRARIES - path to the python library +# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated) +# PYTHON_INCLUDE_DIRS - path to where Python.h is found +# PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated) +# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8) +# +# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of +# version numbers that should be taken into account when searching for Python. +# You need to set this variable before calling find_package(PythonLibs). +# +# You can point to a preferred python install to use by setting the following +# to the point at the root directory of the python install: +# +# PYTHON_ROOT_DIR - The root directory of the python install +# +# If you'd like to specify the installation of Python to use, you should modify +# the following cache variables: +# PYTHON_LIBRARY - path to the python library +# PYTHON_INCLUDE_DIR - path to where Python.h is found + +#============================================================================= +# Copyright 2001-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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake) +# Search for the python framework on Apple. +CMAKE_FIND_FRAMEWORKS(Python) + +set(_PYTHON1_VERSIONS 1.6 1.5) +set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) +set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0) + +if(PythonLibs_FIND_VERSION) + if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") + string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION}") + string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}") + unset(_PYTHON_FIND_OTHER_VERSIONS) + if(PythonLibs_FIND_VERSION_EXACT) + if(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION) + set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}") + else() + set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}" "${_PYTHON_FIND_MAJ_MIN}") + endif() + else() + foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS}) + if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) + list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) + endif() + endforeach() + endif() + unset(_PYTHON_FIND_MAJ_MIN) + unset(_PYTHON_FIND_MAJ) + else() + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION}_VERSIONS}) + endif() +else() + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) +endif() + +# Set up the versions we know about, in the order we will search. Always add +# the user supplied additional versions to the front. +set(_Python_VERSIONS + ${Python_ADDITIONAL_VERSIONS} + ${_PYTHON_FIND_OTHER_VERSIONS} + ) + +unset(_PYTHON_FIND_OTHER_VERSIONS) +unset(_PYTHON1_VERSIONS) +unset(_PYTHON2_VERSIONS) +unset(_PYTHON3_VERSIONS) + +foreach(_CURRENT_VERSION ${_Python_VERSIONS}) + string(REPLACE "." "" _CURRENT_VERSION_NO_DOTS ${_CURRENT_VERSION}) + if(WIN32) + if(MINGW) + find_library(PYTHON_DEBUG_LIBRARY + NAMES python{$_CURRENT_VERSION}_d + PATHS + "${PYTHON_ROOT_DIR}" + "C:/python/${_CURRENT_VERSION}.9" + "C:/python/${_CURRENT_VERSION}.8" + "C:/python/${_CURRENT_VERSION}.7" + "C:/python/${_CURRENT_VERSION}.6" + "C:/python/${_CURRENT_VERSION}.5" + "C:/python/${_CURRENT_VERSION}.4" + "C:/python/${_CURRENT_VERSION}.3" + "C:/python/${_CURRENT_VERSION}.2" + "C:/python/${_CURRENT_VERSION}.1" + "C:/python/${_CURRENT_VERSION}.0" + NO_SYSTEM_ENVIRONMENT_PATH + ) + else() + find_library(PYTHON_DEBUG_LIBRARY + NAMES python${_CURRENT_VERSION_NO_DOTS}_d python + PATHS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + ) + endif() + endif() + + if(MINGW) + find_library(PYTHON_LIBRARY + NAMES python${_CURRENT_VERSION} + PATHS + "${PYTHON_ROOT_DIR}" + "C:/python/${_CURRENT_VERSION}.9" + "C:/python/${_CURRENT_VERSION}.8" + "C:/python/${_CURRENT_VERSION}.7" + "C:/python/${_CURRENT_VERSION}.6" + "C:/python/${_CURRENT_VERSION}.5" + "C:/python/${_CURRENT_VERSION}.4" + "C:/python/${_CURRENT_VERSION}.3" + "C:/python/${_CURRENT_VERSION}.2" + "C:/python/${_CURRENT_VERSION}.1" + "C:/python/${_CURRENT_VERSION}.0" + NO_SYSTEM_ENVIRONMENT_PATH + ) + else() + find_library(PYTHON_LIBRARY + NAMES + python${_CURRENT_VERSION_NO_DOTS} + python${_CURRENT_VERSION}mu + python${_CURRENT_VERSION}m + python${_CURRENT_VERSION}u + python${_CURRENT_VERSION} + PATHS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs + # Avoid finding the .dll in the PATH. We want the .lib. + NO_SYSTEM_ENVIRONMENT_PATH + ) + endif() + + # Look for the static library in the Python config directory + find_library(PYTHON_LIBRARY + NAMES python${_CURRENT_VERSION_NO_DOTS} python${_CURRENT_VERSION} + # Avoid finding the .dll in the PATH. We want the .lib. + NO_SYSTEM_ENVIRONMENT_PATH + # This is where the static library is usually located + PATH_SUFFIXES python${_CURRENT_VERSION}/config + ) + + + # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if + # PYTHON_INCLUDE_DIR is not set. + if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR) + set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH + "Path to where Python.h is found" FORCE) + endif() + + set(PYTHON_FRAMEWORK_INCLUDES) + if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR) + foreach(dir ${Python_FRAMEWORKS}) + set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES} + ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION}) + endforeach() + endif() + + if(MINGW) + find_path(PYTHON_INCLUDE_DIR + NAMES Python.h + PATHS + "${PYTHON_ROOT_DIR}/include" + "C:/python/${_CURRENT_VERSION}.9/include" + "C:/python/${_CURRENT_VERSION}.8/include" + "C:/python/${_CURRENT_VERSION}.7/include" + "C:/python/${_CURRENT_VERSION}.6/include" + "C:/python/${_CURRENT_VERSION}.5/include" + "C:/python/${_CURRENT_VERSION}.4/include" + "C:/python/${_CURRENT_VERSION}.3/include" + "C:/python/${_CURRENT_VERSION}.2/include" + "C:/python/${_CURRENT_VERSION}.1/include" + "C:/python/${_CURRENT_VERSION}.0/include" + ) + else() + find_path(PYTHON_INCLUDE_DIR + NAMES Python.h + PATHS + ${PYTHON_FRAMEWORK_INCLUDES} + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include + PATH_SUFFIXES + python${_CURRENT_VERSION}mu + python${_CURRENT_VERSION}m + python${_CURRENT_VERSION}u + python${_CURRENT_VERSION} + ) + endif() + + # For backward compatibility, set PYTHON_INCLUDE_PATH. + set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}") + + if(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") + file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str + REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") + string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + PYTHONLIBS_VERSION_STRING "${python_version_str}") + unset(python_version_str) + endif() + + if(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) + break() + endif() +endforeach() + +mark_as_advanced( + PYTHON_DEBUG_LIBRARY + PYTHON_LIBRARY + PYTHON_INCLUDE_DIR +) + +# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the +# cache entries because they are meant to specify the location of a single +# library. We now set the variables listed by the documentation for this +# module. +set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") +set(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") + +# These variables have been historically named in this module different from +# what SELECT_LIBRARY_CONFIGURATIONS() expects. +set(PYTHON_LIBRARY_DEBUG "${PYTHON_DEBUG_LIBRARY}") +set(PYTHON_LIBRARY_RELEASE "${PYTHON_LIBRARY}") +include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) +SELECT_LIBRARY_CONFIGURATIONS(PYTHON) +# SELECT_LIBRARY_CONFIGURATIONS() sets ${PREFIX}_FOUND if it has a library. +# Unset this, this prefix doesn't match the module prefix, they are different +# for historical reasons. +unset(PYTHON_FOUND) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs + REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS + VERSION_VAR PYTHONLIBS_VERSION_STRING) + +# PYTHON_ADD_MODULE( src1 src2 ... srcN) is used to build modules for python. +# PYTHON_WRITE_MODULES_HEADER() writes a header file you can include +# in your sources to initialize the static python modules +function(PYTHON_ADD_MODULE _NAME ) + get_property(_TARGET_SUPPORTS_SHARED_LIBS + GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS) + option(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE) + option(PYTHON_MODULE_${_NAME}_BUILD_SHARED + "Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS}) + + # Mark these options as advanced + mark_as_advanced(PYTHON_ENABLE_MODULE_${_NAME} + PYTHON_MODULE_${_NAME}_BUILD_SHARED) + + if(PYTHON_ENABLE_MODULE_${_NAME}) + if(PYTHON_MODULE_${_NAME}_BUILD_SHARED) + set(PY_MODULE_TYPE MODULE) + else() + set(PY_MODULE_TYPE STATIC) + set_property(GLOBAL APPEND PROPERTY PY_STATIC_MODULES_LIST ${_NAME}) + endif() + + set_property(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME}) + add_library(${_NAME} ${PY_MODULE_TYPE} ${ARGN}) +# target_link_libraries(${_NAME} ${PYTHON_LIBRARIES}) + + if(PYTHON_MODULE_${_NAME}_BUILD_SHARED) + set_target_properties(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") + if(WIN32 AND NOT CYGWIN) + set_target_properties(${_NAME} PROPERTIES SUFFIX ".pyd") + endif() + endif() + + endif() +endfunction() + +function(PYTHON_WRITE_MODULES_HEADER _filename) + + get_property(PY_STATIC_MODULES_LIST GLOBAL PROPERTY PY_STATIC_MODULES_LIST) + + get_filename_component(_name "${_filename}" NAME) + string(REPLACE "." "_" _name "${_name}") + string(TOUPPER ${_name} _nameUpper) + set(_filename ${CMAKE_CURRENT_BINARY_DIR}/${_filename}) + + set(_filenameTmp "${_filename}.in") + file(WRITE ${_filenameTmp} "/*Created by cmake, do not edit, changes will be lost*/\n") + file(APPEND ${_filenameTmp} +"#ifndef ${_nameUpper} +#define ${_nameUpper} + +#include + +#ifdef __cplusplus +extern \"C\" { +#endif /* __cplusplus */ + +") + + foreach(_currentModule ${PY_STATIC_MODULES_LIST}) + file(APPEND ${_filenameTmp} "extern void init${PYTHON_MODULE_PREFIX}${_currentModule}(void);\n\n") + endforeach() + + file(APPEND ${_filenameTmp} +"#ifdef __cplusplus +} +#endif /* __cplusplus */ + +") + + + foreach(_currentModule ${PY_STATIC_MODULES_LIST}) + file(APPEND ${_filenameTmp} "int ${_name}_${_currentModule}(void) \n{\n static char name[]=\"${PYTHON_MODULE_PREFIX}${_currentModule}\"; return PyImport_AppendInittab(name, init${PYTHON_MODULE_PREFIX}${_currentModule});\n}\n\n") + endforeach() + + file(APPEND ${_filenameTmp} "void ${_name}_LoadAllPythonModules(void)\n{\n") + foreach(_currentModule ${PY_STATIC_MODULES_LIST}) + file(APPEND ${_filenameTmp} " ${_name}_${_currentModule}();\n") + endforeach() + file(APPEND ${_filenameTmp} "}\n\n") + file(APPEND ${_filenameTmp} "#ifndef EXCLUDE_LOAD_ALL_FUNCTION\nvoid CMakeLoadAllPythonModules(void)\n{\n ${_name}_LoadAllPythonModules();\n}\n#endif\n\n#endif\n") + +# with configure_file() cmake complains that you may not use a file created using file(WRITE) as input file for configure_file() + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_filenameTmp}" "${_filename}" OUTPUT_QUIET ERROR_QUIET) + +endfunction() diff --git a/CMakeModules/PerformFeatureChecks.cmake b/CMakeModules/PerformFeatureChecks.cmake index 3dcae68b30..e1cc304ab6 100644 --- a/CMakeModules/PerformFeatureChecks.cmake +++ b/CMakeModules/PerformFeatureChecks.cmake @@ -56,6 +56,18 @@ macro(perform_feature_checks) # mean won't fail somewhere down the line. check_include_file("iso646.h" HAVE_ISO646_H) + # The STDINT header file test is required because MinGW under Windows + # doesn't define HAVE_STDINT_H even though it does have it. + # + # We need to add it to the global compiler definitions as config.h is not + # included in pyport.h which is where the problem ocurrs without this + # fix. + check_include_file("stdint.h" HAVE_STDINT_H) + + if( HAVE_STDINT_H ) + add_definitions( -DHAVE_STDINT_H ) + endif() + # no place is this used, and "HAVE_STRINGS_H", if present in config.h then # conflicts with /usr/include/python2.6/Python.h. Please rename the macro if # re-introduce this. diff --git a/CMakeModules/SelectLibraryConfigurations.cmake b/CMakeModules/SelectLibraryConfigurations.cmake new file mode 100644 index 0000000000..5bca064f5a --- /dev/null +++ b/CMakeModules/SelectLibraryConfigurations.cmake @@ -0,0 +1,87 @@ +# select_library_configurations( basename ) +# +# This macro takes a library base name as an argument, and will choose good +# values for basename_LIBRARY, basename_LIBRARIES, basename_LIBRARY_DEBUG, and +# basename_LIBRARY_RELEASE depending on what has been found and set. If only +# basename_LIBRARY_RELEASE is defined, basename_LIBRARY, basename_LIBRARY_DEBUG, +# and basename_LIBRARY_RELEASE will be set to the release value. If only +# basename_LIBRARY_DEBUG is defined, then basename_LIBRARY, +# basename_LIBRARY_DEBUG and basename_LIBRARY_RELEASE will take the debug value. +# +# If the generator supports configuration types, then basename_LIBRARY and +# basename_LIBRARIES will be set with debug and optimized flags specifying the +# library to be used for the given configuration. If no build type has been set +# or the generator in use does not support configuration types, then +# basename_LIBRARY and basename_LIBRARIES will take only the release values. + +#============================================================================= +# Copyright 2009 Will Dicharry +# Copyright 2005-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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# This macro was adapted from the FindQt4 CMake module and is maintained by Will +# Dicharry . + +# Utility macro to check if one variable exists while another doesn't, and set +# one that doesn't exist to the one that exists. +macro( _set_library_name basename GOOD BAD ) + if( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} ) + set( ${basename}_LIBRARY_${BAD} ${${basename}_LIBRARY_${GOOD}} ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_${GOOD}} ) + set( ${basename}_LIBRARIES ${${basename}_LIBRARY_${GOOD}} ) + endif() +endmacro() + +macro( select_library_configurations basename ) + # if only the release version was found, set the debug to be the release + # version. + _set_library_name( ${basename} RELEASE DEBUG ) + # if only the debug version was found, set the release value to be the + # debug value. + _set_library_name( ${basename} DEBUG RELEASE ) + + # Set a default case, which will come into effect if + # -no build type is set and the generator only supports one build type + # at a time (i.e. CMAKE_CONFIGURATION_TYPES is false) + # -${basename}_LIBRARY_DEBUG and ${basename}_LIBRARY_RELEASE are the same + # -${basename}_LIBRARY_DEBUG and ${basename}_LIBRARY_RELEASE are both empty + set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) + set( ${basename}_LIBRARIES ${${basename}_LIBRARY_RELEASE} ) + + if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND + NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE ) + # if the generator supports configuration types or CMAKE_BUILD_TYPE + # is set, then set optimized and debug options. + if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) + set( ${basename}_LIBRARY "" ) + foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) + list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) + endforeach() + foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) + list( APPEND ${basename}_LIBRARY debug "${_libname}" ) + endforeach() + set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) + endif() + endif() + + set( ${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH + "The ${basename} library" ) + + if( ${basename}_LIBRARY ) + set( ${basename}_FOUND TRUE ) + endif() + + mark_as_advanced( ${basename}_LIBRARY + ${basename}_LIBRARY_RELEASE + ${basename}_LIBRARY_DEBUG + ) +endmacro()