Index: lldb/trunk/cmake/modules/LLDBConfig.cmake =================================================================== --- lldb/trunk/cmake/modules/LLDBConfig.cmake +++ lldb/trunk/cmake/modules/LLDBConfig.cmake @@ -134,6 +134,48 @@ # locate 64-bit Python libraries. # This function is designed to address those limitations. Currently it only partially # addresses them, but it can be improved and extended on an as-needed basis. +function(find_python_libs_windows_helper LOOKUP_DEBUG OUT_EXE_PATH_VARNAME OUT_LIB_PATH_VARNAME OUT_DLL_PATH_VARNAME OUT_VERSION_VARNAME) + if(LOOKUP_DEBUG) + set(POSTFIX "_d") + else() + set(POSTFIX "") + endif() + + file(TO_CMAKE_PATH "${PYTHON_HOME}/python${POSTFIX}.exe" PYTHON_EXE) + file(TO_CMAKE_PATH "${PYTHON_HOME}/libs/${PYTHONLIBS_BASE_NAME}${POSTFIX}.lib" PYTHON_LIB) + file(TO_CMAKE_PATH "${PYTHON_HOME}/${PYTHONLIBS_BASE_NAME}${POSTFIX}.dll" PYTHON_DLL) + + foreach(component PYTHON_EXE;PYTHON_LIB;PYTHON_DLL) + if(NOT EXISTS ${${component}}) + message(WARNING "Unable to find ${component}") + unset(${component}) + endif() + endforeach() + + if (NOT PYTHON_EXE OR NOT PYTHON_LIB OR NOT PYTHON_DLL) + message(WARNING "Unable to find all Python components. Python support will be disabled for this build.") + set(LLDB_DISABLE_PYTHON 1 PARENT_SCOPE) + return() + endif() + + # Find the version of the Python interpreter. + execute_process(COMMAND "${PYTHON_EXE}" -c + "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" + OUTPUT_VARIABLE PYTHON_VERSION_OUTPUT + RESULT_VARIABLE PYTHON_VERSION_RESULT + ERROR_QUIET) + + if(PYTHON_VERSION_RESULT) + message(WARNING "Unable to retrieve Python executable version") + set(PYTHON_VERSION_OUTPUT "") + endif() + + set(${OUT_EXE_PATH_VARNAME} ${PYTHON_EXE} PARENT_SCOPE) + set(${OUT_LIB_PATH_VARNAME} ${PYTHON_LIB} PARENT_SCOPE) + set(${OUT_DLL_PATH_VARNAME} ${PYTHON_DLL} PARENT_SCOPE) + set(${OUT_VERSION_VARNAME} ${PYTHON_VERSION_OUTPUT} PARENT_SCOPE) +endfunction() + function(find_python_libs_windows) if ("${PYTHON_HOME}" STREQUAL "") message(WARNING "LLDB embedded Python on Windows requires specifying a value for PYTHON_HOME. Python support disabled.") @@ -161,55 +203,65 @@ file(TO_CMAKE_PATH "${PYTHON_HOME}" PYTHON_HOME) # TODO(compnerd) when CMake Policy `CMP0091` is set to NEW, we should use # if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES MultiThreadedDebug) - if(CMAKE_BUILD_TYPE STREQUAL Debug) - file(TO_CMAKE_PATH "${PYTHON_HOME}/python_d.exe" PYTHON_EXE) - file(TO_CMAKE_PATH "${PYTHON_HOME}/libs/${PYTHONLIBS_BASE_NAME}_d.lib" PYTHON_LIB) - file(TO_CMAKE_PATH "${PYTHON_HOME}/${PYTHONLIBS_BASE_NAME}_d.dll" PYTHON_DLL) - else() - file(TO_CMAKE_PATH "${PYTHON_HOME}/python.exe" PYTHON_EXE) - file(TO_CMAKE_PATH "${PYTHON_HOME}/libs/${PYTHONLIBS_BASE_NAME}.lib" PYTHON_LIB) - file(TO_CMAKE_PATH "${PYTHON_HOME}/${PYTHONLIBS_BASE_NAME}.dll" PYTHON_DLL) - endif() - - foreach(component PYTHON_EXE;PYTHON_LIB;PYTHON_DLL) - if(NOT EXISTS ${${component}}) - message(WARNING "unable to find ${component}") - unset(${component}) + if(NOT DEFINED CMAKE_BUILD_TYPE) + # Multi-target generator was selected (like Visual Studio or Xcode) where no concrete build type was passed + # Lookup for both debug and release python installations + find_python_libs_windows_helper(TRUE PYTHON_DEBUG_EXE PYTHON_DEBUG_LIB PYTHON_DEBUG_DLL PYTHON_DEBUG_VERSION_STRING) + find_python_libs_windows_helper(FALSE PYTHON_RELEASE_EXE PYTHON_RELEASE_LIB PYTHON_RELEASE_DLL PYTHON_RELEASE_VERSION_STRING) + if(LLDB_DISABLE_PYTHON) + set(LLDB_DISABLE_PYTHON 1 PARENT_SCOPE) + return() endif() - endforeach() - if (NOT PYTHON_EXE OR NOT PYTHON_LIB OR NOT PYTHON_DLL) - message(WARNING "Unable to find all Python components. Python support will be disabled for this build.") - set(LLDB_DISABLE_PYTHON 1 PARENT_SCOPE) - return() + # We should have been found both debug and release python here + # Now check that their versions are equal + if(NOT PYTHON_DEBUG_VERSION_STRING STREQUAL PYTHON_RELEASE_VERSION_STRING) + message(FATAL_ERROR "Python versions for debug (${PYTHON_DEBUG_VERSION_STRING}) and release (${PYTHON_RELEASE_VERSION_STRING}) are different." + "Python installation is corrupted") + endif () + + set(PYTHON_EXECUTABLE $<$:${PYTHON_DEBUG_EXE}>$<$>:${PYTHON_RELEASE_EXE}>) + set(PYTHON_LIBRARY $<$:${PYTHON_DEBUG_LIB}>$<$>:${PYTHON_RELEASE_LIB}>) + set(PYTHON_DLL $<$:${PYTHON_DEBUG_DLL}>$<$>:${PYTHON_RELEASE_DLL}>) + set(PYTHON_VERSION_STRING ${PYTHON_RELEASE_VERSION_STRING}) + else() + # Lookup for concrete python installation depending on build type + if (CMAKE_BUILD_TYPE STREQUAL Debug) + set(LOOKUP_DEBUG_PYTHON TRUE) + else() + set(LOOKUP_DEBUG_PYTHON FALSE) + endif() + find_python_libs_windows_helper(${LOOKUP_DEBUG_PYTHON} PYTHON_EXECUTABLE PYTHON_LIBRARY PYTHON_DLL PYTHON_VERSION_STRING) + if(LLDB_DISABLE_PYTHON) + set(LLDB_DISABLE_PYTHON 1 PARENT_SCOPE) + return() + endif() endif() - # Find the version of the Python interpreter. - execute_process(COMMAND "${PYTHON_EXE}" -c - "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" - OUTPUT_VARIABLE PYTHON_VERSION_OUTPUT - RESULT_VARIABLE PYTHON_VERSION_RESULT - ERROR_QUIET) - if(NOT PYTHON_VERSION_RESULT) - string(REPLACE ";" "." PYTHON_VERSION_STRING "${PYTHON_VERSION_OUTPUT}") - list(GET PYTHON_VERSION_OUTPUT 0 PYTHON_VERSION_MAJOR) - list(GET PYTHON_VERSION_OUTPUT 1 PYTHON_VERSION_MINOR) - list(GET PYTHON_VERSION_OUTPUT 2 PYTHON_VERSION_PATCH) + if(PYTHON_VERSION_STRING) + string(REPLACE "." ";" PYTHON_VERSION_PARTS "${PYTHON_VERSION_STRING}") + list(GET PYTHON_VERSION_PARTS 0 PYTHON_VERSION_MAJOR) + list(GET PYTHON_VERSION_PARTS 1 PYTHON_VERSION_MINOR) + list(GET PYTHON_VERSION_PARTS 2 PYTHON_VERSION_PATCH) + else() + unset(PYTHON_VERSION_MAJOR) + unset(PYTHON_VERSION_MINOR) + unset(PYTHON_VERSION_PATCH) endif() # Set the same variables as FindPythonInterp and FindPythonLibs. - set(PYTHON_EXECUTABLE ${PYTHON_EXE} PARENT_SCOPE) - set(PYTHON_LIBRARY ${PYTHON_LIB} PARENT_SCOPE) - set(PYTHON_DLL ${PYTHON_DLL} PARENT_SCOPE) - set(PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR} PARENT_SCOPE) - set(PYTHONLIBS_VERSION_STRING "${PYTHONLIBS_VERSION_STRING}" PARENT_SCOPE) - set(PYTHON_VERSION_STRING ${PYTHON_VERSION_STRING} PARENT_SCOPE) - set(PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} PARENT_SCOPE) - set(PYTHON_VERSION_MINOR ${PYTHON_VERSION_MINOR} PARENT_SCOPE) - set(PYTHON_VERSION_PATCH ${PYTHON_VERSION_PATCH} PARENT_SCOPE) + set(PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}" PARENT_SCOPE) + set(PYTHON_LIBRARY "${PYTHON_LIBRARY}" PARENT_SCOPE) + set(PYTHON_DLL "${PYTHON_DLL}" PARENT_SCOPE) + set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}" PARENT_SCOPE) + set(PYTHONLIBS_VERSION_STRING "${PYTHONLIBS_VERSION_STRING}" PARENT_SCOPE) + set(PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}" PARENT_SCOPE) + set(PYTHON_VERSION_MAJOR "${PYTHON_VERSION_MAJOR}" PARENT_SCOPE) + set(PYTHON_VERSION_MINOR "${PYTHON_VERSION_MINOR}" PARENT_SCOPE) + set(PYTHON_VERSION_PATCH "${PYTHON_VERSION_PATCH}" PARENT_SCOPE) message(STATUS "LLDB Found PythonExecutable: ${PYTHON_EXECUTABLE} (${PYTHON_VERSION_STRING})") - message(STATUS "LLDB Found PythonLibs: ${PYTHON_LIB} (${PYTHONLIBS_VERSION_STRING})") + message(STATUS "LLDB Found PythonLibs: ${PYTHON_LIBRARY} (${PYTHONLIBS_VERSION_STRING})") message(STATUS "LLDB Found PythonDLL: ${PYTHON_DLL}") message(STATUS "LLDB Found PythonIncludeDirs: ${PYTHON_INCLUDE_DIR}") endfunction(find_python_libs_windows)