Skip to content

Commit

Permalink
[Backport] Several fixes and patches (commontk#89)
Browse files Browse the repository at this point in the history
(cherry-picked and adapted from MeVisLab/pythonqt@1e794e5)

* minor improvements in code and unit tests
* disable warnings for deprecated declarations
* add -Wpedantic and even -Werror for src, but relax some warnings
* fix undefined behavior
* fix memory leaks
* use QT_NO_CAST_TO_ASCII  to prevent incorrect behavior on non-Latin1 input

* Improvements in build and CI:
** add parallel build
** add `make check` support
** fix `debug`/`release` builds
** force C++11
** introduce UBSan into CI
** fixes for macOS build with clang
** add pkg-config support:
  if PKGCONFIG is set, skip old-style lookup (useful on Linux and macOS GHA,
  when `python-config` returns incorrect linkage options with missing `-Ldirs`)
** add macOS GHA CI
  • Loading branch information
iakov authored and jcfr committed Jan 28, 2024
1 parent 87f362c commit c780d89
Show file tree
Hide file tree
Showing 43 changed files with 294 additions and 185 deletions.
4 changes: 3 additions & 1 deletion PythonQt.pro
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
TEMPLATE = subdirs

CONFIG += ordered
SUBDIRS = generator src extensions tests examples
tests.depends += src extensions
extensions.depends += src
examples.depends += src extensions
3 changes: 2 additions & 1 deletion build/common.prf
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp
VERSION = 3.2.0

win32: CONFIG += skip_target_version_ext
unix: QMAKE_CXXFLAGS += -std=c++11
unix: CONFIG += c++11
gcc: QMAKE_CXXFLAGS += -Wno-deprecated-declarations
40 changes: 30 additions & 10 deletions build/python.prf
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,27 @@ isEmpty( PYTHON_DIR ) {
PYTHON_DIR=$${PYTHON_DIR}/
}

message(Using Python version $${PYTHON_VERSION})
PYTHON_VERSION_MAJOR=$$section(PYTHON_VERSION, ., 0, 0)
PYTHON_VERSION_MINOR=$$section(PYTHON_VERSION, ., 1, 1)

macx {
!equals(PYTHON_VERSION, $${PYTHON_VERSION_MAJOR}.$${PYTHON_VERSION_MINOR}) {
error("Failed to parse PYTHON_VERSION:\"$$PYTHON_VERSION\"")
} else {
message(Using Python version $${PYTHON_VERSION})
}


# Python 2.x has problems:
# 1) https://wiki.gentoo.org/wiki/Project:Python/Strict_aliasing
# 2) deprecated implicit cast of string literals to char*
equals(PYTHON_VERSION_MAJOR, 2):gcc:QMAKE_CXXFLAGS *= -fno-strict-aliasing -Wno-error=write-strings
contains(PKGCONFIG, "python.*"){
CONFIG += link_pkgconfig
PYTHON_PKGCONFIG = $$member($$unique($$find(PKGCONFIG, "python.*")), 1, 1)
# add rpath
PYTHON_LIBDIR = $$system($$pkgConfigExecutable() --libs-only-L $$PYTHON_PKGCONFIG)
QMAKE_RPATHDIR += $$replace(PYTHON_LIBDIR,-L,)
} else:macx:isEmpty(PYTHON_DIR){
# for macx you need to have the Python development kit installed as framework
INCLUDEPATH += /System/Library/Frameworks/Python.framework/Headers
LIBS += -F/System/Library/Frameworks -framework Python
Expand Down Expand Up @@ -52,15 +70,17 @@ macx {
# make sure that you have installed a matching python-dev package.

PYTHON_CONFIG = $${PYTHON_DIR}/bin/python$${PYTHON_VERSION}-config
system($${PYTHON_CONFIG} --embed --libs) {
unix:LIBS += $$system($${PYTHON_CONFIG} --embed --libs)
} else: unix:LIBS += $$system($${PYTHON_CONFIG} --libs)
unix:QMAKE_CXXFLAGS += $$system($${PYTHON_CONFIG} --includes)
PYTHON_CONFIG_OPTIONS_LIBS = --libs
equals(PYTHON_VERSION_MAJOR, 3):!lessThan(PYTHON_VERSION_MINOR, 8) {
# Since 3.8 `--embed` is needed
PYTHON_CONFIG_OPTIONS_LIBS += --embed
}
LIBS += $$system($${PYTHON_CONFIG} $${PYTHON_CONFIG_OPTIONS_LIBS})
QMAKE_CXXFLAGS += $$system($${PYTHON_CONFIG} --includes)
PYTHON_LFLAGS = $$system($${PYTHON_CONFIG} --ldflags)
unix:QMAKE_LFLAGS += $${PYTHON_LFLAGS}
QMAKE_LFLAGS += $${PYTHON_LFLAGS}
# add rpath
PYTHON_LIBDIR = $$find(PYTHON_LFLAGS,-L.*)
RPATH = -Wl,-rpath,
PYTHON_RPATH = $$replace(PYTHON_LIBDIR,-L,$${RPATH})
unix:QMAKE_LFLAGS += $${PYTHON_RPATH}
PYTHON_RPATH = $$replace(PYTHON_LIBDIR,-L,)
QMAKE_RPATHDIR += $$PYTHON_RPATH
}
6 changes: 2 additions & 4 deletions extensions/PythonQt_QtAll/PythonQt_QtAll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,5 @@ namespace PythonQt_QtAll
#ifdef PYTHONQT_WITH_UITOOLS
PythonQt_init_QtUiTools(0);
#endif
};
};


}
}
2 changes: 1 addition & 1 deletion extensions/PythonQt_QtAll/PythonQt_QtAll.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ namespace PythonQt_QtAll
{
//! initialize the Qt binding
PYTHONQT_QTALL_EXPORT void init();
};
}

#endif
68 changes: 37 additions & 31 deletions extensions/PythonQt_QtAll/PythonQt_QtAll.pro
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# get external pythonqtall config or enable all by default

isEmpty( PYTHONQTALL_CONFIG ) {
PYTHONQTALL_CONFIG = $$(PYTHONQTALL_CONFIG)
}

isEmpty( PYTHONQTALL_CONFIG ) {
message("using default PythonQt_QtAll Configuration")
CONFIG += PythonQtCore
CONFIG += PythonQtGui
CONFIG += PythonQtSvg
CONFIG += PythonQtSql
CONFIG += PythonQtNetwork
CONFIG += PythonQtOpengl
CONFIG += PythonQtXml
CONFIG += PythonQtXmlpatterns
CONFIG += PythonQtMultimedia
CONFIG += PythonQtQml
CONFIG += PythonQtQuick
CONFIG += PythonQtUiTools
qtHaveModule(gui):qtHaveModule(widgets):CONFIG += PythonQtGui
qtHaveModule(svg):CONFIG += PythonQtSvg
qtHaveModule(sql):CONFIG += PythonQtSql
qtHaveModule(network):CONFIG += PythonQtNetwork
qtHaveModule(opengl):CONFIG += PythonQtOpengl
qtHaveModule(xml):CONFIG += PythonQtXml
qtHaveModule(xmlpatterns):CONFIG += PythonQtXmlpatterns
qtHaveModule(multimedia):CONFIG += PythonQtMultimedia
qtHaveModule(qml):CONFIG += PythonQtQml
qtHaveModule(quick):CONFIG += PythonQtQuick
qtHaveModule(uitools):CONFIG += PythonQtUiTools

qtHaveModule(webkit):CONFIG += PythonQtWebKit
} else {
Expand All @@ -36,10 +40,10 @@ CONFIG += dll qt
DEFINES += PYTHONQT_QTALL_EXPORTS

HEADERS += \
PythonQt_QtAll.h
$$PWD/PythonQt_QtAll.h

SOURCES += \
PythonQt_QtAll.cpp
$$PWD/PythonQt_QtAll.cpp

unix {
CONFIG += create_pc create_prl no_install_prl
Expand All @@ -60,79 +64,81 @@ headers.path = /include

INSTALLS += target headers

defineTest(Xinclude) {
f=$$PYTHONQT_GENERATED_PATH/$$1/$${1}.pri
exists($$f):include($$f):export(HEADERS):export(SOURCES):export(DEFINES)

}


PythonQtCore {
DEFINES += PYTHONQT_WITH_CORE
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_core/com_trolltech_qt_core.pri)
Xinclude (com_trolltech_qt_core)
}

PythonQtGui {
DEFINES += PYTHONQT_WITH_GUI
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_gui/com_trolltech_qt_gui.pri)
Xinclude (com_trolltech_qt_gui)
QT += gui widgets printsupport
}

PythonQtSvg {
DEFINES += PYTHONQT_WITH_SVG
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_svg/com_trolltech_qt_svg.pri)
Xinclude (com_trolltech_qt_svg)
QT +=svg
}

PythonQtSql {
DEFINES += PYTHONQT_WITH_SQL
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_sql/com_trolltech_qt_sql.pri)
Xinclude (com_trolltech_qt_sql)
QT += sql
}

PythonQtNetwork {
DEFINES += PYTHONQT_WITH_NETWORK
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_network/com_trolltech_qt_network.pri)
Xinclude (com_trolltech_qt_network)
QT += network
}

PythonQtOpengl {
DEFINES += PYTHONQT_WITH_OPENGL
PythonQtCore: include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_opengl/com_trolltech_qt_opengl.pri)
QT += opengl
}

PythonQtXml {
DEFINES += PYTHONQT_WITH_XML
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_xml/com_trolltech_qt_xml.pri)
PythonQtCore: Xinclude (com_trolltech_qt_opengl)
QT += xml
}

PythonQtXmlpatterns {
DEFINES += PYTHONQT_WITH_XMLPATTERNS
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_xmlpatterns/com_trolltech_qt_xmlpatterns.pri)
Xinclude (com_trolltech_qt_xmlpatterns)
QT += xmlpatterns
}

PythonQtMultimedia {
DEFINES += PYTHONQT_WITH_MULTIMEDIA
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_multimedia/com_trolltech_qt_multimedia.pri)
QT += multimedia multimediawidgets
Xinclude (com_trolltech_qt_multimedia)
QT += multimedia multimediawidgets
}

PythonQtQml {
DEFINES += PYTHONQT_WITH_QML
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_qml/com_trolltech_qt_qml.pri)
Xinclude (com_trolltech_qt_qml)
QT += qml
}

PythonQtQuick {
DEFINES += PYTHONQT_WITH_QUICK
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_quick/com_trolltech_qt_quick.pri)
Xinclude (com_trolltech_qt_quick)
QT += quick quickwidgets
}

PythonQtUiTools {
DEFINES += PYTHONQT_WITH_UITOOLS
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_uitools/com_trolltech_qt_uitools.pri)
Xinclude (com_trolltech_qt_uitools)
QT += uitools
}

PythonQtWebKit {
DEFINES += PYTHONQT_WITH_WEBKIT
include ($$PYTHONQT_GENERATED_PATH/com_trolltech_qt_webkit/com_trolltech_qt_webkit.pri)
Xinclude (com_trolltech_qt_webkit)
QT += webkit webkitwidgets
}
11 changes: 8 additions & 3 deletions generator/abstractmetabuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue,
AbstractMetaEnum *meta_enum,
AbstractMetaFunction *meta_function)
{
Q_UNUSED(meta_function)
if (stringValue.isEmpty())
return oldValuevalue;

Expand Down Expand Up @@ -1619,12 +1620,15 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu

// If we where not able to translate the default argument make it
// reset all default arguments before this one too.
for (int i=0; i<first_default_argument; ++i)
for (int i=0; i<first_default_argument; ++i) {
meta_arguments[i]->setDefaultValueExpression(QString());
}

if (ReportHandler::debugLevel() == ReportHandler::FullDebug)
foreach(AbstractMetaArgument *arg, meta_arguments)
if (ReportHandler::debugLevel() == ReportHandler::FullDebug) {
foreach(AbstractMetaArgument *arg, meta_arguments) {
ReportHandler::debugFull(" - " + arg->toString());
}
}

return meta_function;
}
Expand Down Expand Up @@ -1944,6 +1948,7 @@ QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, Abstr
AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class,
int argument_index)
{
Q_UNUSED(type)
QString function_name = fnc->name();
QString class_name = implementing_class->name();

Expand Down
4 changes: 2 additions & 2 deletions generator/abstractmetalang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,13 +1205,13 @@ AbstractMetaField *AbstractMetaField::copy() const

return returned;
}

/* UNUSED
static QString upCaseFirst(const QString &str) {
Q_ASSERT(!str.isEmpty());
QString s = str;
s[0] = s.at(0).toUpper();
return s;
}
} */

static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, uint type) {
AbstractMetaFunction *f = new AbstractMetaFunction;
Expand Down
2 changes: 1 addition & 1 deletion generator/generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Generator : public QObject
{
Q_OBJECT

Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory);
Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory)

public:
enum Option {
Expand Down
12 changes: 7 additions & 5 deletions generator/generator.pri
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ isEmpty(GENERATORPATH):GENERATORPATH = $$PWD
INCLUDEPATH += $$GENERATORPATH

TEMPLATE = app
#CONFIG += cmdline -- does not work as expected with old Qt versions, f.e. is missing in 5.9
CONFIG += console
CONFIG -= app_bundle

TARGET +=
DEPENDPATH += $$GENERATORPATH tests parser
mac:CONFIG -= app_bundle
INCLUDEPATH += $$GENERATORPATH/.
INCLUDEPATH += $$GENERATORPATH/../common

unix:CONFIG += debug_and_release

CONFIG += console
RESOURCES += generator.qrc

include($$GENERATORPATH/parser/rxx.pri)
Expand All @@ -21,6 +21,8 @@ win32-msvc2005:{
QMAKE_CXXFLAGS += -wd4996
QMAKE_CFLAGS += -wd4996
}
gcc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wpedantic
clang: QMAKE_CXXFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unused-private-field

# Input
HEADERS += \
Expand Down Expand Up @@ -58,7 +60,7 @@ SOURCES += \



QT = core xml
QT += core xml

win32-msvc.net {
QMAKE_CXXFLAGS += /Zm500
Expand Down
4 changes: 1 addition & 3 deletions generator/generator.pro
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
TARGET = pythonqt_generator
CONFIG -= debug
CONFIG += release
DESTDIR = .

include(generator.pri)

DEFINES += QT_NO_CAST_TO_ASCII

# Input
HEADERS += \
Expand Down
8 changes: 4 additions & 4 deletions generator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void displayHelp(GeneratorSet *generatorSet);
#include <QDebug>
int main(int argc, char *argv[])
{
GeneratorSet *gs = GeneratorSet::getInstance();
QScopedPointer<GeneratorSet> gs(GeneratorSet::getInstance());

QString default_file = ":/trolltech/generator/qtscript_masterinclude.h";
QString default_system = ":/trolltech/generator/build_all.txt";
Expand Down Expand Up @@ -118,7 +118,7 @@ int main(int argc, char *argv[])

typesystemFileName = args.value("arg-2");
if (args.contains("arg-3"))
displayHelp(gs);
displayHelp(&*gs);

if (fileName.isEmpty())
fileName = default_file;
Expand All @@ -127,10 +127,10 @@ int main(int argc, char *argv[])
typesystemFileName = default_system;

if (fileName.isEmpty() || typesystemFileName.isEmpty() )
displayHelp(gs);
displayHelp(&*gs);

if (!gs->readParameters(args))
displayHelp(gs);
displayHelp(&*gs);

printf("Please wait while source files are being generated...\n");

Expand Down
4 changes: 2 additions & 2 deletions generator/parser/codemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ bool TypeInfo::operator==(const TypeInfo &other)
}
#endif

return flags == other.flags
return m_flags.equals(other.m_flags)
&& m_qualifiedName == other.m_qualifiedName
&& (!m_functionPointer || m_arguments == other.m_arguments);
&& (!m_flags.m_functionPointer || m_arguments == other.m_arguments);
}

// ---------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit c780d89

Please sign in to comment.