diff --git a/CMakeLists.txt b/CMakeLists.txt index 16826416986..a96051a49b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -674,27 +674,42 @@ ENDIF (UNIX AND NOT APPLE) ############################################################# # Python build dependency -FIND_PACKAGE(PythonInterp REQUIRED) +IF(ENABLE_QT5) + SET(PYTHON_VER 3) +ELSE(ENABLE_QT5) + SET(PYTHON_VER 2) +ENDIF(ENABLE_QT5) + +FIND_PACKAGE(PythonInterp ${PYTHON_VER} REQUIRED) ############################################################# # Python bindings IF (WITH_BINDINGS) - # python support: check for interpreter, sip, pyqt4 FIND_PACKAGE(PythonLibrary REQUIRED) + + # python support: check for interpreter, sip, pyqt4 + IF(ENABLE_QT5) + FIND_PACKAGE(PyQt5 REQUIRED) + SET(PYQT_SIP_FLAGS ${PYQT5_SIP_FLAGS}) + SET(PYQT_SIP_DIR ${PYQT5_SIP_DIR}) + ELSE(ENABLE_QT5) + FIND_PACKAGE(PyQt4 REQUIRED) + # setup SIP variables + SET(PYQT_SIP_FLAGS ${PYQT4_SIP_FLAGS}) + SET(PYQT_SIP_DIR ${PYQT4_SIP_DIR}) + ENDIF(ENABLE_QT5) + SEPARATE_ARGUMENTS(PYQT_SIP_FLAGS) # convert space separated values to a list + FIND_PACKAGE(SIP REQUIRED) - FIND_PACKAGE(PyQt4 REQUIRED) FIND_PACKAGE(Qsci REQUIRED) INCLUDE(PythonMacros) + INCLUDE(PyQtMacros) INCLUDE(SIPMacros) - INCLUDE(PyQt4Macros) - # setup SIP variables - SEPARATE_ARGUMENTS(PYQT4_SIP_FLAGS) # convert space separated values to a list - SET(SIP_INCLUDES ${PYQT4_SIP_DIR} ${CMAKE_SOURCE_DIR}/python) + SET(SIP_INCLUDES ${PYQT_SIP_DIR} ${CMAKE_SOURCE_DIR}/python) SET(SIP_CONCAT_PARTS 4) - SET(SIP_EXTRA_OPTIONS ${PYQT4_SIP_FLAGS}) IF (NOT BINDINGS_GLOBAL_INSTALL) SET(PYTHON_SITE_PACKAGES_DIR ${QGIS_DATA_DIR}/python) diff --git a/cmake/FindPyQt4.cmake b/cmake/FindPyQt4.cmake index 0f34365c658..8bf90f4c878 100644 --- a/cmake/FindPyQt4.cmake +++ b/cmake/FindPyQt4.cmake @@ -27,7 +27,7 @@ IF(EXISTS PYQT4_VERSION) SET(PYQT4_FOUND TRUE) ELSE(EXISTS PYQT4_VERSION) - FIND_FILE(_find_pyqt_py FindPyQt.py PATHS ${CMAKE_MODULE_PATH}) + FIND_FILE(_find_pyqt_py FindPyQt4.py PATHS ${CMAKE_MODULE_PATH}) EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} OUTPUT_VARIABLE pyqt_config) IF(pyqt_config) diff --git a/cmake/FindPyQt.py b/cmake/FindPyQt4.py similarity index 99% rename from cmake/FindPyQt.py rename to cmake/FindPyQt4.py index 96bbbae20fa..a4fb88bba73 100644 --- a/cmake/FindPyQt.py +++ b/cmake/FindPyQt4.py @@ -60,7 +60,7 @@ print("pyqt_version_str:%s" % pyqtcfg.pyqt_version_str) pyqt_version_tag = "" in_t = False for item in pyqtcfg.pyqt_sip_flags.split(' '): - if item=="-t": + if item == "-t": in_t = True elif in_t: if item.startswith("Qt_4"): diff --git a/cmake/FindPyQt5.cmake b/cmake/FindPyQt5.cmake new file mode 100644 index 00000000000..eee0b827cbe --- /dev/null +++ b/cmake/FindPyQt5.cmake @@ -0,0 +1,56 @@ +# Find PyQt5 +# ~~~~~~~~~~ +# Copyright (c) 2007-2008, Simon Edwards +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# PyQt5 website: http://www.riverbankcomputing.co.uk/pyqt/index.php +# +# Find the installed version of PyQt5. FindPyQt5 should only be called after +# Python has been found. +# +# This file defines the following variables: +# +# PYQT5_VERSION - The version of PyQt5 found expressed as a 6 digit hex number +# suitable for comparision as a string +# +# PYQT5_VERSION_STR - The version of PyQt5 as a human readable string. +# +# PYQT5_VERSION_TAG - The PyQt version tag using by PyQt's sip files. +# +# PYQT5_SIP_DIR - The directory holding the PyQt5 .sip files. +# +# PYQT5_SIP_FLAGS - The SIP flags used to build PyQt. + +IF(EXISTS PYQT5_VERSION) + # Already in cache, be silent + SET(PYQT5_FOUND TRUE) +ELSE(EXISTS PYQT5_VERSION) + + FIND_FILE(_find_pyqt_py FindPyQt5.py PATHS ${CMAKE_MODULE_PATH}) + + EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} OUTPUT_VARIABLE pyqt_config) + IF(pyqt_config) + STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT5_VERSION ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT5_VERSION_STR ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT5_VERSION_TAG ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_version_num:([^\n]+).*$" "\\1" PYQT5_VERSION_NUM ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_mod_dir:([^\n]+).*$" "\\1" PYQT5_MOD_DIR ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT5_SIP_DIR ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT5_SIP_FLAGS ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_bin_dir:([^\n]+).*$" "\\1" PYQT5_BIN_DIR ${pyqt_config}) + + SET(PYQT5_FOUND TRUE) + ENDIF(pyqt_config) + + IF(PYQT5_FOUND) + IF(NOT PYQT5_FIND_QUIETLY) + MESSAGE(STATUS "Found PyQt5 version: ${PYQT5_VERSION_STR}") + ENDIF(NOT PYQT5_FIND_QUIETLY) + ELSE(PYQT5_FOUND) + IF(PYQT5_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Python") + ENDIF(PYQT5_FIND_REQUIRED) + ENDIF(PYQT5_FOUND) + +ENDIF(EXISTS PYQT5_VERSION) diff --git a/cmake/FindPyQt5.py b/cmake/FindPyQt5.py new file mode 100644 index 00000000000..6fb69c7c118 --- /dev/null +++ b/cmake/FindPyQt5.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2007, Simon Edwards +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Simon Edwards nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY Simon Edwards ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL Simon Edwards BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# FindPyQt.py +# Copyright (c) 2007, Simon Edwards +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +try: + import PyQt5.pyqtconfig + pyqtcfg = PyQt5.pyqtconfig.Configuration() +except ImportError: + import PyQt5.QtCore + import sipconfig # won't work for SIP v5 + import os.path + cfg = sipconfig.Configuration() + sip_dir = cfg.default_sip_dir + for p in (os.path.join(sip_dir, "PyQt5"), sip_dir): + if os.path.exists(os.path.join(p, "QtCore", "QtCoremod.sip")): + sip_dir = p + break + cfg = { + 'pyqt_version': PyQt5.QtCore.PYQT_VERSION, + 'pyqt_version_str': PyQt5.QtCore.PYQT_VERSION_STR, + 'pyqt_sip_flags': PyQt5.QtCore.PYQT_CONFIGURATION['sip_flags'], + 'pyqt_mod_dir': cfg.default_mod_dir, + 'pyqt_sip_dir': sip_dir, + 'pyqt_bin_dir': cfg.default_bin_dir, + } + pyqtcfg = sipconfig.Configuration([cfg]) + +print("pyqt_version:%06.0x" % pyqtcfg.pyqt_version) +print("pyqt_version_num:%d" % pyqtcfg.pyqt_version) +print("pyqt_version_str:%s" % pyqtcfg.pyqt_version_str) + +pyqt_version_tag = "" +in_t = False +for item in pyqtcfg.pyqt_sip_flags.split(' '): + if item == "-t": + in_t = True + elif in_t: + if item.startswith("Qt_4"): + pyqt_version_tag = item + else: + in_t = False +print("pyqt_version_tag:%s" % pyqt_version_tag) + +print("pyqt_mod_dir:%s" % pyqtcfg.pyqt_mod_dir) +print("pyqt_sip_dir:%s" % pyqtcfg.pyqt_sip_dir) +print("pyqt_sip_flags:%s" % pyqtcfg.pyqt_sip_flags) +print("pyqt_bin_dir:%s" % pyqtcfg.pyqt_bin_dir) diff --git a/cmake/FindPythonLibrary.cmake b/cmake/FindPythonLibrary.cmake index 810dccbec8a..4c2adcc9726 100644 --- a/cmake/FindPythonLibrary.cmake +++ b/cmake/FindPythonLibrary.cmake @@ -44,11 +44,15 @@ else(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS " endif("${PYTHON_CUSTOM_FRAMEWORK}" MATCHES "Python\\.framework") endif(APPLE AND PYTHON_CUSTOM_FRAMEWORK) - FIND_PACKAGE(PythonInterp) + IF (ENABLE_QT5) + FIND_PACKAGE(PythonInterp 3) + ADD_DEFINITIONS(-DPYTHON3) + ELSE (ENABLE_QT5) + FIND_PACKAGE(PythonInterp 2) + ADD_DEFINITIONS(-DPYTHON2) + ENDIF (ENABLE_QT5) if(PYTHONINTERP_FOUND) - ADD_DEFINITIONS(-DPYTHON2) - FIND_FILE(_find_lib_python_py FindLibPython.py PATHS ${CMAKE_MODULE_PATH}) EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_lib_python_py} OUTPUT_VARIABLE python_config) @@ -65,7 +69,7 @@ else(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS " endif(NOT PYTHON_LIBS_WITH_KDE_LIBS) endif(NOT PYTHON_SITE_PACKAGES_DIR) STRING(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_SHORT_VERSION_NO_DOT ${PYTHON_SHORT_VERSION}) - set(PYTHON_LIBRARY_NAMES python${PYTHON_SHORT_VERSION} python${PYTHON_SHORT_VERSION_NO_DOT}) + set(PYTHON_LIBRARY_NAMES python${PYTHON_SHORT_VERSION} python${PYTHON_SHORT_VERSION_NO_DOT} python${PYTHON_SHORT_VERSION}m python${PYTHON_SHORT_VERSION_NO_DOT}m) if(WIN32) STRING(REPLACE "\\" "/" PYTHON_SITE_PACKAGES_DIR ${PYTHON_SITE_PACKAGES_DIR}) endif(WIN32) diff --git a/cmake/FindQsci.cmake b/cmake/FindQsci.cmake index 6dedc222f4c..6ef1f65842d 100644 --- a/cmake/FindQsci.cmake +++ b/cmake/FindQsci.cmake @@ -1,4 +1,4 @@ -# Find QScintilla2 PyQt4 module +# Find QScintilla2 PyQt module # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # QScintilla2 website: http://www.riverbankcomputing.co.uk/software/qscintilla/ @@ -8,7 +8,7 @@ # # This file defines the following variables: # -# QSCI_FOUND - system has QScintilla2 PyQt4 module +# QSCI_FOUND - system has QScintilla2 PyQt module # # QSCI_MOD_VERSION_STR - The version of Qsci module as a human readable string. # @@ -37,11 +37,11 @@ ELSE(EXISTS QSCI_MOD_VERSION_STR) ) IF(NOT QSCI_FIND_QUIETLY) - MESSAGE(STATUS "Found QScintilla2 PyQt4 module: ${QSCI_MOD_VERSION_STR}") + MESSAGE(STATUS "Found QScintilla2 PyQt module: ${QSCI_MOD_VERSION_STR}") ENDIF(NOT QSCI_FIND_QUIETLY) ELSE(QSCI_FOUND) IF(QSCI_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find QScintilla2 PyQt4 module") + MESSAGE(FATAL_ERROR "Could not find QScintilla2 PyQt module") ENDIF(QSCI_FIND_REQUIRED) ENDIF(QSCI_FOUND) diff --git a/cmake/FindQsci.py b/cmake/FindQsci.py index 323854626a4..69c28c2ec47 100644 --- a/cmake/FindQsci.py +++ b/cmake/FindQsci.py @@ -25,7 +25,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -"""Find QScintilla2 PyQt4 module version. +"""Find QScintilla2 PyQt4/PyQt5 module version. .. note:: Redistribution and use is allowed according to the terms of the BSD license. For details see the accompanying COPYING-CMAKE-SCRIPTS file. @@ -39,6 +39,10 @@ try: from PyQt4.Qsci import QSCINTILLA_VERSION_STR VER = QSCINTILLA_VERSION_STR except ImportError: - VER = "" + try: + from PyQt5.Qsci import QSCINTILLA_VERSION_STR + VER = QSCINTILLA_VERSION_STR + except ImportError: + VER = "" print("qsci_version_str:%s" % VER) diff --git a/cmake/PyQt4Macros.cmake b/cmake/PyQtMacros.cmake similarity index 54% rename from cmake/PyQt4Macros.cmake rename to cmake/PyQtMacros.cmake index 2e0fae3f375..e5254db3fba 100644 --- a/cmake/PyQt4Macros.cmake +++ b/cmake/PyQtMacros.cmake @@ -1,34 +1,43 @@ -# Macros for PyQt4 +# Macros for PyQt # ~~~~~~~~~~~~~~~~ # Copyright (c) 2009, Juergen E. Fischer # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. +IF(ENABLE_QT5) + SET(PYUIC_PROG_NAME pyuic5) + SET(PYUIC_PROG_NAMES pyuic5) + SET(PYRCC_PROG_NAME pyrcc5) +ELSE(ENABLE_QT5) + SET(PYUIC_PROG_NAME pyuic4) + SET(PYUIC_PROG_NAMES python2-pyuic4 pyuic4) + SET(PYRCC_PROG_NAME pyrcc4) +ENDIF(ENABLE_QT5) -IF(NOT PYUIC4_PROGRAM) +IF(NOT PYUIC_PROGRAM) IF (MSVC) - FIND_PROGRAM(PYUIC4_PROGRAM - NAMES pyuic4.bat + FIND_PROGRAM(PYUIC_PROGRAM + NAMES ${PYUIC_PROG_NAME}.bat PATHS $ENV{LIB_DIR}/bin ) ELSE(MSVC) - FIND_PROGRAM(PYUIC4_PROGRAM NAMES python2-pyuic4 pyuic4) + FIND_PROGRAM(PYUIC_PROGRAM NAMES ${PYUIC_PROG_NAMES}) ENDIF (MSVC) - IF (NOT PYUIC4_PROGRAM) - MESSAGE(FATAL_ERROR "pyuic4 not found - aborting") - ENDIF (NOT PYUIC4_PROGRAM) -ENDIF(NOT PYUIC4_PROGRAM) + IF (NOT PYUIC_PROGRAM) + MESSAGE(FATAL_ERROR "pyuic[4|5] not found - aborting") + ENDIF (NOT PYUIC_PROGRAM) +ENDIF(NOT PYUIC_PROGRAM) # Adapted from QT4_WRAP_UI -MACRO(PYQT4_WRAP_UI outfiles ) +MACRO(PYQT_WRAP_UI outfiles ) IF(WIN32) - SET(PYUIC4_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic4-wrapper.bat") - SET(PYUIC4_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/bin/${CMAKE_BUILD_TYPE}") + SET(PYUIC_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/${PYUIC_PROG_NAME}-wrapper.bat") + SET(PYUIC_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/bin/${CMAKE_BUILD_TYPE}") ELSE(WIN32) # TODO osx - SET(PYUIC4_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic4-wrapper.sh") - SET(PYUIC4_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/lib") + SET(PYUIC_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic4-wrapper.sh") + SET(PYUIC_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/lib") ENDIF(WIN32) FOREACH(it ${ARGN}) @@ -36,37 +45,37 @@ MACRO(PYQT4_WRAP_UI outfiles ) GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py) ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${PYUIC4_WRAPPER} "${PYUIC4_PROGRAM}" "${PYUIC4_WRAPPER_PATH}" "${QGIS_OUTPUT_DIRECTORY}/python" ${infile} -o ${outfile} - MAIN_DEPENDENCY ${infile} + COMMAND ${PYUIC_WRAPPER} "${PYUIC_PROGRAM}" "${PYUIC_WRAPPER_PATH}" "${QGIS_OUTPUT_DIRECTORY}/python" ${infile} -o ${outfile} + MAIN_DEPENDENCY ${infile} DEPENDS pygui pycore ) SET(${outfiles} ${${outfiles}} ${outfile}) ENDFOREACH(it) -ENDMACRO(PYQT4_WRAP_UI) +ENDMACRO(PYQT_WRAP_UI) -IF(NOT PYRCC4_PROGRAM) +IF(NOT PYRCC_PROGRAM) IF (MSVC) - FIND_PROGRAM(PYRCC4_PROGRAM - NAMES pyrcc4.exe + FIND_PROGRAM(PYRCC_PROGRAM + NAMES ${PYUIC_PROG_NAME}.exe PATHS $ENV{LIB_DIR}/bin ) ELSE(MSVC) - FIND_PROGRAM(PYRCC4_PROGRAM pyrcc4) + FIND_PROGRAM(PYRCC_PROGRAM ${PYRCC_PROG_NAME}) ENDIF (MSVC) - IF (NOT PYRCC4_PROGRAM) - MESSAGE(FATAL_ERROR "pyrcc4 not found - aborting") - ENDIF (NOT PYRCC4_PROGRAM) -ENDIF(NOT PYRCC4_PROGRAM) + IF (NOT PYRCC_PROGRAM) + MESSAGE(FATAL_ERROR "pyrcc[4|5] not found - aborting") + ENDIF (NOT PYRCC_PROGRAM) +ENDIF(NOT PYRCC_PROGRAM) # Adapted from QT4_ADD_RESOURCES -MACRO (PYQT4_ADD_RESOURCES outfiles ) +MACRO (PYQT_ADD_RESOURCES outfiles ) FOREACH (it ${ARGN}) GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) GET_FILENAME_COMPONENT(rc_path ${infile} PATH) SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py) - # parse file for dependencies + # parse file for dependencies # all files are absolute paths or relative to the location of the qrc file FILE(READ "${infile}" _RC_FILE_CONTENTS) STRING(REGEX MATCHALL "