diff options
Diffstat (limited to 'sources/shiboken2/doc')
-rw-r--r-- | sources/shiboken2/doc/commandlineoptions.rst | 110 | ||||
-rw-r--r-- | sources/shiboken2/doc/conf.py.in | 8 | ||||
-rw-r--r-- | sources/shiboken2/doc/contents.rst | 4 | ||||
-rw-r--r-- | sources/shiboken2/doc/images/icecream.png | bin | 0 -> 4272 bytes | |||
-rw-r--r-- | sources/shiboken2/doc/images/qtforpython-underthehood.png | bin | 0 -> 19144 bytes | |||
-rw-r--r-- | sources/shiboken2/doc/index.rst | 28 | ||||
-rw-r--r-- | sources/shiboken2/doc/samplebinding.rst | 250 |
7 files changed, 377 insertions, 23 deletions
diff --git a/sources/shiboken2/doc/commandlineoptions.rst b/sources/shiboken2/doc/commandlineoptions.rst index d373561cd..c335fab75 100644 --- a/sources/shiboken2/doc/commandlineoptions.rst +++ b/sources/shiboken2/doc/commandlineoptions.rst @@ -37,16 +37,22 @@ Options Enable heuristics to detect parent relationship on return values. For more info, check :ref:`return-value-heuristics`. +.. _avoid-protected-hack: + +``--avoid-protected-hack`` + Avoid the use of the '#define protected public' hack. + +.. _use-isnull-as-nb_nonzero: + +``--use-isnull-as-nb_nonzero`` + If a class have an isNull() const method, it will be used to + compute the value of boolean casts + .. _api-version: ``--api-version=<version>`` Specify the supported api version used to generate the bindings. -.. _debug-level: - -``--debug-level=[sparse|medium|full]`` - Set the debug level. - .. _documentation-only: ``--documentation-only`` @@ -63,16 +69,52 @@ Options ``--generation-set`` Generator set to be used (e.g. qtdoc). -.. _help: +.. _diff: -``--help`` - Display this help and exit. +``--diff`` + Print a diff of wrapper files. + +.. _dryrun: + +``--dryrun`` + Dry run, do not generate wrapper files. + +.. _--project-file: + +``--project-file=<file>`` + Text file containing a description of the binding project. + Replaces and overrides command line arguments. .. _include-paths: -``--include-paths=<path>[:<path>:...]`` +``-I<path>, --include-paths=<path>[:<path>:...]`` Include paths used by the C++ parser. +... _system-include-paths: + +``-isystem<path>, --system-include-paths=<path>[:<path>:...]`` + System include paths used by the C++ parser + +.. _framework-include-paths: + +``-F<path>, --framework-include-paths=<path>[:<path>:...]`` + Framework include paths used by the C++ parser + +.. _language-level: + +``--language-level=, -std=<level>`` + C++ Language level (c++11..c++17, default=c++14) + +.. _typesystem-paths: + +``-T<path>, --typesystem-paths=<path>[:<path>:...]`` + Paths used when searching for type system files. + +.. _output-directory: + +``--output-directory=[dir]`` + The directory where the generated files will be written. + .. _license-file=[license-file]: ``--license-file=[license-file]`` @@ -83,23 +125,57 @@ Options ``--no-suppress-warnings`` Show all warnings. -.. _output-directory: - -``--output-directory=[dir]`` - The directory where the generated files will be written. - .. _silent: ``--silent`` Avoid printing any message. -.. _typesystem-paths: +.. _debug-level: -``--typesystem-paths=<path>[:<path>:...]`` - Paths used when searching for type system files. +``--debug-level=[sparse|medium|full]`` + Set the debug level. + +.. _help: + +``--help`` + Display this help and exit. .. _version: ``--version`` Output version information and exit. +QtDocGenerator Options +---------------------- + +.. _doc-parser: + +``--doc-parser=<parser>`` + The documentation parser used to interpret the documentation + input files (qdoc|doxygen). + +.. _documentation-code-snippets-dir: + +``--documentation-code-snippets-dir=<dir>`` + Directory used to search code snippets used by the documentation. + +.. _documentation-data-dir: + +``--documentation-data-dir=<dir>`` + Directory with XML files generated by documentation tool. + +.. _documentation-extra-sections-dir=<dir>: + +``--documentation-extra-sections-dir=<dir>`` + Directory used to search for extra documentation sections. + +.. _library-source-dir: + +``--library-source-dir=<dir>`` + Directory where library source code is located. + +.. _additional-documentation: + +``--additional-documentation=<file>`` + List of additional XML files to be converted to .rst files + (for example, tutorials). diff --git a/sources/shiboken2/doc/conf.py.in b/sources/shiboken2/doc/conf.py.in index 57c2f94b9..d3aa95c0b 100644 --- a/sources/shiboken2/doc/conf.py.in +++ b/sources/shiboken2/doc/conf.py.in @@ -39,11 +39,11 @@ source_suffix = '.rst' source_encoding = 'utf-8' # The master toctree document. -#master_doc = 'contents' +master_doc = 'index' # General information about the project. project = u'Shiboken' -copyright = u'Copyright (C) 2016 The Qt Company Ltd.' +copyright = u'© 2018 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/license/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -137,7 +137,7 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes'] # Additional templates that should be rendered to pages, maps page names to # template names. -html_additional_pages = { 'index' : 'index.html'} +#html_additional_pages = { 'index' : 'index.html'} # If false, no module index is generated. html_use_modindex = False @@ -159,4 +159,4 @@ html_show_sourcelink = False # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' -intersphinx_mapping = {'apiextractor': ('@CMAKE_BINARY_DIR@/ApiExtractor/doc/html','@CMAKE_BINARY_DIR@/ApiExtractor/doc/html/objects.inv')} +intersphinx_mapping = {'apiextractor': ('ApiExtractor','@CMAKE_BINARY_DIR@/ApiExtractor/doc/html/objects.inv')} diff --git a/sources/shiboken2/doc/contents.rst b/sources/shiboken2/doc/contents.rst index 24adb1c68..a0b40effb 100644 --- a/sources/shiboken2/doc/contents.rst +++ b/sources/shiboken2/doc/contents.rst @@ -1,11 +1,10 @@ Table of contents ***************** .. toctree:: - :numbered: :maxdepth: 3 - faq.rst overview.rst + samplebinding.rst commandlineoptions.rst projectfile.rst typesystemvariables.rst @@ -15,3 +14,4 @@ Table of contents ownership.rst wordsofadvice.rst shibokenmodule.rst + faq.rst diff --git a/sources/shiboken2/doc/images/icecream.png b/sources/shiboken2/doc/images/icecream.png Binary files differnew file mode 100644 index 000000000..41d1a25fa --- /dev/null +++ b/sources/shiboken2/doc/images/icecream.png diff --git a/sources/shiboken2/doc/images/qtforpython-underthehood.png b/sources/shiboken2/doc/images/qtforpython-underthehood.png Binary files differnew file mode 100644 index 000000000..64e30b1c5 --- /dev/null +++ b/sources/shiboken2/doc/images/qtforpython-underthehood.png diff --git a/sources/shiboken2/doc/index.rst b/sources/shiboken2/doc/index.rst new file mode 100644 index 000000000..4cc5b204e --- /dev/null +++ b/sources/shiboken2/doc/index.rst @@ -0,0 +1,28 @@ +Shiboken the Binding Generator +******************************* + +Shiboken is the CPython-based binding code generator for C or C++ libraries. +It uses an ApiExtractor library to parse the C or C++ headers and get the +type information, using Clang. The library can also be used to parse non-Qt +projects. The following diagram summarizes Shiboken's role in the PySide +project. + +.. image:: images/qtforpython-underthehood.png + +A typesystem file (XML) is used to specify the types to be exposed to Python +and to apply modifications to properly represent and manipulate the types in +the Python World. For example, you can remove and add methods to certain types, +and also modify the arguments of each method. Such actions are inevitable to +properly handle the data structures or types. + +The final outcome of this process is a set of wrappers written in CPython, +which can be used as a module in your python code. + +Refer to the following topics for more information and examples: + +.. toctree:: + :maxdepth: 1 + + overview + samplebinding + contents diff --git a/sources/shiboken2/doc/samplebinding.rst b/sources/shiboken2/doc/samplebinding.rst new file mode 100644 index 000000000..be8dd3ae5 --- /dev/null +++ b/sources/shiboken2/doc/samplebinding.rst @@ -0,0 +1,250 @@ +SampleBinding Example +*********************** + +The example showcases how you can generate CPython-based binding code for a +C++ library using Shiboken. The C++ library is called :code:`Universe`, +with two classes: :code:`Icecream` and :code:`Truck`. Ice creams are +characterized by their flavor, and :code:`Truck` serves as a vehicle of +:code:`Icecream` distribution for kids in a neighborhood. + +First, let's look at the definition of the two classes: + +.. code-block:: cpp + :caption: icecream.h + + class Icecream + { + public: + Icecream(const std::string &flavor); + virtual Icecream *clone(); + virtual ~Icecream(); + virtual const std::string getFlavor(); + + private: + std::string m_flavor; + }; + +.. code-block:: cpp + :caption: truck.h + + class Truck { + public: + Truck(bool leaveOnDestruction = false); + Truck(const Truck &other); + Truck& operator=(const Truck &other); + ~Truck(); + + void addIcecreamFlavor(Icecream *icecream); + void printAvailableFlavors() const; + + bool deliver() const; + void arrive() const; + void leave() const; + + void setLeaveOnDestruction(bool value); + void setArrivalMessage(const std::string &message); + + private: + void clearFlavors(); + + bool m_leaveOnDestruction = false; + std::string m_arrivalMessage = "A new icecream truck has arrived!\n"; + std::vector m_flavors; + }; + +Here is a summary of what the :code:`Universe` library includes: + +* The :code:`Icecream` polymorphic type, which is intended to be overridden. +* The :code:`Icecream::getFlavor()` method returns the flavor depending on the + actual derived type. +* The :code:`Truck` value type that contains pointers, hence the copy + constructor. +* :code:`Truck` stores the :code:`Icecream` objects in a vector, which can be + modified via :code:`Truck::addIcecreamFlavor()`. +* The :code:`Truck’s` arrival message can be customized using its + :code:`setArrivalMessage()` method. +* The :code:`Truck::deliver()` method tells us if the ice cream delivery was + successful. + +Shiboken typesystem +==================== + +Now that the library definitions are in place, Shiboken generator needs a header +file that includes the types we are interested in: + +.. code-block:: cpp + :caption: bindings.h + + #ifndef BINDINGS_H + #define BINDINGS_H + #include "icecream.h" + #include "truck.h" + #endif // BINDINGS_H + +In addition, Shiboken also requires an XML-based typesystem file that defines the +relationship between C++ and Python types: + +.. code-block:: xml + :caption: bindings.xml + + <?xml version="1.0"?> + <typesystem package="Universe"> + <primitive-type name="bool"/> + <primitive-type name="std::string"/> + <object-type name="Icecream"> + <modify-function signature="clone()"> + <modify-argument index="0"> + <define-ownership owner="c++"/> + </modify-argument> + </modify-function> + </object-type> + <value-type name="Truck"> + <modify-function signature="addIcecreamFlavor(Icecream*)"> + <modify-argument index="1"> + <define-ownership owner="c++"/> + </modify-argument> + </modify-function> + </value-type> + </typesystem> + +The first important thing to notice here is that we declare :code:`"bool"` and +:code:`"std::string"` as primitive types. These types are used by some of the +C++ methods as parameters or return types, so Shiboken must know about them. +It can then generate relevant conversion code between C++ and Python, although +most C++ primitive types are handled by Shiboken without additional code. + +Next, we declare 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 cannot magically know who is responsible for freeing the C++ objects +allocated in the Python code. It can guess, but it’s not always correct. There +can be cases where Python should release the C++ memory when the ref count +of the Python object becomes zero. It should never delete the C++ object assuming +that it will not be deleted by the C++ library or maybe it’s 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. + +Building +========= + +To build the :code:`Universe` custom library and then generate bindings for it, +use the :file:`CMakeLists.txt` file provided with the example. You can reuse the +file for your own libraries with minor changes. + +Now, run the command :command:`"cmake ."` from the prompt to configure the +project and build with the toolchain of your choice (we recommend the +‘(N)Makefiles’ generator though). + +As a result, you end up with two shared libraries: +:file:`libuniverse.(so/dylib/dll)` and :file:`Universe.(so/pyd)`. The former is +the custom C++ library, and the latter is the Python module that can be +imported in your Python script. + +Refer to the :file:`README.md` file for more details about the Windows-specific +build instructions. + +Using the Python module +======================== + +The following script uses the :code:`Universe` module, derives a few types from +:code:`Icecream`, implements virtual methods, instantiates objects, and much more: + +.. code-block:: python + :caption: main.py + + from Universe import Icecream, Truck + + class VanillaChocolateIcecream(Icecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateIcecream(self.getFlavor()) + + def getFlavor(self): + return "vanilla sprinked with chocolate" + + class VanillaChocolateCherryIcecream(VanillaChocolateIcecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateCherryIcecream(self.getFlavor()) + + def getFlavor(self): + base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor() + return base_flavor + " and a cherry" + + if __name__ == '__main__': + leave_on_destruction = True + truck = Truck(leave_on_destruction) + + flavors = ["vanilla", "chocolate", "strawberry"] + for f in flavors: + icecream = Icecream(f) + truck.addIcecreamFlavor(icecream) + + truck.addIcecreamFlavor(VanillaChocolateIcecream()) + truck.addIcecreamFlavor(VanillaChocolateCherryIcecream()) + + truck.arrive() + truck.printAvailableFlavors() + result = truck.deliver() + + if result: + print("All the kids got some icecream!") + else: + print("Aww, someone didn't get the flavor they wanted...") + + if not result: + special_truck = Truck(truck) + del truck + + print("") + special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n") + special_truck.arrive() + special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream")) + special_truck.printAvailableFlavors() + special_truck.deliver() + print("Now everyone got the flavor they wanted!") + special_truck.leave() + +After importing the classes from the :code:`Universe` module, it derives two +types from :code:`Icecream` for different “flavors”. It then creates a +:code:`truck` 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. + +The script above shows how to derive from C++ types, override virtual methods, +create and destroy objects, and more. Try running it to see if the ice creams +are delivered. + +.. note:: + You can find the sources for this example under + :file:`<PYTHON_ENV_ROOT>/site-packages/lib/PySide2/examples/samplebinding`. + +Refer to the following topics for detailed information about using Shiboken: + * :doc:`Shiboken module <shibokenmodule>` + * :doc:`Type System Variables <typesystemvariables>` + * :doc:`User Defined Type Conversion <typeconverters>` + * :doc:`Object ownership <ownership>` + * :doc:`Frequently Asked Questions <faq>` |