diff options
Diffstat (limited to 'examples/samplebinding')
-rw-r--r-- | examples/samplebinding/CMakeLists.txt | 31 | ||||
-rw-r--r-- | examples/samplebinding/doc/bindings.h.rstinc | 2 | ||||
-rw-r--r-- | examples/samplebinding/doc/bindings.xml.rstinc | 31 | ||||
-rw-r--r-- | examples/samplebinding/doc/samplebinding.pyproject | 1 | ||||
-rw-r--r-- | examples/samplebinding/doc/samplebinding.rst | 23 |
5 files changed, 78 insertions, 10 deletions
diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt index a57fd67e0..4807904c1 100644 --- a/examples/samplebinding/CMakeLists.txt +++ b/examples/samplebinding/CMakeLists.txt @@ -1,5 +1,8 @@ -cmake_minimum_required(VERSION 3.16) -cmake_policy(VERSION 3.16) +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.18) +cmake_policy(VERSION 3.18) # Enable policy to not use RPATH settings for install_name on macOS. if(POLICY CMP0068) @@ -42,7 +45,21 @@ set(generated_sources # ================================== Shiboken detection ====================================== # Use provided python interpreter if given. if(NOT python_interpreter) - find_program(python_interpreter "python") + if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + find_program(python_interpreter "python_d") + if(NOT python_interpreter) + message(FATAL_ERROR + "A debug Python interpreter could not be found, which is a requirement when " + "building this example in a debug configuration. Make sure python_d.exe is in " + "PATH.") + endif() + else() + find_program(python_interpreter "python") + if(NOT python_interpreter) + message(FATAL_ERROR + "No Python interpreter could be found. Make sure python is in PATH.") + endif() + endif() endif() message(STATUS "Using python interpreter: ${python_interpreter}") @@ -118,7 +135,7 @@ target_compile_definitions(${sample_library} PRIVATE BINDINGS_BUILD) # Set up the options to pass to shiboken. set(shiboken_options --generator-set=shiboken --enable-parent-ctor-heuristic - --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --enable-return-value-heuristic --use-isnull-as-nb-bool --avoid-protected-hack -I${CMAKE_SOURCE_DIR} -T${CMAKE_SOURCE_DIR} @@ -159,7 +176,11 @@ set_property(TARGET ${bindings_library} PROPERTY PREFIX "") set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") if(WIN32) - set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") + if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + set_property(TARGET ${bindings_library} PROPERTY SUFFIX "_d.pyd") + else() + set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") + endif() endif() # Make sure the linker doesn't complain about not finding Python symbols on macOS. diff --git a/examples/samplebinding/doc/bindings.h.rstinc b/examples/samplebinding/doc/bindings.h.rstinc new file mode 100644 index 000000000..e2a0b6fef --- /dev/null +++ b/examples/samplebinding/doc/bindings.h.rstinc @@ -0,0 +1,2 @@ +The Shiboken generator needs a header file that includes +the types we are interested in: diff --git a/examples/samplebinding/doc/bindings.xml.rstinc b/examples/samplebinding/doc/bindings.xml.rstinc new file mode 100644 index 000000000..60b9b1a48 --- /dev/null +++ b/examples/samplebinding/doc/bindings.xml.rstinc @@ -0,0 +1,31 @@ +Shiboken requires an XML-based typesystem file that defines the +relationship between C++ and Python types. + +It declares the two aforementioned classes. One of them as an +“object-type” and the other as a “value-type”. The main difference is that +object-types are passed around in generated code as pointers, whereas +value-types are copied (value semantics). + +By specifying the names of these classes in the typesystem file, Shiboken +automatically tries to generate bindings for all methods of those +classes. You need not mention all the methods manually in the XML file, unless +you want to modify them. + +**Object ownership rules** + +Shiboken doesn't know if Python or C++ are responsible for freeing the C++ +objects that were allocated in the Python code, and assuming this might lead to +errors. There can be cases where Python should release the C++ memory when the +reference count of the Python object becomes zero, but it should never delete +the underlying C++ object just from assuming that it will not be deleted by +underlying C++ library, or if it's maybe parented to another object (like +QWidgets). + +In our case, the :code:`clone()` method is only called inside the C++ library, +and we assume that the C++ code takes care of releasing the cloned object. + +As for :code:`addIcecreamFlavor()`, we know that a :code:`Truck` owns the +:code:`Icecream` object, and will remove it once the :code:`Truck` is +destroyed. That's why the ownership is set to “c++” in the typesystem file, +so that the C++ objects are not deleted when the corresponding Python names +go out of scope. diff --git a/examples/samplebinding/doc/samplebinding.pyproject b/examples/samplebinding/doc/samplebinding.pyproject index 82c485a09..b0786355f 100644 --- a/examples/samplebinding/doc/samplebinding.pyproject +++ b/examples/samplebinding/doc/samplebinding.pyproject @@ -1,5 +1,6 @@ { "files": ["../bindings.h", + "../bindings.xml", "../icecream.cpp", "../icecream.h", "../macros.h", diff --git a/examples/samplebinding/doc/samplebinding.rst b/examples/samplebinding/doc/samplebinding.rst index 8d74be281..defb55d6b 100644 --- a/examples/samplebinding/doc/samplebinding.rst +++ b/examples/samplebinding/doc/samplebinding.rst @@ -54,8 +54,8 @@ done by specifying a special XML file called a typesystem file. In the typesystem file you specify things like: - * which C++ classes should have bindings (Icecream) and what kind of - semantics (value / object) + * Which C++ classes should have bindings (Icecream, Truck) and with what + kind of semantics (value / object) * Ownership rules (who deletes the C++ objects, C++ or Python) @@ -181,17 +181,30 @@ On Windows: mkdir build cd build - cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release + cmake -S.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cl.exe ninja ninja install cd .. +Use the Python module ++++++++++++++++++++++ + The final example can then be run by: .. code-block:: bash python main.py +In the ``main.py`` script, two types are derived from :code:`Icecream` for +different “flavors” after importing the classes from the :code:`Universe` +module. Then, a :code:`truck` is created to deliver some regular flavored +Icecreams and two special ones. + +If the delivery fails, a new :code:`truck` is created with the old flavors +copied over, and a new *magical* flavor that will surely satisfy all customers. + +Try running it to see if the ice creams are delivered. + Windows troubleshooting +++++++++++++++++++++++ @@ -207,13 +220,13 @@ passing the compiler on the command line: .. code-block:: bash - cmake -H.. -B. -DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe + cmake -S.. -B. -DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe or by using the -G option: .. code-block:: bash - cmake -H.. -B. -G "Visual Studio 14 Win64" + cmake -S.. -B. -G "Visual Studio 14 Win64" If the ``-G "Visual Studio 14 Win64"`` option is used, a ``sln`` file will be generated, and can be used with ``MSBuild`` |