Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for building with Shiboken2 in Engine #697

Merged
merged 2 commits into from Nov 7, 2021

Conversation

YakoYakoYokuYoku
Copy link
Member

@YakoYakoYokuYoku YakoYakoYokuYoku commented Nov 3, 2021

Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. Additionally, make sure you've done all of these things:

PR Description

What type of PR is this? (Check one of the boxes below)

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (non-breaking change which does not add functionality nor fixes a bug but improves Natron in some way)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • My change requires a change to the documentation
    • I have updated the documentation accordingly

What does this pull request do?

This is a partial attempt to bring support for Qt5+/Shiboken2+/PySide2+ support in Natron as Qt4 was deprecated by upstream. Although the Qt5 series are reaching End Of Support too this changes nonetheless may permit an smoother transition to Qt6.

In order to make the PR easier for review the Engine/NatronEngine changes have yet to be uploaded, although it can be done via shiboken2 generation as described in the INSTALL_LINUX.md doc.

Show a few screenshots (if this is a visual change)

Screenshot from 2021-11-02 22-03-00

Have you tested your changes (if applicable)? If so, how?

I've followed this tutorial and rendered it successfully.

Watch the tutorial

An even more rigorous testing is needed for the sake of coverage and to make sure things are ok.

Built under Solus 4.3.

Futher details of this pull request

Used configuration.

# config.pri
boost: LIBS += -lboost_serialization
expat: LIBS += -lexpat
expat: PKGCONFIG -= expat
python {
	PYV=3
	PY_PKG_SUFFIX=
	PYTHON_CONFIG_FLAGS=
	INCLUDEPATH += $$system(pkg-config --variable=includedir python3)/python$$system(pkg-config --modversion python3)
	LIBS += -lpython3
	PYV=3
}
pyside {
        PKGCONFIG -= pyside
        INCLUDEPATH += $$system(pkg-config --variable=includedir pyside2)
        INCLUDEPATH += $$system(pkg-config --variable=includedir pyside2)/QtCore
        INCLUDEPATH += $$system(pkg-config --variable=includedir pyside2)/QtGui
        INCLUDEPATH += $$system(pkg-config --variable=includedir pyside2)/QtWidgets
        INCLUDEPATH += $$system(pkg-config --variable=includedir Qt5Gui)
        LIBS += $$system(pkg-config --libs pyside2)
}
shiboken {
        PKGCONFIG -= shiboken
        INCLUDEPATH += $$system(pkg-config --variable=includedir shiboken2)
        LIBS += $$system(pkg-config --libs shiboken2)
}

Example command output (TODO: notice the Python scripts).

> ./Builds/Natron/usr/bin/Natron
Natron Version 2.5
(C) 2018-2021 The Natron developers
(C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
>>>Use the --help or -h option to print usage.<<<
Fontconfig configuration file /home/yakoyoku/Builds/Natron/usr/bin/../Resources/etc/fonts does not exist, not setting FONTCONFIG_PATH
Found OpenGL Renderer: AMD Radeon R7 200 Series (BONAIRE, DRM 3.42.0, 5.14.15-204.current, LLVM 12.0.1) , Vendor: AMD , OpenGL Version: 4.6 (Compatibility Profile) Mesa 21.2.4 , Max. Texture Size 16384 ,Max GPU Memory: "1.91 GiB"
Attempt to read an OpenColorIO configuration but the configuration directory "/usr/share/OpenColorIO-Configs" does not exist.
Attempt to read an OpenColorIO configuration but the configuration directory "/home/yakoyoku/Builds/Natron/usr/bin/../Resources/OpenColorIO-Configs" does not exist.
fontID= 0 families= ("Droid Sans")
fontID= 1 families= ("Droid Sans")
Setting application font to  "Droid Sans" 11
... found "Droid Sans" available styles:
"Droid Sans" "Regular"
"Droid Sans" "Bold"
Not an exact match, got:  "Droid Sans" 11
Building Fontconfig fonts...
Fontconfig fonts built
Load OFX Plugins...
Load OFX Plugins: prepend bundled plugins dir /home/yakoyoku/Builds/Natron/usr/Plugins/OFX/Natron
Load OFX Plugins: reading cache file "/home/yakoyoku/.cache/INRIA/Natron/OFXLoadCache/OFXCache_2.5_Devel_0.xml"
Load OFX Plugins: reading cache file... done!
Load OFX Plugins: plugin path is "/home/yakoyoku/Builds/Natron/usr/Plugins/OFX/Natron" "/usr/share/OFX/Plugins" "/usr/share/OFX/Natron" "/usr/share/OFX/Nuke"
Load OFX Plugins: scan plugins...
Load OFX Plugins: scan plugins... done!
Load OFX Plugins... done!
templatesSearchPath:  ("/home/yakoyoku/Builds/Natron/usr/Plugins/PyPlugs", "/home/yakoyoku/.Natron", "/usr/share/Natron/Plugins")
Info: init.py script not loaded (this is not an error)
Info: initGui.py script not loaded (this is not an error)
templatesSearchPath:  ("/home/yakoyoku/Builds/Natron/usr/Plugins/PyPlugs", "/home/yakoyoku/.Natron", "/usr/share/Natron/Plugins")

Engine/Settings.cpp Outdated Show resolved Hide resolved
Engine/Knob.h Show resolved Hide resolved
@@ -428,6 +428,7 @@ class Int2DParam

Int2DTuple get() const;
Int2DTuple get(double frame) const;
using IntParam::set;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both Int2DParam and Int3DParam require a function definition of get(int) (get(int, int) too for 3D) if not it will be shadowed, another way to solve this is by qualifying the method calls but is way harder to do so. See https://stackoverflow.com/questions/24342270/base-class-template-member-function-shadowed-in-derived-class-albeit-different

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need these functions? I think it's expected to have them shadowed, and I don't see what this has to do with this PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If hiding is expected then Shiboken2 was doing the very nasty thing of ignoring the shadowing and generating the get(int) where it wasn't supposed to be. IIRC these kind of exclusions can be done in the typesystem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I would say a proper solution would be to provide explicit implementations that throw an exception. Don't you think so?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like it's the most sanish way to do so. One way could be immediately throwing a mismatched dimension error. Another putting those methods under a private field although at the cost of reporting a wrong error.

@@ -444,6 +445,8 @@ class Int3DParam

Int3DTuple get() const;
Int3DTuple get(double frame) const;
using IntParam::set;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

@@ -39,10 +39,8 @@ CLANG_DIAG_OFF(mismatched-tags)
GCC_DIAG_OFF(unused-parameter)
GCC_DIAG_OFF(missing-field-initializers)
#include <basewrapper.h>
#include <conversions.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use #if/#ifdef, please don't remove

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FreeCAD codebase uses #if/#ifdef for the Python wrapper, gonna abstain the removals and use the preprocessor instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK!
also, I would remommend putting shiboken-generated files and shiboken2 generated files in two separate directories, so that we can check in both in the sources. That would be great

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem is that the Engine.pro is gonna need a good amount of tinkering, cannot get any idea to what to do here

@@ -17,6 +17,9 @@
* along with Natron. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
* ***** END LICENSE BLOCK ***** */

//Defined to avoid including some headers when running shiboken which may crash shiboken (particularly boost headers)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why move this here? this should be inside the include guard

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know exactly yet but Shiboken (2 and 6) does something strange that it makes "two passes" over this file, and at the second "pass" it ignores the SBK_RUN definition. Will see if something can be done instead.

rowVec[j] = ret;
}
} else if (PyUnicode_Check(pyString) ) {
if (PyUnicode_Check(pyString) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of removing,

  • replace PyString_Check by PyBytes_Check
  • replace PyString_AsString by PyObject_Bytes
  • put the if ( PyBytes_Check(pyString) ) { section after the if (PyUnicode_Check(pyString) section

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is to keep python2 compatibility)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gonna follow PEP-393 by adapting what you've suggested. May be better for Shiboken to be smart enough for #if PY_MAJOR_VERSION > 3/#else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the PyBytes_Check works both in python2 and 3 (PyString_Check disappeared from Python3), so that makes the code 2/3 compatible. Are you suggesting it should be done differently? There is similar code at several places in Natron

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Luckily enough one call to PyUnicode_Check is needed to check if the type is suitable for Python strings, according to the official docs. Although the PyBytes_Check method works too.

@@ -28,11 +28,6 @@ CLANG_DIAG_OFF(deprecated)
CLANG_DIAG_ON(deprecated)

NATRON_NAMESPACE_ENTER
#ifdef SBK_RUN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newer C++ implementations let the preprocessor to expand the name of a namespace if it was defined. Wasn't portable to begin with.

@@ -684,11 +679,6 @@ enum MergingFunctionEnum
//typedef QFlags<StandardButtonEnum> StandardButtons;
Q_DECLARE_FLAGS(StandardButtons, StandardButtonEnum)

#ifdef SBK_RUN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove?

@@ -66,10 +66,10 @@ CLANG_DIAG_ON(deprecated)
//#define foreach Q_FOREACH


typedef boost::uint32_t U32;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated change. file a different PR if you think this is useful

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The later versions of Shiboken were ignoring the boost::*_t types. Given that C++11 has fixed width integers it compiled without nuisance. Can remain here in the case of being accepted, otherwise I can file a different PR.

@@ -41,8 +41,6 @@ run-without-python {
# from <https://docs.python.org/3/c-api/intro.html#include-files>:
# "Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included."
CONFIG += python
QMAKE_CFLAGS += -include Python.h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was giving me build errors to preinclude that file. If the current Natron build can do it without these flags, which I think it can and it is already included in many places of the codebase where it's needed.

Copy link
Member

@devernay devernay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I would prefer if the code could be as compatible as possible with QT4/PySide during the transition.

Could you please split that into:

  • a PR that fixes Qt5-related stuff, making sure it doesn't break Qt4 support (#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) is your friend)
  • a PR that adds PySide2/Shiboken2 support, making sure it doesn't break PySide/Shiboken support (same)

Similarly, we try to keep python2/python3 compat during the transition (see the PyBytes_Check comment)

@devernay
Copy link
Member

devernay commented Nov 4, 2021

Btw we're looking for a volunteer to setup github actions for CI (since travis is gone). That would be a good way to test the Qt4|Qt5/Py2|Py3 matrix in CI.
Would you have some time to do this?
Currently, CI is broken and we run builds/tests manually on our own machines

@YakoYakoYokuYoku
Copy link
Member Author

Thank you!

You are welcome too.

* a PR that fixes Qt5-related stuff, making sure it doesn't break Qt4 support (#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) is your friend)

Although no Qt5 is used (besides obviously PySide2) in this PR, I'll make sure to do the split in #698.

Btw we're looking for a volunteer to setup github actions for CI (since travis is gone).

Sounds hella easy to do.

@YakoYakoYokuYoku
Copy link
Member Author

Added a Global/Pyside_Shiboken2_Macros.h for use with shiboken2, e.g.

shiboken2 --enable-parent-ctor-heuristic --use-isnull-as-nb_nonzero --avoid-protected-hack \
    --include-paths=.:Global:libs/OpenFX/include:/usr/include/PySide2:/usr/include/python3.9 \
    --typesystem-paths=/usr/share/PySide2/typesystems --output-directory=Engine \
    Global/Pyside_Shiboken2_Macros.h Engine/Pyside_Engine_Python.h Engine/typesystem_engine.xml

@devernay devernay merged commit e708012 into NatronGitHub:RB-2.5 Nov 7, 2021
devernay added a commit that referenced this pull request Dec 2, 2021
we have to find a shiboken2 solution that doesn't break shiboken1
See #698 #697 #704
@YakoYakoYokuYoku YakoYakoYokuYoku mentioned this pull request Dec 5, 2021
10 tasks
@YakoYakoYokuYoku YakoYakoYokuYoku mentioned this pull request Jun 8, 2022
@YakoYakoYokuYoku YakoYakoYokuYoku deleted the engine-sbk2 branch June 18, 2022 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants