diff --git a/CMakeLists.txt b/CMakeLists.txt index cad15f8..417ba44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ add_custom_target(PyQt6) mo2_python_pip_install(PyQt6 DIRECTORY ${CMAKE_BINARY_DIR}/pylibs/ PACKAGES - PyQt${Qt_VERSION_MAJOR}==${Qt_VERSION} + PyQt${MO2_QT_VERSION_MAJOR}==${MO2_QT_VERSION} sip==6.8.5) # useful for naming DLL, zip, etc. (3.10 -> 310) diff --git a/src/mobase/CMakeLists.txt b/src/mobase/CMakeLists.txt index 864fe45..d20310d 100644 --- a/src/mobase/CMakeLists.txt +++ b/src/mobase/CMakeLists.txt @@ -4,7 +4,7 @@ find_package(Qt6 COMPONENTS Core) find_package(mo2-uibase CONFIG REQUIRED) pybind11_add_module(mobase MODULE) -mo2_configure_library(mobase +mo2_configure_target(mobase SOURCE_TREE WARNINGS 4 EXTERNAL_WARNINGS 4 diff --git a/src/proxy/CMakeLists.txt b/src/proxy/CMakeLists.txt index e34f56f..12b141e 100644 --- a/src/proxy/CMakeLists.txt +++ b/src/proxy/CMakeLists.txt @@ -15,13 +15,13 @@ mo2_configure_plugin(proxy ${CMAKE_CURRENT_SOURCE_DIR}/../pybind11-qt) target_link_libraries(proxy PRIVATE runner mo2::uibase) set_target_properties(proxy PROPERTIES OUTPUT_NAME ${PLUGIN_NAME}) -mo2_install_target(proxy FOLDER) +mo2_install_plugin(proxy FOLDER) set(PLUGIN_PYTHON_DIR bin/plugins/${PLUGIN_NAME}) # install runner target_link_options(proxy PRIVATE "/DELAYLOAD:runner.dll") -mo2_install_target(runner INSTALLDIR ${PLUGIN_PYTHON_DIR}/dlls) +install(FILES $ DESTINATION ${PLUGIN_PYTHON_DIR}/dlls) # translations (custom location) mo2_add_translations(proxy @@ -58,11 +58,8 @@ install(FILES ${pythoncore_zip} DESTINATION ${PYLIB_DIR}) install(TARGETS mobase DESTINATION ${PYLIB_DIR}) # install PyQt6 -# set(PYQT_LIB_DIR ${CMAKE_BINARY_DIR}/pylibs/PyQt${Qt_VERSION_MAJOR}) -# set(PYQT_TARGET_DIR ${PYLIB_DIR}/PyQt${Qt_VERSION_MAJOR}) -# file(GLOB pyqt_files ${PYQT_LIB_DIR}/*.py ${PYQT_LIB_DIR}/*.pyd ${PYQT_LIB_DIR}/*.pyi) install( - DIRECTORY ${CMAKE_BINARY_DIR}/pylibs/PyQt${Qt_VERSION_MAJOR} + DIRECTORY ${CMAKE_BINARY_DIR}/pylibs/PyQt${MO2_QT_VERSION_MAJOR} DESTINATION ${PYLIB_DIR} PATTERN "*.pyd" PATTERN "*.pyi" diff --git a/src/pybind11-qt/CMakeLists.txt b/src/pybind11-qt/CMakeLists.txt index 451b3c5..f94e496 100644 --- a/src/pybind11-qt/CMakeLists.txt +++ b/src/pybind11-qt/CMakeLists.txt @@ -5,7 +5,7 @@ find_package(Qt6 REQUIRED COMPONENTS Core Widgets) mo2_find_python_executable(PYTHON_EXE) add_library(pybind11-qt STATIC) -mo2_configure_library(pybind11-qt +mo2_configure_target(pybind11-qt SOURCE_TREE WARNINGS 4 EXTERNAL_WARNINGS 4 @@ -25,12 +25,12 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_BINARY_DIR}/pylibs ${CMAKE_BINARY_DIR}/pylibs/bin/sip-module.exe - --sip-h PyQt${Qt_VERSION_MAJOR}.sip + --sip-h PyQt${MO2_QT_VERSION_MAJOR}.sip --target-dir ${CMAKE_CURRENT_BINARY_DIR} ) -target_sources(pybind11-qt PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/sip.h") add_dependencies(PyQt6-siph PyQt6) - add_dependencies(pybind11-qt PyQt6-siph) +target_include_directories(pybind11-qt PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + add_library(pybind11::qt ALIAS pybind11-qt) diff --git a/src/pybind11-qt/include/pybind11_qt/details/pybind11_qt_sip.h b/src/pybind11-qt/include/pybind11_qt/details/pybind11_qt_sip.h index 2996c4b..556a980 100644 --- a/src/pybind11-qt/include/pybind11_qt/details/pybind11_qt_sip.h +++ b/src/pybind11-qt/include/pybind11_qt/details/pybind11_qt_sip.h @@ -4,21 +4,37 @@ #include #include -#include #include #include #include "../pybind11_qt_holder.h" +struct _sipTypeDef; +typedef struct _sipTypeDef sipTypeDef; + +struct _sipSimpleWrapper; +typedef struct _sipSimpleWrapper sipSimpleWrapper; + +struct _sipWrapper; +typedef struct _sipWrapper sipWrapper; + namespace pybind11::detail::qt { - /** - * @brief Retrieve the SIP api. - * - * @return const sipAPIDef* - */ - const sipAPIDef* sipAPI(); + // helper functions to avoid bringing in this header + namespace sip { + + // extract the underlying data if present from the equivalent PyQt object + void* extract_data(PyObject*); + + const sipTypeDef* api_find_type(const char* type); + int api_can_convert_to_type(PyObject* pyObj, const sipTypeDef* td, int flags); + + void api_transfer_to(PyObject* self, PyObject* owner); + void api_transfer_back(PyObject* self); + PyObject* api_convert_from_type(void* cpp, const sipTypeDef* td, + PyObject* transferObj); + } // namespace sip template struct MetaData; @@ -91,12 +107,11 @@ namespace pybind11::detail::qt { } } - const sipTypeDef* type = - qt::sipAPI()->api_find_type(MetaData::class_name); + const auto* type = sip::api_find_type(MetaData::class_name); if (type == nullptr) { return false; } - if (!qt::sipAPI()->api_can_convert_to_type(src.ptr(), type, 0)) { + if (!sip::api_can_convert_to_type(src.ptr(), type, 0)) { return false; } @@ -107,20 +122,14 @@ namespace pybind11::detail::qt { // // sipAPI()->api_transfer_to(objPtr, Py_None); // - void* data = nullptr; - if (PyObject_TypeCheck(src.ptr(), qt::sipAPI()->api_simplewrapper_type)) { - data = reinterpret_cast(src.ptr())->data; - } - else if (PyObject_TypeCheck(src.ptr(), qt::sipAPI()->api_wrapper_type)) { - data = reinterpret_cast(src.ptr())->super.data; - } + void* const data = sip::extract_data(src.ptr()); if (data) { if constexpr (is_pointer) { value = reinterpret_cast(data); // transfer ownership - sipAPI()->api_transfer_to(src.ptr(), Py_None); + sip::api_transfer_to(src.ptr(), Py_None); // tie the py::object to the C++ one new pybind11::detail::qt::qobject_holder_impl(value); @@ -164,8 +173,7 @@ namespace pybind11::detail::qt { } } - const sipTypeDef* type = - qt::sipAPI()->api_find_type(MetaData::class_name); + const sipTypeDef* type = sip::api_find_type(MetaData::class_name); if (type == nullptr) { return Py_None; } @@ -188,7 +196,7 @@ namespace pybind11::detail::qt { sipData = &src; } - sipObj = qt::sipAPI()->api_convert_from_type(sipData, type, 0); + sipObj = sip::api_convert_from_type(sipData, type, 0); if (sipObj == nullptr) { return Py_None; @@ -196,11 +204,11 @@ namespace pybind11::detail::qt { // ensure Python deletes the C++ component if constexpr (!is_pointer) { - qt::sipAPI()->api_transfer_back(sipObj); + sip::api_transfer_back(sipObj); } else { if (policy == return_value_policy::take_ownership) { - qt::sipAPI()->api_transfer_back(sipObj); + sip::api_transfer_back(sipObj); } } diff --git a/src/pybind11-qt/pybind11_qt_sip.cpp b/src/pybind11-qt/pybind11_qt_sip.cpp index e3e0a1f..69ad4b8 100644 --- a/src/pybind11-qt/pybind11_qt_sip.cpp +++ b/src/pybind11-qt/pybind11_qt_sip.cpp @@ -4,6 +4,8 @@ #include +#include + namespace py = pybind11; namespace pybind11::detail::qt { @@ -61,4 +63,43 @@ namespace pybind11::detail::qt { return sipApi; } + namespace sip { + const sipTypeDef* api_find_type(const char* type) + { + return sipAPI()->api_find_type(type); + } + + int api_can_convert_to_type(PyObject* pyObj, const sipTypeDef* td, int flags) + { + return sipAPI()->api_can_convert_to_type(pyObj, td, flags); + } + + void api_transfer_to(PyObject* self, PyObject* owner) + { + sipAPI()->api_transfer_to(self, owner); + } + + void api_transfer_back(PyObject* self) + { + sipAPI()->api_transfer_back(self); + } + + PyObject* api_convert_from_type(void* cpp, const sipTypeDef* td, PyObject*) + { + return sipAPI()->api_convert_from_type(cpp, td, 0); + } + + void* extract_data(PyObject* ptr) + { + if (PyObject_TypeCheck(ptr, sipAPI()->api_simplewrapper_type)) { + return reinterpret_cast(ptr)->data; + } + else if (PyObject_TypeCheck(ptr, sipAPI()->api_wrapper_type)) { + return reinterpret_cast(ptr)->super.data; + } + return nullptr; + } + + } // namespace sip + } // namespace pybind11::detail::qt diff --git a/src/pybind11-utils/CMakeLists.txt b/src/pybind11-utils/CMakeLists.txt index 4b2c170..c684115 100644 --- a/src/pybind11-utils/CMakeLists.txt +++ b/src/pybind11-utils/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) add_library(pybind11-utils STATIC) -mo2_configure_library(pybind11-utils +mo2_configure_target(pybind11-utils SOURCE_TREE WARNINGS 4 EXTERNAL_WARNINGS 4 diff --git a/src/runner/CMakeLists.txt b/src/runner/CMakeLists.txt index d02f77d..5a6a3cf 100644 --- a/src/runner/CMakeLists.txt +++ b/src/runner/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16) find_package(mo2-uibase CONFIG REQUIRED) add_library(runner SHARED) -mo2_configure_library(runner +mo2_configure_target(runner SOURCE_TREE WARNINGS 4 EXTERNAL_WARNINGS 4 diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 0e23ae8..34d5487 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -27,8 +27,8 @@ UIBASE_PATH=set:${UIBASE_PATH}" mo2_python_pip_install(python-tests DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pylibs PACKAGES pytest - PyQt${Qt_VERSION_MAJOR}==${Qt_VERSION} - PyQt${Qt_VERSION_MAJOR}-Qt${Qt_VERSION_MAJOR}==${Qt_VERSION}) + PyQt${MO2_QT_VERSION_MAJOR}==${MO2_QT_VERSION} + PyQt${MO2_QT_VERSION_MAJOR}-Qt${MO2_QT_VERSION_MAJOR}==${MO2_QT_VERSION}) add_dependencies(python-tests mobase) set_target_properties(python-tests PROPERTIES FOLDER tests/python) diff --git a/tests/runner/CMakeLists.txt b/tests/runner/CMakeLists.txt index eb9cd41..65dffaa 100644 --- a/tests/runner/CMakeLists.txt +++ b/tests/runner/CMakeLists.txt @@ -27,8 +27,8 @@ mo2_python_pip_install(runner-tests DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pylibs PACKAGES pytest - PyQt${Qt_VERSION_MAJOR}==${Qt_VERSION} - PyQt${Qt_VERSION_MAJOR}-Qt${Qt_VERSION_MAJOR}==${Qt_VERSION}) + PyQt${MO2_QT_VERSION_MAJOR}==${MO2_QT_VERSION} + PyQt${MO2_QT_VERSION_MAJOR}-Qt${MO2_QT_VERSION_MAJOR}==${MO2_QT_VERSION}) add_dependencies(runner-tests mobase)