Skip to content
Snippets Groups Projects
Commit 655ff547 authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony
Browse files

Add support for sip v5 build system

The new sip build system complies with pep 517 and
requires configuration by a standard pyproject.toml
file rather than running a single command. Along with
these changes the fixed sip.h file has been removed in
favour of a header generated locally if required.

We now support both the sip build systems as this is
required in our current support for multiple OSes. In
the process of adding support some cleanup has been
included:
  - the .sip files in our tree are now full module defs
    rather than the boilerplate being filled in by CMake,
    giving each module more flexibility.
  - the sipwrapper file has been removed in favour of a
    simpler script to simply strip the problematic code
    for C++17 compatability.
parent 3106b6c2
No related branches found
No related tags found
No related merge requests found
Showing
with 535 additions and 293 deletions
......@@ -92,11 +92,11 @@
"MODULE_OUTPUT_DIR": 1,
"PYQT_VERSION": 1,
"FOLDER": 1,
"SIP_SRCS": "+",
"SIP_SRC": 1,
"HEADER_DEPS": "+",
"INCLUDE_DIRS": "+",
"LINK_LIBS": "+",
"INSTALL_DIRS": "+",
"INSTALL_DIR": "+",
"OSX_INSTALL_RPATH": "+",
"LINUX_INSTALL_RPATH": "+"
}
......
# Find SIP
# ~~~~~~~~
# Mantid Repository : https://github.com/mantidproject/mantid
#
# 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 © 2008 ISIS Rutherford Appleton Laboratory UKRI, NScD Oak Ridge
# National Laboratory, European Spallation Source, Institut Laue - Langevin &
# CSNS, Institute of High Energy Physics, CAS SPDX - License - Identifier: GPL -
# 3.0 +
# 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.
#[=======================================================================[.rst:
FindSIP
-------
Find the installed version of the SIP Python binding library.
FindSIP should be called after Python has been found.
It supports both sip build systems in v6 and <= v5.
SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
IF(SIP_VERSION)
# Already in cache, be silent
SET(SIP_FOUND TRUE)
ELSE(SIP_VERSION)
Result Variables
^^^^^^^^^^^^^^^^
if (EXISTS "${CMAKE_MODULE_PATH}/FindSIP.py")
set (_find_sip_py "${CMAKE_MODULE_PATH}/FindSIP.py")
else()
FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
endif()
All versions of sip define the following variables:
if (NOT EXISTS ${_find_sip_py})
message(FATAL_ERROR "Failed to find FindSIP.py in \"${CMAKE_MODULE_PATH}\"")
endif()
``SIP_FOUND``
True if sip has been found.
``SIP_VERSION``
The version of SIP found in ``X.Y.Z`` format
For versions 6 and this file additionally defines the following variables:
``SIP_BUILD_EXECUTABLE``
The path to the sip-build executable
``SIP_MODULE_EXECUTABLE``
The path to the sip-module executable
For versions prior to 5 this file additionally defines the following variables:
``SIP_EXECUTABLE``
Path and filename of the SIP command line executable.
``SIP_INCLUDE_DIR``
Directory holding the SIP C++ header file.
#]=======================================================================]
include(FindPackageHandleStandardArgs)
# First look for sip-build, indicating the newer v6 build system
find_program(SIP_BUILD_EXECUTABLE sip-build)
if(SIP_BUILD_EXECUTABLE)
# version string
execute_process(
COMMAND ${SIP_BUILD_EXECUTABLE} --version
OUTPUT_VARIABLE SIP_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# module generator
find_program(SIP_MODULE_EXECUTABLE sip-module)
# pyproject.toml template
find_file(SIP_PYPROJECT_TOML_TEMPLATE NAME pyproject.toml.in
PATHS ${CMAKE_MODULE_PATH}/sip-build
)
# project.py template
find_file(SIP_PROJECT_PY_TEMPLATE NAME project.py.in
PATHS ${CMAKE_MODULE_PATH}/sip-build
)
# Set expected variables for find_package
find_package_handle_standard_args(
SIP
REQUIRED_VARS SIP_BUILD_EXECUTABLE SIP_MODULE_EXECUTABLE
SIP_PYPROJECT_TOML_TEMPLATE SIP_PROJECT_PY_TEMPLATE
VERSION_VAR SIP_VERSION
)
endif()
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_DIRECTORY ${sip_config})
SET(SIP_FOUND TRUE)
ENDIF(sip_config)
# Check that it really exists
if(${CMAKE_SYSTEM} MATCHES "Darwin" AND IS_SYMLINK ${SIP_INCLUDE_DIRECTORY}/sip.h)
get_filename_component(_sip_h "${SIP_INCLUDE_DIRECTORY}/sip.h" REALPATH BASE_DIR)
get_filename_component(SIP_INCLUDE_DIRECTORY "${_sip_h}" DIRECTORY)
if(NOT SIP_FOUND)
# Python development is required for the older system
if(NOT Python_Development_FOUND)
message(
FATAL_ERROR "FindSIP requires find_package(Python) to be called first"
)
endif()
find_path(SIP_INCLUDE_DIR sip.h PATHS ${SIP_INCLUDE_DIRECTORY} NO_DEFAULT_PATH)
include ( FindPackageHandleStandardArgs )
find_package_handle_standard_args( SIP DEFAULT_MSG SIP_VERSION_STR SIP_INCLUDE_DIR SIP_EXECUTABLE )
# Look for older sip build system. CentOS has this prefixed with python3
find_program(SIP_EXECUTABLE NAMES python${Python_VERSION_MAJOR}-sip sip)
# 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)
# version string
execute_process(
COMMAND ${SIP_EXECUTABLE} -V
OUTPUT_VARIABLE SIP_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
mark_as_advanced ( _find_sip_py )
# header directory
find_path(SIP_INCLUDE_DIR sip.h HINTS ${Python_INCLUDE_DIRS})
ENDIF(SIP_VERSION)
# Set expected variables for find_package
find_package_handle_standard_args(
SIP
REQUIRED_VARS SIP_EXECUTABLE SIP_INCLUDE_DIR
VERSION_VAR SIP_VERSION
)
endif()
# 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)
......@@ -2,38 +2,29 @@
# Python module from a set of .sip definitions
include(QtTargetFunctions)
# ~~~
# brief: Add a module target to generate Python bindings for a set of sip
# sources. The sources list should be a list of filenames without a path. The
# .sip module is generated in the CMAKE_CURRENT_BINARY_DIR keyword: MODULE_NAME
# The name of the final python module (without extension) keyword:
# MODULE_OUTPUT_DIR The final destination of the built module optional keyword:
# SIP_SRCS A list of input .sip file paths keyword: HEADER_DEPS A list of header
# files that are included in the .sip files. These are set as dependencies on
# the target. keyword: INCLUDE_DIRS A list of additional
# target_include_directories keyword: SYSTEM_INCLUDE_DIRS A list of additional
# target_include_directories that should be marked as system headers keyword:
# LINK_LIBS A list of additional target_link_libraries keyword: PYQT_VERSION A
# single value indicating the version of PyQt to compile against keyword:
# INSTALL_DIR The target location for installing this library keyword:
# OSX_INSTALL_RPATH Install path for osx version > 10.8 keyword:
# LINUX_INSTALL_RPATH Install path for CMAKE_SYSTEM_NAME == Linux
# .sip module is generated in the CMAKE_CURRENT_BINARY_DIR
# keyword: MODULE_NAME The name of the final python module (without extension)
# keyword: MODULE_OUTPUT_DIR The final destination of the built module optional
# keyword: SIP_SRC The input .sip file path
# keyword: HEADER_DEPS A list of header files that are included in the .sip files. These are set as dependencies on
# the target.
# keyword: INCLUDE_DIRS A list of additional target_include_directories
# keyword: SYSTEM_INCLUDE_DIRS A list of additional target_include_directories that should be marked as system headers
# keyword: LINK_LIBS A list of additional target_link_libraries
# keyword: PYQT_VERSION A single value indicating the version of PyQt to compile against
# keyword: INSTALL_DIR The target location for installing this library
# keyword: OSX_INSTALL_RPATH Install path for osx version > 10.8
# keyword: LINUX_INSTALL_RPATH Install path for CMAKE_SYSTEM_NAME == Linux
# ~~~
function(mtd_add_sip_module)
find_file(_sipmodule_template_path NAME sipqtmodule_template.sip.in
PATHS ${CMAKE_MODULE_PATH}
)
if(NOT _sipmodule_template_path)
message(
FATAL
"Unable to find sipqtmodule_template.sip.in in cmake module path. Cannot continue."
)
endif()
set(options)
set(oneValueArgs MODULE_NAME TARGET_NAME MODULE_OUTPUT_DIR PYQT_VERSION
FOLDER
set(oneValueArgs MODULE_NAME TARGET_NAME SIP_SRC MODULE_OUTPUT_DIR
PYQT_VERSION FOLDER
)
set(multiValueArgs
SIP_SRCS
HEADER_DEPS
SYSTEM_INCLUDE_DIRS
INCLUDE_DIRS
......@@ -49,22 +40,7 @@ function(mtd_add_sip_module)
# Create the module spec file from the list of .sip files The template file
# expects the variables to have certain names
set(MODULE_NAME ${PARSED_MODULE_NAME})
set(SIP_INCLUDES)
# Sip cannot %Include absolute paths so make them relative and add -I flag
foreach(_sip_file ${PARSED_SIP_SRCS})
get_filename_component(_filename ${_sip_file} NAME)
get_filename_component(_directory ${_sip_file} DIRECTORY)
set(SIP_INCLUDES "${SIP_INCLUDES}%Include ${_filename}\n")
if(NOT _directory)
set(_directory ${CMAKE_CURRENT_LIST_DIR})
elseif(NOT IS_ABSOLUTE _directory)
set(_directory ${CMAKE_CURRENT_LIST_DIR}/${_directory})
endif()
list(APPEND _sip_include_flags "-I${_directory}")
list(APPEND _sip_include_deps "${_sip_file}")
endforeach()
# Add absolute paths for header dependencies
# Add absolute paths for target header dependencies
foreach(_header ${PARSED_HEADER_DEPS})
if(IS_ABSOLUTE ${_header})
list(APPEND _sip_include_deps "${_header}")
......@@ -73,37 +49,26 @@ function(mtd_add_sip_module)
endif()
endforeach()
# Run sip code generator
if(PARSED_PYQT_VERSION EQUAL 4 AND USE_PRIVATE_SIPPYQT4)
set(_sip_include_dir ${PYQT4_SIP_INCLUDE_DIR})
set(_sip_executable ${PYQT4_SIP_EXECUTABLE})
# Configure final module
set(_module_spec ${CMAKE_CURRENT_LIST_DIR}/${PARSED_SIP_SRC})
if(PARSED_PYQT_VERSION EQUAL 5)
if(SIP_BUILD_EXECUTABLE)
_add_sip_library(
${PARSED_TARGET_NAME} ${PARSED_MODULE_NAME} ${_module_spec}
${PARSED_PYQT_VERSION} _sip_include_deps
)
else()
_add_sip_library_v4(
${PARSED_TARGET_NAME} ${PARSED_MODULE_NAME} ${_module_spec}
_sip_include_deps
)
endif()
elseif(PARSED_PYQT_VERSION EQUAL 6)
message(FATAL_ERROR "PyQt6 is not yet supported")
else()
set(_sip_include_dir ${SIP_INCLUDE_DIR})
set(_sip_executable ${SIP_EXECUTABLE})
message(FATAL_ERROR "Unknown PYQT_VERSION: ${PARSED_PYQT_VERSION}")
endif()
set(_module_spec ${CMAKE_CURRENT_BINARY_DIR}/${PARSED_MODULE_NAME}.sip)
configure_file(${_sipmodule_template_path} ${_module_spec})
set(_pyqt_sip_dir ${PYQT${PARSED_PYQT_VERSION}_SIP_DIR})
set(_sip_wrapper ${CMAKE_SOURCE_DIR}/tools/sip/sipwrapper.py)
list(APPEND _sip_include_flags "-I${_pyqt_sip_dir}")
set(_pyqt_sip_flags ${PYQT${PARSED_PYQT_VERSION}_SIP_FLAGS})
set(_sip_generated_cpp
${CMAKE_CURRENT_BINARY_DIR}/sip${PARSED_MODULE_NAME}part0.cpp
)
add_custom_command(
OUTPUT ${_sip_generated_cpp}
COMMAND
${Python_EXECUTABLE} ${_sip_wrapper} ${_sip_executable}
${_sip_include_flags} ${_pyqt_sip_flags} -c ${CMAKE_CURRENT_BINARY_DIR}
-j1 -w -e ${_module_spec}
DEPENDS ${_module_spec} ${_sip_include_deps}
COMMENT "Generating ${PARSED_MODULE_NAME} python bindings with sip"
)
add_library(
${PARSED_TARGET_NAME} MODULE ${_sip_generated_cpp} ${_sip_include_deps}
)
# Suppress Warnings about sip bindings have PyObject -> PyFunc casts which is
# a valid pattern GCC8 onwards detects GCC 8 onwards needs to disable
# functional casting at the Python interface
......@@ -112,20 +77,16 @@ function(mtd_add_sip_module)
PRIVATE
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,8.0>>:-Wno-cast-function-type>
)
target_include_directories(
${PARSED_TARGET_NAME} SYSTEM PRIVATE ${_sip_include_dir} Python::Python
)
target_include_directories(
${PARSED_TARGET_NAME} PRIVATE ${PARSED_INCLUDE_DIRS}
)
target_include_directories(
${PARSED_TARGET_NAME} SYSTEM PRIVATE ${PARSED_SYSTEM_INCLUDE_DIRS}
)
target_link_libraries(${PARSED_TARGET_NAME} PRIVATE ${PARSED_LINK_LIBS})
target_link_libraries(
${PARSED_TARGET_NAME} PRIVATE Python::Python ${PARSED_LINK_LIBS}
)
if(PARSED_PYQT_VERSION EQUAL 4 AND USE_PRIVATE_SIPPYQT4)
add_dependencies(${PARSED_TARGET_NAME} extern-pyqt4)
endif()
# Set all required properties on the target
set_target_properties(
${PARSED_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_NAME ${PARSED_MODULE_NAME}
......@@ -184,3 +145,107 @@ function(mtd_add_sip_module)
set_target_properties(${PARSED_TARGET_NAME} PROPERTIES PREFIX "")
endif()
endfunction()
# Private API Add a library target based on the given sip module file.
# ~~~
# Add a library target based on the given sip module file. The library target
# will first generate the bindings and then compile to code.
# Args:
# - target_name: The name of the library target
# - module_name: The name of the sip module as seen by Python
# - module_spec: The full path to the sip module file
# - pyqt_major_version: The major version of PyQt building against
# - sip_include_deps_var: A variable containing a list of files to add as
# dependencies to the target
# ~~~
function(_add_sip_library target_name module_name module_spec
pyqt_major_version sip_include_deps_var
)
# first produce template files for the sip-build project in the binary
# directory
set(_project_dir ${CMAKE_CURRENT_BINARY_DIR})
# replacement variables for templates
set(MODULE_NAME ${module_name})
set(MODULE_SPEC_FILE ${module_spec})
set(PYQT_MAJOR_VERSION ${pyqt_major_version})
set(PYQT_SIP_ABI_VERSION ${PYQT${pyqt_major_version}_SIP_ABI_VERSION})
# generate project files for sip-build
configure_file(${SIP_PROJECT_PY_TEMPLATE} ${_project_dir}/project.py)
configure_file(${SIP_PYPROJECT_TOML_TEMPLATE} ${_project_dir}/pyproject.toml)
# add command for running sip-build. Sets a custom build directory and
# sip-build is then responsible for the directory layout below that. We are
# just interested in the directory that contains the generated .cpp file
set(_sip_build_dir sip-generated)
set(_sip_generated_cpp
${_project_dir}/${_sip_build_dir}/${module_name}/sip${module_name}part0.cpp
)
# We also have to deal with the added complication that sip generates code
# that is not C++-17 compatible as it includes throw specifiers. We deal with
# this by replacing them in the generated code.
set(_sip_sanitizer ${CMAKE_SOURCE_DIR}/tools/sip/sip-sanitize-module.py)
add_custom_command(
OUTPUT ${_sip_generated_cpp}
COMMAND ${SIP_BUILD_EXECUTABLE} ARGS --build-dir=${_sip_build_dir}
COMMAND ${Python_EXECUTABLE} ${_sip_sanitizer} ARGS ${_sip_generated_cpp}
WORKING_DIRECTORY ${_project_dir}
DEPENDS ${module_spec} ${_project_dir}/project.py
${_project_dir}/pyproject.toml ${_sip_include_deps}
${_sip_sanitizer}
COMMENT "Generating ${module_name} python bindings with sip"
)
add_library(
${target_name} MODULE ${_sip_generated_cpp} ${${_sip_include_deps_var}}
)
target_include_directories(
${target_name} SYSTEM PRIVATE ${_project_dir}/${_sip_build_dir}
)
endfunction()
# ~~~
# Add a library target based on the given sip module file. The library target
# will first generate the bindings and then compile to code.
# Note that this is for sip <= v4 build system and hardcode to PyQt5
# Args:
# - target_name: The name of the library target
# - module_name: The name of the sip module as seen by Python
# - module_spec: The full path to the sip module file
# - sip_include_deps_var: A variable containing a list of files to add as
# dependencies to the target
# ~~~
function(_add_sip_library_v4 target_name module_name module_spec
sip_include_deps_var
)
if(NOT PYQT5_SIP_DIR)
message(
FATAL_ERROR
"find_package(PyQt) must have been called with the correct PyQt version"
)
endif()
# Build sip command
list(APPEND _sip_include_flags "-I${PYQT5_SIP_DIR}")
set(_pyqt_sip_flags "${PYQT5_SIP_FLAGS}")
set(_sip_generated_cpp ${CMAKE_CURRENT_BINARY_DIR}/sip${module_name}part0.cpp)
# We also have to deal with the added complication that sip generates code
# that is not C++-17 compatible as it includes throw specifiers. We deal with
# this by replacing them in the generated code.
set(_sip_sanitizer ${CMAKE_SOURCE_DIR}/tools/sip/sip-sanitize-module.py)
add_custom_command(
OUTPUT ${_sip_generated_cpp}
COMMAND ${SIP_EXECUTABLE} ARGS ${_sip_include_flags} ${_pyqt_sip_flags} -c
${CMAKE_CURRENT_BINARY_DIR} -j1 -w -e ${_module_spec}
COMMAND ${Python_EXECUTABLE} ${_sip_sanitizer} ARGS ${_sip_generated_cpp}
DEPENDS ${_module_spec} ${_sip_include_deps}
COMMENT "Generating ${PARSED_MODULE_NAME} python bindings with sip"
)
add_library(
${target_name} MODULE ${_sip_generated_cpp} ${${_sip_include_deps_var}}
)
target_include_directories(${target_name} SYSTEM PRIVATE ${SIP_INCLUDE_DIR})
endfunction()
# sip-build template files
This directory contains a project file and pyproject template meant for input
into the sipbuild system. CMake uses these files as templates to generate build
steps for each of the sip binding layers.
See https://www.riverbankcomputing.com/static/Docs/sip/index.html for more information.
"""This module provides a Builder and Project for sip-build.
It disables building such that only the bindings are generated, allowing
us to add the generated files to an external builder as part of a regular
CMake target
"""
from sipbuild import Builder, Project
class NoOpBuilder(Builder):
"""A 'Builder' that does nothing but satisfy the required interface"""
def build_executable(self, buildable, *, fatal=True):
""" Build an executable from a BuildableExecutable object and return
the relative pathname of the executable.
"""
return None
def build_project(self, target_dir, *, wheel_tag=None):
""" Build the project. """
return None
def install_project(self, target_dir, *, wheel_tag=None):
""" Install the project into a target directory. """
return None
class ExternalBuilderProject(Project):
"""Define a Project that uses
a no-op builder such that we only generate the
bindings but leave building to an external entity
"""
def __init__(self):
"""Initializes the class with the NoOpBuilder instance and lets
the base class do the rest
"""
super().__init__()
self.builder_factory = NoOpBuilder
[build-system]
requires = ["sip >=5.3"]
build-backend = "sipbuild.api"
[tool.sip.metadata]
name = "@MODULE_NAME@"
[tool.sip.project]
sip-module = "PyQt@PYQT_MAJOR_VERSION@.sip"
abi-version = "@PYQT_SIP_ABI_VERSION@"
[tool.sip.bindings.@MODULE_NAME@]
concatenate = 1
internal = true
# We need exception support so that errors are translated correctly into Python errors
# Unfortunately sip generates dynamic exception specifiers that were removed in C++17
# so we have to strip those manually ourselves. See tools/sip/sipwrapper.py.
exceptions = true
protected-is-public = false
sip-file = "@MODULE_SPEC_FILE@"
//
// This file defines the Python bindings for the
// @MODULE_NAME@ library.
//
// This file was autogenerated by cmake.
//
// Module name must match the final library filename
// without the extension
%Module(name=@MODULE_NAME@)
%UnitCode
#if defined(_MSC_VER)
# pragma warning( disable: 4290 )
#elif defined(__GNUC__) && !defined(__clang__)
// We need default visibility for this module so that
// python can see the init function.
#pragma GCC visibility push(default)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#if __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#endif
%End
// Always import core, gui and widgets in Qt5
%Import QtCore/QtCoremod.sip
%Import QtGui/QtGuimod.sip
%If(Qt_5_0_0 -)
%Import QtWidgets/QtWidgetsmod.sip
%End
// Module contents
@SIP_INCLUDES@
include(SipQtTargetFunctions)
set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/../../widgets/common/inc)
set(COMMON_SIP_DIR ${CMAKE_CURRENT_LIST_DIR}/../common_sip)
set(
_header_depends
${COMMON_SIP_DIR}/SIPVector.h
${COMMON_SIP_DIR}/string.sip
${COMMON_SIP_DIR}/vector.sip
${COMMON_INC_DIR}/MantidQtWidgets/Common/AlgorithmDialog.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Message.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/MessageDisplay.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/HintStrategy.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Hint.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/Row.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/RowLocation.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/JobTreeView.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/JobTreeViewSignalAdapter.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/InstrumentSelector.h)
set(COMMON_SIP_DIR ${CMAKE_CURRENT_LIST_DIR}/../sip)
set(_header_depends
${COMMON_SIP_DIR}/vector.sip.h
${COMMON_SIP_DIR}/string.sip
${COMMON_SIP_DIR}/vector.sip
${COMMON_INC_DIR}/MantidQtWidgets/Common/AlgorithmDialog.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Message.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/MessageDisplay.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/HintStrategy.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Hint.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/Row.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/RowLocation.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/JobTreeView.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/Batch/JobTreeViewSignalAdapter.h
${COMMON_INC_DIR}/MantidQtWidgets/Common/InstrumentSelector.h
)
list(APPEND common_link_libs
${CORE_MANTIDLIBS}
${POCO_LIBRARIES}
PythonInterfaceCore)
list(APPEND common_link_libs ${CORE_MANTIDLIBS} ${POCO_LIBRARIES}
PythonInterfaceCore
)
# Wrapper module linked against Qt5
if(ENABLE_WORKBENCH)
mtd_add_sip_module(MODULE_NAME _commonqt5
TARGET_NAME mantidqt_commonqt5
HEADER_DEPS
${_header_depends}
SIP_SRCS _common.sip
PYQT_VERSION 5
INCLUDE_DIRS
${CMAKE_CURRENT_LIST_DIR}
${COMMON_SIP_DIR}
LINK_LIBS
MantidQtWidgetsCommonQt5
${common_link_libs}
Qt5::Core
Qt5::Widgets
Qt5::Gui
Qt5::Qscintilla
API
INSTALL_DIR
${WORKBENCH_SITE_PACKAGES}/mantidqt
LINUX_INSTALL_RPATH
"\$ORIGIN/.."
OSX_INSTALL_RPATH
"@loader_path/.."
FOLDER Qt5)
mtd_add_sip_module(
MODULE_NAME _commonqt5
TARGET_NAME mantidqt_commonqt5
HEADER_DEPS ${_header_depends}
SIP_SRC _common.sip
PYQT_VERSION 5
INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR} ${COMMON_SIP_DIR}
LINK_LIBS MantidQtWidgetsCommonQt5
${common_link_libs}
Qt5::Core
Qt5::Widgets
Qt5::Gui
Qt5::Qscintilla
API
INSTALL_DIR ${WORKBENCH_SITE_PACKAGES}/mantidqt
LINUX_INSTALL_RPATH "\$ORIGIN/.."
OSX_INSTALL_RPATH "@loader_path/.."
FOLDER Qt5
)
endif()
add_subdirectory(icons)
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
// This file defines the Python bindings for the
// _common library.
%Module(name=_commonqt5)
%UnitCode
#if defined(_MSC_VER)
# pragma warning( disable: 4290 )
#elif defined(__GNUC__) && !defined(__clang__)
// We need default visibility for this module so that
// python can see the init function.
#pragma GCC visibility push(default)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#if __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#endif
%End
// PyQt5 widgets
%Import QtGui/QtGuimod.sip
%Import QtWidgets/QtWidgetsmod.sip
%ModuleCode
#include "MantidQtWidgets/Common/FittingMode.h"
#include "MantidQtWidgets/Common/Message.h"
......@@ -10,9 +39,15 @@ using namespace MantidQt::MantidWidgets;
using namespace MantidQt::MantidWidgets::Batch;
%End
%Include ../common_sip/exceptions.sip
%Include ../common_sip/string.sip
%Include ../common_sip/vector.sip
// Remove namespace qualifiers in generated code. We control
// the package layout separately in Python
%HideNamespace(name=MantidQt)
%HideNamespace(name=MantidQt::MantidWidgets)
%HideNamespace(name=MantidQt::MantidWidgets::Batch)
%Include ../sip/exceptions.sip
%Include ../sip/string.sip
%Include ../sip/vector.sip
%InitialisationCode
qRegisterMetaType<std::string>("StdString");
......@@ -176,8 +211,6 @@ private:
ScriptEditor(const ScriptEditor&);
};
%If (Qt_5_0_0 -)
class AlgorithmProgressWidget : QWidget {
%TypeHeaderCode
#include "MantidQtWidgets/Common/AlgorithmProgress/AlgorithmProgressWidget.h"
......@@ -201,9 +234,6 @@ private:
CodeExecution(const CodeExecution&);
};
%End // end >= Qt5
class AlgorithmDialog: QDialog {
%TypeHeaderCode
#include "MantidQtWidgets/Common/AlgorithmDialog.h"
......@@ -642,12 +672,10 @@ public:
// RowLocation needs to be wrapped in a SIP namespace class
// otherwise it cannot be recognised as a type when passed into a signal
// e.g. in JobTreeViewSignalAdapter's cellTextChanged signal
namespace MantidQt
{
namespace MantidWidgets
{
namespace Batch
{
// The namespace is hidden so that it is not visible to the outside world.
namespace MantidQt {
namespace MantidWidgets {
namespace Batch {
class RowLocation
{
......@@ -677,9 +705,9 @@ public:
bool operator>=(const MantidQt::MantidWidgets::Batch::RowLocation& other);
};
}; // Batch
}; // MantidWidgets
}; // MantidQt
};
};
};
class RowPredicate {
%TypeHeaderCode
......
set(ICONS_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../icons/inc/)
set(_header_depends
${COMMON_SIP_DIR}/SIPVector.h
${COMMON_SIP_DIR}/vector.sip
${ICONS_INC_DIR}/MantidQtIcons/Icon.h)
set(_header_depends ${ICONS_INC_DIR}/MantidQtIcons/Icon.h)
# Wrapper module linked against Qt5
if(ENABLE_WORKBENCH)
mtd_add_sip_module(MODULE_NAME _iconsqt5
TARGET_NAME mantidqt_iconsqt5
SIP_SRCS _icons.sip
HEADER_DEPS ${_header_depends}
PYQT_VERSION 5
INCLUDE_DIRS
${COMMON_SIP_DIR}
${ICONS_INC_DIR}
${CMAKE_SOURCE_DIR}/Framework/PythonInterface/core/inc
LINK_LIBS
MantidQtIconsQt5
Qt5::Core
Qt5::Gui
Python::Python
INSTALL_DIR
${WORKBENCH_SITE_PACKAGES}/mantidqt/icons
LINUX_INSTALL_RPATH
"\$ORIGIN/../.."
OSX_INSTALL_RPATH
"@loader_path/../.."
FOLDER Qt5)
mtd_add_sip_module(
MODULE_NAME _iconsqt5
TARGET_NAME mantidqt_iconsqt5
SIP_SRC _icons.sip
HEADER_DEPS ${_header_depends}
PYQT_VERSION 5
INCLUDE_DIRS ${COMMON_SIP_DIR} ${ICONS_INC_DIR}
${CMAKE_SOURCE_DIR}/Framework/PythonInterface/core/inc
LINK_LIBS MantidQtIconsQt5 Qt5::Core Qt5::Gui Python::Python
INSTALL_DIR ${WORKBENCH_SITE_PACKAGES}/mantidqt/icons
LINUX_INSTALL_RPATH "\$ORIGIN/../.."
OSX_INSTALL_RPATH "@loader_path/../.."
FOLDER Qt5
)
endif()
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
// This file defines the Python bindings for the
// _icons library.
%Module(name=_iconsqt5)
%UnitCode
#if defined(_MSC_VER)
# pragma warning( disable: 4290 )
#elif defined(__GNUC__) && !defined(__clang__)
// We need default visibility for this module so that
// python can see the init function.
#pragma GCC visibility push(default)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#if __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#endif
%End
%ModuleCode
#include "MantidQtIcons/Icon.h"
using namespace MantidQt::Icons;
%End
// PyQt5 Gui module
%Import QtGui/QtGuimod.sip
QIcon getIcon(const QString &iconName, const QString &color = QString("black"), const double scaleFactor = 1.0);
QIcon getIcon(const QStringList &iconNames, const QList<QVariant> &options);
if(ENABLE_WORKBENCH)
# Defines a Python wrapper module for instrument view access This wraps the low-
# level classes.
# Defines a Python wrapper module for instrument view access This wraps the
# low- level classes.
set(INSTRUMENTVIEW_INC_DIR ../../widgets/instrumentview/inc)
set(_header_depends
${INSTRUMENTVIEW_INC_DIR}/InstrumentWidget.h)
set(_header_depends ${INSTRUMENTVIEW_INC_DIR}/InstrumentWidget.h)
# The wrapper is only defined for Qt5 and does not support legacy Qt4 mode
mtd_add_sip_module(MODULE_NAME _instrumentviewqt5
TARGET_NAME mantidqt_instrumentviewqt5
SIP_SRCS _instrumentview.sip
PYQT_VERSION 5
LINK_LIBS
DataObjects
${common_link_libs}
MantidQtWidgetsInstrumentViewQt5
MantidQtWidgetsCommonQt5
MantidQtWidgetsMplCppQt5
Qt5::Core
Qt5::Gui
Qt5::OpenGL
Qt5::Widgets
INSTALL_DIR
${WORKBENCH_SITE_PACKAGES}/mantidqt/widgets/instrumentview
LINUX_INSTALL_RPATH
"\$ORIGIN/../../.."
OSX_INSTALL_RPATH
"@loader_path/../../.."
FOLDER Qt5)
mtd_add_sip_module(
MODULE_NAME _instrumentviewqt5
TARGET_NAME mantidqt_instrumentviewqt5
SIP_SRC _instrumentview.sip
PYQT_VERSION 5
LINK_LIBS DataObjects
${common_link_libs}
MantidQtWidgetsInstrumentViewQt5
MantidQtWidgetsCommonQt5
MantidQtWidgetsMplCppQt5
Qt5::Core
Qt5::Gui
Qt5::OpenGL
Qt5::Widgets
INSTALL_DIR ${WORKBENCH_SITE_PACKAGES}/mantidqt/widgets/instrumentview
LINUX_INSTALL_RPATH "\$ORIGIN/../../.."
OSX_INSTALL_RPATH "@loader_path/../../.."
FOLDER Qt5
)
endif()
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
// This file defines the Python bindings for the
// _instrumentview library.
%Module(name=_instrumentviewqt5)
%UnitCode
#if defined(_MSC_VER)
# pragma warning( disable: 4290 )
#elif defined(__GNUC__) && !defined(__clang__)
// We need default visibility for this module so that
// python can see the init function.
#pragma GCC visibility push(default)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#if __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#endif
%End
// PyQt5 widgets
%Import QtWidgets/QtWidgetsmod.sip
%ModuleCode
#include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
// Allows suppression of namespaces within the module
using namespace MantidQt::MantidWidgets;
%End
%Include ../../../common_sip/exceptions.sip
%Include ../../../common_sip/string.sip
%Include ../../../sip/exceptions.sip
%Include ../../../sip/string.sip
%InitialisationCode
qRegisterMetaType<std::string>("StdString");
......
......@@ -12,6 +12,4 @@ from mantidqt.utils.qt import import_qt
Cell = import_qt('..._common', 'mantidqt.widgets.jobtreeview', 'Cell')
JobTreeView = import_qt('..._common', 'mantidqt.widgets.jobtreeview', 'JobTreeView')
JobTreeViewSignalAdapter = import_qt('..._common', 'mantidqt.widgets.jobtreeview', 'JobTreeViewSignalAdapter')
# RowLocation must be accessed differently as it is wrapped in a SIP namespace class
RowLocation = import_qt('..._common', 'mantidqt.widgets.jobtreeview').MantidQt.MantidWidgets.Batch.RowLocation
RowLocation = import_qt('..._common', 'mantidqt.widgets.jobtreeview', 'RowLocation')
This directory contains a set of sip definitions for things such as converters
for common types that might be reused across multiple modules.
File moved
File moved
......@@ -17,7 +17,7 @@
%Include string.sip
%ModuleCode
#include "SIPVector.h"
#include "vector.sip.h"
%End
template<TYPE>
......@@ -30,7 +30,7 @@ template<TYPE>
%ConvertFromTypeCode
return vectorToPythonList(*sipCpp, [&](TYPE item) -> PyObject* {
auto *heapCopy = new TYPE(item);
return sipConvertFromInstance(heapCopy, sipClass_TYPE, sipTransferObj);
return sipConvertFromType(heapCopy, sipType_TYPE, sipTransferObj);
});
%End
......@@ -40,15 +40,15 @@ template<TYPE>
return isIterable(sipPy);
} else {
auto cppValue = pythonListToVector<TYPE>(sipPy, [&](PyObject* pyItem) -> boost::optional<TYPE> {
if (!sipCanConvertToInstance(pyItem, sipClass_TYPE, SIP_NOT_NONE)) {
if (!sipCanConvertToType(pyItem, sipType_TYPE, SIP_NOT_NONE)) {
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to TYPE");
return boost::none;
} else {
int state;
auto* cppItemPtr = reinterpret_cast<TYPE*>(
sipConvertToInstance(pyItem, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipConvertToType(pyItem, sipType_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipReleaseInstance(cppItemPtr, sipClass_TYPE, state);
sipReleaseType(cppItemPtr, sipType_TYPE, state);
return asOptional(sipIsErr, cppItemPtr);
}
});
......@@ -69,7 +69,7 @@ template<TYPE>
return optionalToPyObject(*sipCpp, [&](std::vector<TYPE> const& vector) -> PyObject* {
return vectorToPythonList(vector, [&](TYPE const& item) -> PyObject* {
auto *heapCopy = new TYPE(item);
return sipConvertFromInstance(heapCopy, sipClass_TYPE, sipTransferObj);
return sipConvertFromType(heapCopy, sipType_TYPE, sipTransferObj);
});
});
%End
......@@ -81,15 +81,15 @@ template<TYPE>
} else {
auto cppValue = pythonObjectToOptional<std::vector<TYPE>>(sipPy, [&](PyObject* pythonList) -> boost::optional<std::vector<TYPE>> {
return pythonListToVector<TYPE>(pythonList, [&](PyObject* pyItem) -> boost::optional<TYPE> {
if (!sipCanConvertToInstance(pyItem, sipClass_TYPE, SIP_NOT_NONE)) {
if (!sipCanConvertToType(pyItem, sipType_TYPE, SIP_NOT_NONE)) {
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to TYPE");
return boost::none;
} else {
int state;
auto* cppItemPtr = reinterpret_cast<TYPE*>(
sipConvertToInstance(pyItem, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipConvertToType(pyItem, sipType_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipReleaseInstance(cppItemPtr, sipClass_TYPE, state);
sipReleaseType(cppItemPtr, sipType_TYPE, state);
return asOptional(sipIsErr, cppItemPtr);
}
});
......@@ -246,7 +246,7 @@ template<TYPE>
return vectorToPythonList(*sipCpp, [&](std::vector<TYPE> const& item) -> PyObject* {
return vectorToPythonList(item, [&](TYPE const& item) -> PyObject* {
auto *heapCopy = new TYPE(item);
return sipConvertFromInstance(heapCopy, sipClass_TYPE, sipTransferObj);
return sipConvertFromType(heapCopy, sipType_TYPE, sipTransferObj);
});
});
%End
......@@ -258,14 +258,14 @@ template<TYPE>
} else {
auto cppValue = pythonListToVector<std::vector<TYPE>>(sipPy, [&](PyObject* pyItem) -> boost::optional<std::vector<TYPE>> {
return pythonListToVector<TYPE>(pyItem, [&](PyObject* pyInnerItem) -> boost::optional<TYPE> {
if (!sipCanConvertToInstance(pyInnerItem, sipClass_TYPE, SIP_NOT_NONE)) {
if (!sipCanConvertToType(pyInnerItem, sipType_TYPE, SIP_NOT_NONE)) {
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to the damn TYPE");
return boost::none;
} else {
int state;
auto* cppItemPtr = reinterpret_cast<TYPE*>(
sipConvertToInstance(pyInnerItem, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipReleaseInstance(cppItemPtr, sipClass_TYPE, state);
sipConvertToType(pyInnerItem, sipType_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipReleaseType(cppItemPtr, sipType_TYPE, state);
return asOptional(sipIsErr, cppItemPtr);
}
});
......@@ -293,7 +293,7 @@ template<TYPE>
return vectorToPythonList(vector, [&](std::vector<TYPE> const& item) -> PyObject* {
return vectorToPythonList(item, [&](TYPE const& item) -> PyObject* {
auto *heapCopy = new TYPE(item);
return sipConvertFromInstance(heapCopy, sipClass_TYPE, sipTransferObj);
return sipConvertFromType(heapCopy, sipType_TYPE, sipTransferObj);
});
});
});
......@@ -309,15 +309,15 @@ template<TYPE>
[&](PyObject* pythonList) -> boost::optional<std::vector<std::vector<TYPE>>> {
return pythonListToVector<std::vector<TYPE>>(pythonList, [&](PyObject* pythonInnerList) -> boost::optional<std::vector<TYPE>> {
return pythonListToVector<TYPE>(pythonInnerList, [&](PyObject* pyItem) -> boost::optional<TYPE> {
if (!sipCanConvertToInstance(pyItem, sipClass_TYPE, SIP_NOT_NONE)) {
if (!sipCanConvertToType(pyItem, sipType_TYPE, SIP_NOT_NONE)) {
PyErr_Format(PyExc_TypeError, "object in iterable cannot be converted to TYPE");
return boost::none;
} else {
int state;
auto* cppItemPtr = reinterpret_cast<TYPE*>(
sipConvertToInstance(pyItem, sipClass_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipConvertToType(pyItem, sipType_TYPE, 0, SIP_NOT_NONE, &state, sipIsErr));
sipReleaseInstance(cppItemPtr, sipClass_TYPE, state);
sipReleaseType(cppItemPtr, sipType_TYPE, state);
return asOptional(sipIsErr, cppItemPtr);
}
});
......
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment