Skip to content

Commit

Permalink
[py3] CMake updates to support Python3 and PyQt5
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Nov 16, 2015
1 parent 768bab8 commit 0b6dd35
Show file tree
Hide file tree
Showing 22 changed files with 239 additions and 73 deletions.
31 changes: 23 additions & 8 deletions CMakeLists.txt
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion cmake/FindPyQt4.cmake
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion cmake/FindPyQt.py → cmake/FindPyQt4.py
Expand Up @@ -60,7 +60,7 @@
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"):
Expand Down
56 changes: 56 additions & 0 deletions cmake/FindPyQt5.cmake
@@ -0,0 +1,56 @@
# Find PyQt5
# ~~~~~~~~~~
# Copyright (c) 2007-2008, Simon Edwards <simon@simonzone.com>
# 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)
75 changes: 75 additions & 0 deletions cmake/FindPyQt5.py
@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# 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 <simon@simonzone.com> 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 <simon@simonzone.com> ''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 <simon@simonzone.com> 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 <simon@simonzone.com>
# 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)
12 changes: 8 additions & 4 deletions cmake/FindPythonLibrary.cmake
Expand Up @@ -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(PYTHONINTERP_FOUND)
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)
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)
Expand All @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions cmake/FindQsci.cmake
@@ -1,4 +1,4 @@
# Find QScintilla2 PyQt4 module
# Find QScintilla2 PyQt module
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# QScintilla2 website: http://www.riverbankcomputing.co.uk/software/qscintilla/
Expand All @@ -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.
#
Expand Down Expand Up @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions cmake/FindQsci.py
Expand Up @@ -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.
Expand All @@ -39,6 +39,10 @@
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)

5 comments on commit 0b6dd35

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 0b6dd35 Nov 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-kuhn I get an error when running the "make install" command after making a qt4 qgis build:

CMake Error at python/PyQt/cmake_install.cmake:36 (file):
file INSTALL cannot find
"/home/webmaster/dev/cpp/QGIS/python/PyQt/QtWidgets.py".
Call Stack (most recent call first):
python/cmake_install.cmake:143 (include)
cmake_install.cmake:61 (include)

It should look for QtWidgets.py in the QGIS/python/PyQt/PyQt4 directory.

@tudorbarascu
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the same error, even after a clean install (deleted the build dir)

@mach0
Copy link
Member

@mach0 mach0 commented on 0b6dd35 Nov 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!
Same error here on debian 8 stable.
As already said it searches in
/home//dev/cpp/QGIS/python/PyQt/ for the files but on my debian machine with Qt4 AND Qt5 installed there are
/home//dev/cpp/QGIS/python/PyQt/PyQt4/ AND
/home//dev/cpp/QGIS/python/PyQt/PyQt5/ Directories and I guess according to the switch it should either search in PyQt4 or PyQt5 Directory than in the PyQt Dir below them ..

@m-kuhn
Copy link
Member Author

@m-kuhn m-kuhn commented on 0b6dd35 Nov 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if the latest commit on this branch fixes it: https://github.com/m-kuhn/QGIS/tree/installprefix

In particular, can you check that the files are installed in the end in the PyQt/ directory and not a PyQt/PyQt4 directory.

@m-kuhn
Copy link
Member Author

@m-kuhn m-kuhn commented on 0b6dd35 Nov 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request opened #2474

Please sign in to comment.