Refactor and fixes Python binding

Python binding was broke since commit b1f37a8.
This is a fix and to some degree a refactor.
The binding build is now integrated. Controlled by the CMake
QTERMWIDGET_BUILD_PYTHON_BINDING option.

CMake components taken from https://cgit.kde.org/pykde5.git/. No need to
reinvent the wheel.

Closes https://github.com/lxqt/qtermwidget/issues/135.
This commit is contained in:
Luís Pereira
2018-04-24 11:42:10 +01:00
committed by Alf Gaida
parent 4cc05f9899
commit 3ba895f573
17 changed files with 537 additions and 226 deletions
+7
View File
@@ -14,6 +14,7 @@ set(LXQTBT_MINIMUM_VERSION "0.4.1")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
option(BUILD_EXAMPLE "Build example application. Default OFF." OFF)
option(QTERMWIDGET_USE_UTEMPTER "Uses the libutempter library. Mainly for FreeBSD" OFF)
option(QTERMWIDGET_BUILD_PYTHON_BINDING "Build python binding" OFF)
# just change version for releases
set(QTERMWIDGET_VERSION_MAJOR "0")
@@ -304,6 +305,12 @@ if(BUILD_EXAMPLE)
endif()
# end of example application
# python binding
if (QTERMWIDGET_BUILD_PYTHON_BINDING)
add_subdirectory(pyqt)
endif()
# end of python binding
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+61
View File
@@ -0,0 +1,61 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Match what's used in the main macros
cmake_policy(SET CMP0002 OLD)
find_package(PythonLibrary)
include(PythonMacros)
find_package(SIP)
include(SIPMacros)
if(SIP_VERSION STRLESS "040f03") # These version numbers also appear in ../CMakeLists.txt
message(FATAL_ERROR "The version of SIP found is too old. 4.15.3 or later is needed.")
endif()
find_package(PyQt5)
if(PYQT5_VERSION STRLESS "050101") # These version numbers also appear in ../CMakeLists.txt
message(FATAL_ERROR "The version of PyQt found is too old. 5.1.1 or later is required.")
endif()
set(SIP_INCLUDES ${PYQT5_SIP_DIR} sip)
set(SIP_CONCAT_PARTS 8)
set(SIP_TAGS ALL WS_X11 ${PYQT5_VERSION_TAG})
set(SIP_DISABLE_FEATURES VendorID PyQt_NoPrintRangeBug)
# Use an extra option when compiling on Python 3.
if (PYTHON_VERSION_MAJOR GREATER 2)
if(PYQT5_VERSION STRGREATER "040904")
# Disable for newer PyQt
set(SIP_EXTRA_OPTIONS -P -g)
else ()
set(SIP_EXTRA_OPTIONS -g)
endif()
else (PYTHON_VERSION_MAJOR GREATER 2)
if(PYQT5_VERSION STRGREATER "040904")
# Disable for newer PyQt
set(SIP_EXTRA_OPTIONS -P -g -x Py_v3)
else ()
set(SIP_EXTRA_OPTIONS -g -x Py_v3)
endif()
endif ()
include_directories(
"${SIP_INCLUDE_DIR}"
)
add_definitions(-D_REENTRANT -DSIP_PROTECTED_IS_PUBLIC -Dprotected=public)
file(GLOB qtermwidget_files_sip sip/*.sip)
set(SIP_EXTRA_FILES_DEPEND "${qtermwidget_files_sip}")
add_sip_python_module(QTermWidget sip/qtermwidget.sip qtermwidget5)
python_install(__init__.py "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/PyQt5/qtermwidget")
set (SIP_FILES_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/sip")
install(DIRECTORY sip/ DESTINATION "${SIP_FILES_INSTALL_DIR}/PyQt5/qtermwidget"
PATTERN "*~" EXCLUDE # This sucks, why can't I just whitelist what I _do_ want?
PATTERN ".svn" EXCLUDE
PATTERN "*.in" EXCLUDE
)
-36
View File
@@ -1,36 +0,0 @@
PyQt5 Bindings for QTermWidget
==============================
INSTALL:
------------
####1. Download, compile and install QTermWidget:
$ git clone https://github.com/lxqt/qtermwidget.git
$ cd qtermwidget && mkdir build && cd build
$ cmake ..
$ make
$ sudo make install
If `make install` command will not work just copy the `qtermwidget.so*` files to /usr/lib directory.
####2. Install PyQt5 and PyQt5-devel if not yet installed.
####3. Configure, compile and install Python bindings. Execute in terminal in the qtermwidget bindings folder:
$ cd pyqt/
$ QT_SELECT=5 python config.py
$ make
$ sudo make install
####4. You can run ./test.py to test the installed module.
ABOUT:
---------
Curently maintained by:
- Pawel Koston <pawelkoston@gmail.com>
Based on previous PyQt4 bindings by:
- Piotr "Riklaunim" Maliński <riklaunim@gmail.com>,
- Alexander Slesarev <alex.slesarev@gmail.com>
PyQt5 QTermWidget Bindings
License: GPL3
+22
View File
@@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+53
View File
@@ -0,0 +1,53 @@
# Find PyQt5
# ~~~~~~~~~~
# Copyright (c) 2014, 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 comparison 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_pyqt5_py FindPyQt5.py PATHS ${CMAKE_MODULE_PATH})
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt5_py} OUTPUT_VARIABLE pyqt5_config)
IF(pyqt5_config)
STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT5_VERSION ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT5_VERSION_STR ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT5_VERSION_TAG ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT5_SIP_DIR ${pyqt5_config})
STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT5_SIP_FLAGS ${pyqt5_config})
SET(PYQT5_FOUND TRUE)
ENDIF(pyqt5_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 PyQt5.")
ENDIF(PYQT5_FIND_REQUIRED)
ENDIF(PYQT5_FOUND)
ENDIF(EXISTS PYQT5_VERSION)
+28
View File
@@ -0,0 +1,28 @@
# Copyright (c) 2014, 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.
import PyQt5.Qt
import sys
import os.path
print("pyqt_version:%06.0x" % PyQt5.Qt.PYQT_VERSION)
print("pyqt_version_str:%s" % PyQt5.Qt.PYQT_VERSION_STR)
pyqt_version_tag = ""
in_t = False
for item in PyQt5.Qt.PYQT_CONFIGURATION["sip_flags"].split(' '):
if item=="-t":
in_t = True
elif in_t:
if item.startswith("Qt_5"):
pyqt_version_tag = item
else:
in_t = False
print("pyqt_version_tag:%s" % pyqt_version_tag)
# FIXME This next line is just a little bit too crude.
pyqt_sip_dir = os.path.join(sys.prefix, "share", "sip", "PyQt5")
print("pyqt_sip_dir:%s" % pyqt_sip_dir)
print("pyqt_sip_flags:%s" % PyQt5.Qt.PYQT_CONFIGURATION["sip_flags"])
+73
View File
@@ -0,0 +1,73 @@
# Find Python
# ~~~~~~~~~~~
# Find the Python interpreter and related Python directories.
#
# This file defines the following variables:
#
# PYTHON_EXECUTABLE - The path and filename of the Python interpreter.
#
# PYTHON_SHORT_VERSION - The version of the Python interpreter found,
# excluding the patch version number. (e.g. 2.5 and not 2.5.1))
#
# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human
# readable string.
#
# PYTHON_SITE_PACKAGES_INSTALL_DIR - this cache variable can be used for installing
# own python modules. You may want to adjust this to be the
# same as ${PYTHON_SITE_PACKAGES_DIR}, but then admin
# privileges may be required for installation.
#
# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory.
#
# PYTHON_INCLUDE_PATH - Directory holding the python.h include file.
#
# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library.
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
include(FindPackageHandleStandardArgs)
find_package(PythonInterp)
if (PYTHONINTERP_FOUND)
option(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX "Install the Python files in the Python packages dir" FALSE)
# Set the Python libraries to what we actually found for interpreters
set(Python_ADDITIONAL_VERSIONS "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
# These are kept for compatibility
set(PYTHON_SHORT_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
set(PYTHON_LONG_VERSION ${PYTHON_VERSION_STRING})
find_package(PythonLibs QUIET)
if(PYTHONLIBS_FOUND)
set(PYTHON_LIBRARY ${PYTHON_LIBRARIES})
endif(PYTHONLIBS_FOUND)
# Auto detect Python site-packages directory
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Python system site-packages directory: ${PYTHON_SITE_PACKAGES_DIR}")
if(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX)
set(PYTHON_SITE_PACKAGES_INSTALL_DIR ${PYTHON_SITE_PACKAGES_DIR})
else()
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True, prefix='${CMAKE_INSTALL_PREFIX}'))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_INSTALL_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
if(NOT PYTHON_SITE_PACKAGES_INSTALL_DIR STREQUAL PYTHON_SITE_PACKAGES_DIR)
message(STATUS "The Python files will be installed to ${PYTHON_SITE_PACKAGES_INSTALL_DIR}. Make sure to add them to the Python search path (e.g. by setting PYTHONPATH)")
endif()
endif(PYTHONINTERP_FOUND)
find_package_handle_standard_args(PythonLibrary DEFAULT_MSG PYTHON_LIBRARY)
+64
View File
@@ -0,0 +1,64 @@
# Find SIP
# ~~~~~~~~
#
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
#
# Find the installed version of SIP. FindSIP should be called after Python
# has been found.
#
# This file defines the following variables:
#
# SIP_VERSION - The version of SIP found expressed as a 6 digit hex number
# suitable for comparison as a string.
#
# SIP_VERSION_STR - The version of SIP found as a human readable string.
#
# SIP_EXECUTABLE - Path and filename of the SIP command line executable.
#
# SIP_INCLUDE_DIR - Directory holding the SIP C++ header file.
#
# SIP_DEFAULT_SIP_DIR - Default directory where .sip files should be installed
# into.
# 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.
IF(SIP_VERSION)
# Already in cache, be silent
SET(SIP_FOUND TRUE)
ELSE(SIP_VERSION)
FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_sip_py} OUTPUT_VARIABLE sip_config)
IF(sip_config)
STRING(REGEX REPLACE "^sip_version:([^\n]+).*$" "\\1" SIP_VERSION ${sip_config})
STRING(REGEX REPLACE ".*\nsip_version_str:([^\n]+).*$" "\\1" SIP_VERSION_STR ${sip_config})
STRING(REGEX REPLACE ".*\nsip_bin:([^\n]+).*$" "\\1" SIP_EXECUTABLE ${sip_config})
IF(NOT SIP_DEFAULT_SIP_DIR)
STRING(REGEX REPLACE ".*\ndefault_sip_dir:([^\n]+).*$" "\\1" SIP_DEFAULT_SIP_DIR ${sip_config})
ENDIF(NOT SIP_DEFAULT_SIP_DIR)
STRING(REGEX REPLACE ".*\nsip_inc_dir:([^\n]+).*$" "\\1" SIP_INCLUDE_DIR ${sip_config})
FILE(TO_CMAKE_PATH ${SIP_DEFAULT_SIP_DIR} SIP_DEFAULT_SIP_DIR)
FILE(TO_CMAKE_PATH ${SIP_INCLUDE_DIR} SIP_INCLUDE_DIR)
IF(EXISTS ${SIP_EXECUTABLE})
SET(SIP_FOUND TRUE)
ELSE()
MESSAGE(STATUS "Found SIP configuration but the sip executable could not be found.")
ENDIF()
ENDIF(sip_config)
IF(SIP_FOUND)
IF(NOT SIP_FIND_QUIETLY)
MESSAGE(STATUS "Found SIP version: ${SIP_VERSION_STR}")
ENDIF(NOT SIP_FIND_QUIETLY)
ELSE(SIP_FOUND)
IF(SIP_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find SIP")
ENDIF(SIP_FIND_REQUIRED)
ENDIF(SIP_FOUND)
ENDIF(SIP_VERSION)
+15
View File
@@ -0,0 +1,15 @@
# FindSIP.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.
import sys
import sipconfig
sipcfg = sipconfig.Configuration()
print("sip_version:%06.0x" % sipcfg.sip_version)
print("sip_version_str:%s" % sipcfg.sip_version_str)
print("sip_bin:%s" % sipcfg.sip_bin)
print("default_sip_dir:%s" % sipcfg.default_sip_dir)
print("sip_inc_dir:%s" % sipcfg.sip_inc_dir)
+4
View File
@@ -0,0 +1,4 @@
# By Simon Edwards <simon@simonzone.com>
# This file is in the public domain.
import py_compile, sys
sys.exit(py_compile.main())
+82
View File
@@ -0,0 +1,82 @@
# Python macros
# ~~~~~~~~~~~~~
# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
# Copyright (c) 2012, Rolf Eike Beer <eike@sf-mail.de>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# This file defines the following macros:
#
# PYTHON_INSTALL (SOURCE_FILE DESTINATION_DIR)
# Install the SOURCE_FILE, which is a Python .py file, into the
# destination directory during install. The file will be byte compiled
# and both the .py file and .pyc file will be installed.
set(PYTHON_MACROS_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
macro(PYTHON_INSTALL SOURCE_FILE DESTINATION_DIR)
find_file(_python_compile_py PythonCompile.py PATHS ${CMAKE_MODULE_PATH})
# Install the source file.
install(FILES ${SOURCE_FILE} DESTINATION ${DESTINATION_DIR})
# Byte compile and install the .pyc file, unless explicitly prevented by env..
if("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
get_filename_component(_absfilename ${SOURCE_FILE} ABSOLUTE)
get_filename_component(_filename ${SOURCE_FILE} NAME)
get_filename_component(_filenamebase ${SOURCE_FILE} NAME_WE)
get_filename_component(_basepath ${SOURCE_FILE} PATH)
if(WIN32)
# remove drive letter
string(REGEX REPLACE "^[a-zA-Z]:/" "/" _basepath "${_basepath}")
endif(WIN32)
set(_bin_py ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filename})
# Python 3.2 changed the pyc file location
if(PYTHON_VERSION_STRING VERSION_GREATER 3.1)
# To get the right version for suffix
set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/__pycache__/${_filenamebase}.cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}.pyc")
set(_py_install_dir "${DESTINATION_DIR}/__pycache__/")
else()
set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filenamebase}.pyc")
set(_py_install_dir "${DESTINATION_DIR}")
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_basepath})
# Setting because it will be displayed later, in compile_python_files
set(_message "Byte-compiling ${_bin_py} to ${_bin_pyc}")
string(REPLACE "/" "_" _rule_name "${_basepath}/${_bin_pyc}")
add_custom_target("${_rule_name}" ALL)
get_filename_component(_abs_bin_py ${_bin_py} ABSOLUTE)
if(_abs_bin_py STREQUAL _absfilename) # Don't copy the file onto itself.
add_custom_command(
TARGET "${_rule_name}"
COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
DEPENDS "${_absfilename}"
)
else()
add_custom_command(
TARGET "${_rule_name}"
COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
COMMAND "${CMAKE_COMMAND}" -E copy "${_absfilename}" "${_bin_py}"
COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
DEPENDS "${_absfilename}"
)
endif()
install(FILES ${_bin_pyc} DESTINATION "${_py_install_dir}")
unset(_py_install_dir)
unset(_message)
endif("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
endmacro(PYTHON_INSTALL)
+124
View File
@@ -0,0 +1,124 @@
# Macros for SIP
# ~~~~~~~~~~~~~~
# 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.
#
# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
#
# This file defines the following macros:
#
# ADD_SIP_PYTHON_MODULE (MODULE_NAME MODULE_SIP [library1, libaray2, ...])
# Specifies a SIP file to be built into a Python module and installed.
# MODULE_NAME is the name of Python module including any path name. (e.g.
# os.sys, Foo.bar etc). MODULE_SIP the path and filename of the .sip file
# to process and compile. libraryN are libraries that the Python module,
# which is typically a shared library, should be linked to. The built
# module will also be install into Python's site-packages directory.
#
# The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a
# number of variables:
#
# SIP_INCLUDES - List of directories which SIP will scan through when looking
# for included .sip files. (Corresponds to the -I option for SIP.)
#
# SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t
# option for SIP.)
#
# SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code
# of each module should be split into. Defaults to 8. (Corresponds to the
# -j option for SIP.)
#
# SIP_DISABLE_FEATURES - List of feature names which should be disabled
# running SIP. (Corresponds to the -x option for SIP.)
#
# SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to
# SIP.
SET(SIP_INCLUDES)
SET(SIP_TAGS)
SET(SIP_CONCAT_PARTS 8)
SET(SIP_DISABLE_FEATURES)
SET(SIP_EXTRA_OPTIONS)
MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP)
SET(EXTRA_LINK_LIBRARIES ${ARGN})
STRING(REPLACE "." "/" _x ${MODULE_NAME})
GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH)
GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME)
GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH)
if(_module_path STREQUAL "")
set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
else(_module_path STREQUAL "")
set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_module_path}")
endif(_module_path STREQUAL "")
GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE)
# We give this target a long logical target name.
# (This is to avoid having the library name clash with any already
# install library names. If that happens then cmake dependancy
# tracking get confused.)
STRING(REPLACE "." "_" _logical_name ${MODULE_NAME})
SET(_logical_name "python_module_${_logical_name}")
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SIP_OUTPUT_DIR}) # Output goes in this dir.
SET(_sip_includes)
FOREACH (_inc ${SIP_INCLUDES})
GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE)
LIST(APPEND _sip_includes -I ${_abs_inc})
ENDFOREACH (_inc )
SET(_sip_tags)
FOREACH (_tag ${SIP_TAGS})
LIST(APPEND _sip_tags -t ${_tag})
ENDFOREACH (_tag)
SET(_sip_x)
FOREACH (_x ${SIP_DISABLE_FEATURES})
LIST(APPEND _sip_x -x ${_x})
ENDFOREACH (_x ${SIP_DISABLE_FEATURES})
SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}")
SET(_sip_output_files)
FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_SIP_OUTPUT_DIR}/sip${_child_module_name}part${CONCAT_NUM}.cpp )
ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
IF(NOT WIN32)
SET(TOUCH_COMMAND touch)
ELSE(NOT WIN32)
SET(TOUCH_COMMAND echo)
# instead of a touch command, give out the name and append to the files
# this is basically what the touch command does.
FOREACH(filename ${_sip_output_files})
FILE(APPEND filename "")
ENDFOREACH(filename ${_sip_output_files})
ENDIF(NOT WIN32)
ADD_CUSTOM_COMMAND(
OUTPUT ${_sip_output_files}
COMMAND ${CMAKE_COMMAND} -E echo ${message}
COMMAND ${TOUCH_COMMAND} ${_sip_output_files}
COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_SIP_OUTPUT_DIR} ${_sip_includes} ${_abs_module_sip}
DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND}
)
# not sure if type MODULE could be uses anywhere, limit to cygwin for now
IF (CYGWIN)
ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} )
ELSE (CYGWIN)
ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} )
ENDIF (CYGWIN)
TARGET_LINK_LIBRARIES(${_logical_name} ${PYTHON_LIBRARY})
TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES})
SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name})
INSTALL(TARGETS ${_logical_name} DESTINATION "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/${_parent_module_path}")
ENDMACRO(ADD_SIP_PYTHON_MODULE)
-85
View File
@@ -1,85 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# PyQt4 bindings for th QTermWidget project.
#
# Copyright (C) 2009 Piotr "Riklaunim" Maliński <riklaunim@gmail.com>,
# Alexander Slesarev <alex.slesarev@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sipconfig
from PyQt4 import pyqtconfig
# The name of the SIP build file generated by SIP and used by the build
# system.
build_file = "qtermwidget.sbf"
# Get the PyQt configuration information.
config = pyqtconfig.Configuration()
# Get the extra SIP flags needed by the imported qt module. Note that
# this normally only includes those flags (-x and -t) that relate to SIP's
# versioning system.
qt_sip_flags = config.pyqt_sip_flags
# Run SIP to generate the code. Note that we tell SIP where to find the qt
# module's specification files using the -I flag.
os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I",
config.pyqt_sip_dir, qt_sip_flags, "qtermwidget.sip"]))
# We are going to install the SIP specification file for this module and
# its configuration module.
installs = []
installs.append(["qtermwidget.sip", os.path.join(config.default_sip_dir,
"qtermwidget")])
installs.append(["qtermwidgetconfig.py", config.default_mod_dir])
# Create the Makefile. The QtModuleMakefile class provided by the
# pyqtconfig module takes care of all the extra preprocessor, compiler and
# linker flags needed by the Qt library.
makefile = pyqtconfig.QtGuiModuleMakefile(
configuration = config,
build_file = build_file,
installs = installs)
# Add the library we are wrapping. The name doesn't include any platform
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
# ".dll" extension on Windows).
makefile.extra_lib_dirs.append("..")
makefile.extra_libs = ["qtermwidget4"]
# Generate the Makefile itself.
makefile.generate()
# Now we create the configuration module. This is done by merging a Python
# dictionary (whose values are normally determined dynamically) with a
# (static) template.
content = {
# Publish where the SIP specifications for this module will be
# installed.
"qtermwidget_sip_dir": config.default_sip_dir,
# Publish the set of SIP flags needed by this module. As these are the
# same flags needed by the qt module we could leave it out, but this
# allows us to change the flags at a later date without breaking
# scripts that import the configuration module.
"qtermwidget_sip_flags": qt_sip_flags}
# This creates the qtermwidgetconfig.py module from the qtermwidgetconfig.py.in
# template and the dictionary.
sipconfig.create_config_module("qtermwidgetconfig.py", "config.py.in", content)
-104
View File
@@ -1,104 +0,0 @@
import os
import sipconfig
import subprocess
import os
import site
import pprint
from distutils import sysconfig
from PyQt5 import QtCore
import PyQt5
class Configuration(sipconfig.Configuration):
"""The class that represents PyQt configuration values.
"""
def getEnv(self, name, default):
return os.environ.get(name) or default
def __init__(self):
qmake_bin = subprocess.check_output(
["which", "qmake"], universal_newlines=True).strip(' \t\n\r')
qtconfig = subprocess.check_output(
[qmake_bin, "-query"], universal_newlines=True)
qtconfig = dict(x.split(":", 1) for x in qtconfig.splitlines())
self.pyQtIncludePath = self.getEnv(
'PYQT_INCLUDE_PATH', '/usr/share/sip/PyQt5')
pyqtconfig = {
"pyqt_config_args": "--confirm-license -v " + str(self.pyQtIncludePath) + " --qsci-api -q " + qmake_bin,
"pyqt_version": QtCore.PYQT_VERSION,
"pyqt_version_str": QtCore.PYQT_VERSION_STR,
"pyqt_bin_dir": PyQt5.__path__[0],
"pyqt_mod_dir": PyQt5.__path__[0],
"pyqt_sip_dir": str(self.pyQtIncludePath),
"pyqt_modules": "QtCore QtGui QtWidgets", # ... and many more
"pyqt_sip_flags": QtCore.PYQT_CONFIGURATION['sip_flags'],
"qt_version": QtCore.QT_VERSION,
"qt_edition": "free",
"qt_winconfig": "shared",
"qt_framework": 0,
"qt_threaded": 1,
"qt_dir": qtconfig['QT_INSTALL_PREFIX'],
"qt_data_dir": qtconfig['QT_INSTALL_DATA'],
"qt_archdata_dir": qtconfig['QT_INSTALL_DATA'],
"qt_inc_dir": qtconfig['QT_INSTALL_HEADERS'],
"qt_lib_dir": qtconfig['QT_INSTALL_LIBS']
}
macros = sipconfig._default_macros.copy()
macros['INCDIR_QT'] = qtconfig['QT_INSTALL_HEADERS']
macros['LIBDIR_QT'] = qtconfig['QT_INSTALL_LIBS']
macros['MOC'] = os.path.join(qtconfig['QT_INSTALL_BINS'], 'moc')
sipconfig.Configuration.__init__(self, [pyqtconfig])
self.set_build_macros(macros)
# The name of the SIP build file generated by SIP and used by the build system.
build_file = "qtermwidget.sbf"
# Get the SIP configuration information.
config = Configuration()
# Run SIP to generate the build_file
os.system(" ".join([config.sip_bin, '-I', str(config.pyQtIncludePath), str(
config.pyqt_sip_flags), "-b", build_file, "-o", "-c", ". " " qtermwidget.sip"]))
installs = []
installs.append(["qtermwidget.sip", os.path.join(
config.pyqt_sip_dir, "qtermwidget")])
installs.append(["qtermwidgetconfig.py", config.pyqt_mod_dir])
makefile = sipconfig.SIPModuleMakefile(
configuration=config, build_file=build_file, installs=installs, qt=["QtCore", "QtGui", "QtWidgets"])
# Add the library we are wrapping. The name doesn't include any platform
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
# ".dll" extension on Windows).
makefile.extra_lib_dirs.append("../lib/")
makefile.extra_lib_dirs.append("..")
makefile.extra_libs = ["qtermwidget5"]
# Support for C++11
makefile.extra_cxxflags.append('-std=c++11')
# Generate the Makefile itself.
makefile.generate()
content = {
# Publish where the SIP specifications for this module will be
# installed.
"qtermwidget_sip_dir": config.pyqt_sip_dir,
# Publish the set of SIP flags needed by this module. As these are the
# same flags needed by the qt module we could leave it out, but this
# allows us to change the flags at a later date without breaking
# scripts that import the configuration module.
"qtermwidget_sip_flags": config.pyqt_sip_flags
}
# This creates the qtermwidgetconfig.py module from the qtermwidgetconfig.py.in
# template and the dictionary.
sipconfig.create_config_module("qtermwidgetconfig.py", "config.py.in", content)
View File
@@ -1,5 +1,8 @@
%Module QTermWidget
%ModuleHeaderCode
#pragma GCC visibility push(default)
%End
%Import QtGui/QtGuimod.sip
%Import QtCore/QtCoremod.sip
@@ -19,7 +22,7 @@ public:
ScrollBarRight=2
};
enum KeyboardCursorShape
enum class KeyboardCursorShape
{
BlockCursor=0,
UnderlineCursor=1,