Skip to content

Commit fb1eb93

Browse files
iakovmrbean-bremen
authored andcommitted
Tiny improvements for build system
* Basic `clang-msvc` support * Fixes for `msvc` and `mingw` * Support for LTO (`CONFIG+=ltcg`) builds on all platforms * Minor code improvements, including build scripts unification
1 parent cae3702 commit fb1eb93

File tree

12 files changed

+180
-37
lines changed

12 files changed

+180
-37
lines changed

.github/workflows/build.yml

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ jobs:
173173
set -eu
174174
PYTHON_VERSION_FULL=$(python --version 2>&1 | cut -f 2 -d ' ')
175175
PYTHON_VERSION_SHORT=$(cut -f 1,2 -d . <<< $PYTHON_VERSION_FULL)
176-
QT_VERSION_FULL=$($Qt5_DIR/bin/qmake -query QT_VERSION)
176+
QT_VERSION_FULL=$($Qt5_Dir/bin/qmake -query QT_VERSION)
177177
QT_VERSION_SHORT=$(cut -f 1,2 -d . <<< $QT_VERSION_FULL)
178178
MACOS_VERSION_FULL=$(sw_vers -productVersion)
179179
MACOS_VERSION_SHORT=$(cut -f 1,2 -d . <<< $MACOS_VERSION_FULL)
@@ -197,7 +197,7 @@ jobs:
197197
do if pkg-config --exists "$i"; then PYTHON_PKGCONFIG_NAME="$i"; break; fi; done
198198
qmake CONFIG+=release CONFIG+=sanitizer CONFIG+=sanitize_undefined \
199199
PYTHON_VERSION=${{ steps.versions.outputs.PYTHON_VERSION_SHORT }} \
200-
PYTHON_DIR="$pythonLocation" \
200+
PYTHON_PATH="$pythonLocation" \
201201
PKGCONFIG+=$PYTHON_PKGCONFIG_NAME \
202202
-r PythonQt.pro
203203
make -j 2 && make check TESTARGS="-platform offscreen"
@@ -206,11 +206,120 @@ jobs:
206206
run: |
207207
cd generator
208208
# workaround to allow to find the Qt include dirs for installed standard qt packages
209-
QTDIR=-UNDEFINED- ./pythonqt_generator --include-paths=$Qt5_DIR/lib
209+
QTDIR=-UNDEFINED- ./pythonqt_generator --include-paths=$Qt5_Dir/lib
210210
211211
- name: Upload Wrappers
212212
uses: actions/upload-artifact@v3
213213
with:
214214
name: wrappers_macos${{ steps.versions.outputs.MACOS_VERSION_SHORT }}_qt${{ steps.versions.outputs.QT_VERSION_SHORT }}
215215
path: generated_cpp
216216

217+
windows:
218+
strategy:
219+
fail-fast: false
220+
matrix:
221+
qt-arch: ['win64_mingw73']
222+
python-version: ['3.10']
223+
qt-version: ['5.12.*']
224+
python-arch: ['x64']
225+
pythonqtall-config: ['']
226+
# msvc-toolset: ['14.0']
227+
include:
228+
- qt-arch: 'win64_msvc2017_64'
229+
python-version: '3.6'
230+
python-arch: 'x64'
231+
qt-version: '5.11.*'
232+
# msvc-toolset: '14.16'
233+
234+
- qt-arch: 'win32_mingw53'
235+
python-version: '2.7'
236+
python-arch: 'x86'
237+
qt-version: '5.11.*'
238+
239+
#Either MSVC2015 is sick or Qt5.9 is buggy :(
240+
#Main problem is QBasicMutex with default ctor, that (by no means) is missing in dll-export of QtCore, but linker tries to find it
241+
# - qt-arch: 'win32_msvc2015'
242+
# python-version: '2.7'
243+
# python-arch: 'x86'
244+
# qt-version: '5.9.*'
245+
# pythonqtall-config: 'PythonQtCore PythonQtGui PythonQtMultimedia'
246+
247+
runs-on: windows-latest
248+
steps:
249+
250+
- name: Checkout PythonQt
251+
uses: actions/checkout@v3
252+
253+
- name: Reset PATH
254+
uses: egor-tensin/cleanup-path@v3
255+
256+
- name: Install MSVC++
257+
uses: ilammy/msvc-dev-cmd@v1
258+
if: ${{ contains(matrix.qt-arch, 'msvc') }}
259+
with:
260+
arch: amd64${{ contains(matrix.python-arch, 'x86') && '_x86' || '' }}
261+
262+
- name: Install Qt
263+
uses: jurplel/install-qt-action@v3
264+
with:
265+
aqtversion: '==2.1.*'
266+
version: ${{ matrix.qt-version }}
267+
host: 'windows'
268+
target: 'desktop'
269+
arch: ${{ matrix.qt-arch }}
270+
modules: 'qtscript'
271+
archives: 'qtwinextras qtmultimedia qtbase'
272+
tools: ${{ contains(matrix.qt-arch, 'mingw') && format('tools_mingw,qt.tools.{0}0', matrix.qt-arch) || '' }}
273+
274+
- name: Setup Python ${{ matrix.python-version }}
275+
uses: actions/setup-python@v4
276+
with:
277+
python-version: '${{ matrix.python-version }}'
278+
architecture: ${{ matrix.python-arch }}
279+
280+
- name: Detect exact versions
281+
shell: bash
282+
id: versions
283+
run: |
284+
set -eu
285+
QT_VERSION_FULL=$("$Qt5_Dir/bin/qmake" -query QT_VERSION)
286+
QT_VERSION_SHORT=$(cut -f 1,2 -d . <<< $QT_VERSION_FULL)
287+
PYTHON_VERSION_FULL=$(python --version 2>&1 | cut -f 2 -d ' ')
288+
PYTHON_VERSION_SHORT=$(cut -f 1,2 -d . <<< $PYTHON_VERSION_FULL)
289+
echo "QT_VERSION_FULL=$QT_VERSION_FULL" | tee -a $GITHUB_OUTPUT
290+
echo "QT_VERSION_SHORT=$QT_VERSION_SHORT" | tee -a $GITHUB_OUTPUT
291+
echo "PYTHON_VERSION_SHORT=$PYTHON_VERSION_SHORT" | tee -a $GITHUB_OUTPUT
292+
293+
- name: Add Qt and MinGW to PATH
294+
shell: cmd
295+
run: |
296+
set "ADDPATH=%Qt5_Dir%\bin"
297+
${{ contains(matrix.qt-arch, 'mingw') && format('FOR /F "tokens=1,2 delims=_" %%I IN ("{0}") DO SET "ADDPATH=%ADDPATH%;%IQTA_TOOLS%\%%J0_{1}\bin', matrix.qt-arch, contains(matrix.qt-arch, 'win32') && '32' || '64') || '' }}
298+
echo PATH=%ADDPATH%;%PATH% >> %GITHUB_ENV%
299+
echo CL=/MP >> $GITHUB_ENV
300+
301+
- name: Build PythonQt
302+
shell: cmd
303+
run: |
304+
qmake -query
305+
python --version
306+
qmake CONFIG+=release CONFIG-=debug_and_release CONFIG-=debug_and_release_target ^
307+
"PYTHONQTALL_CONFIG=${{ matrix.pythonqtall-config }}" ^
308+
"PYTHON_PATH=%pythonLocation%" ^
309+
"PYTHON_VERSION=${{ steps.versions.outputs.PYTHON_VERSION_SHORT }}" ^
310+
PythonQt.pro
311+
mingw32-make -j 2 && mingw32-make check "TESTARGS=-platform offscreen" ^
312+
|| nmake && nmake check "TESTARGS=-platform offscreen"
313+
314+
- name: Generate Wrappers
315+
shell: cmd
316+
run: |
317+
cd generator
318+
set QTDIR=%Qt5_Dir%
319+
pythonqt_generator
320+
321+
- name: Upload Wrappers
322+
uses: actions/upload-artifact@v3
323+
with:
324+
name: wrappers_${{ matrix.qt-arch }}_${{ steps.versions.outputs.QT_VERSION_SHORT }}
325+
path: generated_cpp

build/PythonQt.prf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ CONFIG(debug, debug|release) {
1212
}
1313

1414
win32-g++: LIBS += $$DESTDIR/../lib/PythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}.dll
15-
win32-msvc*: LIBS += $$DESTDIR/../lib/PythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}.lib
15+
win32-*msvc*: LIBS += $$DESTDIR/../lib/PythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}.lib
1616
unix: LIBS += -L$$DESTDIR/../lib -lPythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}

build/common.prf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp
7070
}
7171

7272
VERSION = 3.2.0
73-
73+
greaterThan(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 9): CONFIG += c++11
7474
win32: CONFIG += skip_target_version_ext
75-
unix: CONFIG += c++11
76-
gcc: QMAKE_CXXFLAGS += -Wno-deprecated-declarations
75+
gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wuninitialized -Winit-self -ansi -pedantic
76+
win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-unused-command-line-argument
77+
#Do not issue warning to system includes
78+
gcc:!isEmpty(QT_INSTALL_HEADERS): QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_HEADERS]

build/python.prf

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ isEmpty( PYTHON_VERSION ) {
66
PYTHON_VERSION=$$(PYTHON_VERSION)
77
}
88
isEmpty( PYTHON_VERSION ) {
9-
win32:PYTHON_VERSION=27
10-
unix:PYTHON_VERSION=2.7
9+
PYTHON_VERSION=2.7
1110
}
1211

1312
isEmpty( PYTHON_DIR ) {
@@ -30,8 +29,18 @@ PYTHON_VERSION_MINOR=$$section(PYTHON_VERSION, ., 1, 1)
3029
# Python 2.x has problems:
3130
# 1) https://wiki.gentoo.org/wiki/Project:Python/Strict_aliasing
3231
# 2) deprecated implicit cast of string literals to char*
33-
equals(PYTHON_VERSION_MAJOR, 2):gcc:QMAKE_CXXFLAGS *= -fno-strict-aliasing -Wno-error=write-strings
32+
equals(PYTHON_VERSION_MAJOR, 2) {
33+
gcc:QMAKE_CXXFLAGS *= -fno-strict-aliasing -Wno-write-strings
34+
# Qt 5.4 adds this option, but this is not compatible with the Python API
35+
msvc: QMAKE_CXXFLAGS -= -Zc:strictStrings
36+
}
37+
3438
contains(PKGCONFIG, "python.*"){
39+
# If `pkg-config` is configured, use `qmake PKGCONFIG+=python3.8-embed CONFIG+=...`
40+
# or `PKGCONFIG+=python2.7m`-like form for older versions,
41+
# see `pkg-config --list-all | grep python` for details.
42+
# This can help with GNU/Linux (including macOS with Homebrew), MSYS2/MinGW environment,
43+
# and also with OpenEmbedded and other cross-builds
3544
CONFIG += link_pkgconfig
3645
PYTHON_PKGCONFIG = $$member($$unique($$find(PKGCONFIG, "python.*")), 1, 1)
3746
# add rpath
@@ -63,8 +72,26 @@ contains(PKGCONFIG, "python.*"){
6372
DEBUG_EXT =
6473
}
6574

66-
win32:INCLUDEPATH += $$(PYTHON_PATH)/PC $$(PYTHON_PATH)/include
67-
win32:LIBS += $$(PYTHON_LIB)/python$${PYTHON_VERSION}$${DEBUG_EXT}.lib
75+
isEmpty(PYTHON_PATH):PYTHON_PATH=$(PYTHON_PATH)
76+
isEmpty(PYTHON_PATH)|!exists("$$PYTHON_PATH\\include") | !exists("$$PYTHON_PATH\\libs\\") {
77+
error("PYTHON_PATH must be set to correct folder with \\libs and \\include subfolders ")
78+
}
79+
80+
#We need to destinguish 64-bit build to add a workaround option
81+
#The only known problematic case is MinGW with external (MSVC-built) Python2
82+
mingw:equals(PYTHON_VERSION_MAJOR, 2): isEmpty(QMAKE_TARGET.arch):system(\
83+
$$system_quote($$system_path($${PYTHON_PATH}/python.exe)) -c \
84+
$$system_quote(import sysconfig;exit(0 if 0 <= sysconfig.get_platform().find(\'win-amd64\') else 1))\
85+
):DEFINES += MS_WIN64
86+
87+
INCLUDEPATH += $$shell_path($${PYTHON_PATH}/include)
88+
89+
LIBS += $$shell_path(-L$${PYTHON_PATH}/libs)
90+
LIBS += -lpython$${PYTHON_VERSION_MAJOR}$${PYTHON_VERSION_MINOR}$${DEBUG_EXT}
91+
92+
# Hack for "CONFIG+=testcase" and 'make check' to add python's dll to PATH
93+
deppath += $$shell_path($${PYTHON_PATH})
94+
6895
} else:unix {
6996
# on linux, python-config is used to autodetect Python.
7097
# make sure that you have installed a matching python-dev package.

extensions/PythonQt_QtAll/PythonQt_QtAll.pro

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ include ( ../../build/common.prf )
3535
include ( ../../build/PythonQt.prf )
3636
TARGET = $$replace(TARGET, PythonXY, Python$${PYTHON_VERSION})
3737

38-
CONFIG += dll qt
38+
CONFIG += qt strict_c++
39+
40+
!static:!staticlib {
41+
CONFIG += dll
42+
# Force linker to complain on undefined references for dll/so/dylib build when possible
43+
QMAKE_LFLAGS_SHLIB += $$QMAKE_LFLAGS_NOUNDEF
44+
}
3945

4046
DEFINES += PYTHONQT_QTALL_EXPORTS
4147

@@ -74,6 +80,7 @@ defineTest(Xinclude) {
7480
PythonQtCore {
7581
DEFINES += PYTHONQT_WITH_CORE
7682
Xinclude (com_trolltech_qt_core)
83+
QT += core
7784
}
7885

7986
PythonQtGui {
@@ -85,7 +92,7 @@ PythonQtGui {
8592
PythonQtSvg {
8693
DEFINES += PYTHONQT_WITH_SVG
8794
Xinclude (com_trolltech_qt_svg)
88-
QT +=svg
95+
QT += svg
8996
}
9097

9198
PythonQtSql {

generator/generator.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@
4242
#ifndef GENERATOR_H
4343
#define GENERATOR_H
4444

45-
#include "metajava.h"
46-
#include "typesystem.h"
47-
48-
#include "codemodel.h"
45+
#include "abstractmetalang.h"
4946

5047
#include <QObject>
5148
#include <QFile>
@@ -57,7 +54,7 @@ class Generator : public QObject
5754
Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory)
5855

5956
public:
60-
enum Option {
57+
enum Option:uint32_t {
6158
NoOption = 0x00000000,
6259
BoxedPrimitive = 0x00000001,
6360
ExcludeConst = 0x00000002,

generator/generator.pri

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ include($$GENERATORPATH/parser/rxx.pri)
1717

1818
include($$GENERATORPATH/parser/rpp/rpp.pri)
1919

20-
win32-msvc2005:{
20+
CONFIG += strict_c++ c++11
21+
win32-msvc*{
22+
#Disable warning C4996 (deprecated declarations)
2123
QMAKE_CXXFLAGS += -wd4996
2224
QMAKE_CFLAGS += -wd4996
25+
#Disable warnings for external headers
26+
greaterThan(QMAKE_MSC_VER, 1599):QMAKE_CXXFLAGS += -external:anglebrackets -external:W0 -external:templates-
2327
}
24-
gcc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wpedantic
25-
clang: QMAKE_CXXFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unused-private-field
28+
#Do not issue warning to Qt's system includes
29+
gcc:!isEmpty(QT_INSTALL_HEADERS): QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_HEADERS]
30+
gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -pedantic -ansi -Winit-self -Wuninitialized
31+
clang|win32-clang-msvc: QMAKE_CXXFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unused-private-field
32+
win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-language-extension-token -Wno-microsoft-enum-value
33+
2634

2735
# Input
2836
HEADERS += \

generator/shellheadergenerator.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
****************************************************************************/
4141

4242
#include "shellheadergenerator.h"
43-
#include "fileout.h"
4443

4544
#include <QtCore/QDir>
4645

@@ -156,7 +155,6 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c
156155
s << "};" << endl;
157156
}
158157
s << endl;
159-
const AbstractMetaClass* c = meta_class;
160158
s << " ~" << shellClassName(meta_class) << "()" << (meta_class->hasVirtualDestructor() ? " override" : "") << ";" << endl;
161159
s << endl;
162160

generator/shellimplgenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
176176
s << " }" << endl;
177177
s << " }" << endl;
178178
}
179-
s << " if (result) { Py_DECREF(result); } " << endl;
179+
s << " if (result) { Py_DECREF(result); }" << endl;
180180
s << " Py_DECREF(obj);" << endl;
181181
// ugly hack, we don't support QGraphicsScene* nor QGraphicsItem* QVariants in PythonQt...
182182
if (fun->name() == "itemChange" && fun->type() && fun->type()->isVariant()) {

src/src.pri

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ INCLUDEPATH += $$PWD
44

55
CONFIG += c++11
66

7-
gcc:!no_warn {
8-
!clang:QMAKE_CXXFLAGS += -Werror -Wno-error=missing-field-initializers
9-
clang:QMAKE_CXXFLAGS += -Wno-error=sometimes-uninitialized
10-
}
7+
gcc:!no_warn:!clang:QMAKE_CXXFLAGS += -Wno-error=missing-field-initializers
8+
*-clang*:!no_warn:QMAKE_CXXFLAGS += -Wno-error=sometimes-uninitialized
119

1210
# This was needed to work around "number of sections exceeded object file format limit" linker error
1311
win32-msvc*:QMAKE_CXXFLAGS += /bigobj
14-
win32-g++: QMAKE_CXXFLAGS += -Wa,-mbig-obj
12+
!ltcg:win32-g++: QMAKE_CXXFLAGS += -Wa,-mbig-obj
13+
14+
# Force linker to complain on undefined references for dll/so/dylib build when possible
15+
QMAKE_LFLAGS_SHLIB += $$QMAKE_LFLAGS_NOUNDEF
1516

1617
HEADERS += \
1718
$$PWD/PythonQt.h \

src/src.pro

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@
77
TARGET = PythonQt-Qt5-PythonXY
88
TEMPLATE = lib
99

10-
1110
DESTDIR = ../lib
1211

1312
CONFIG += qt
1413
CONFIG -= flat
1514

16-
mingw:QMAKE_CXXFLAGS+=-Wa,-mbig-obj
17-
1815
# allow to choose static linking through the environment variable PYTHONQT_STATIC
1916
isEmpty(PYTHONQT_STATIC) {
2017
PYTHONQT_STATIC = $$(PYTHONQT_STATIC)
@@ -31,9 +28,6 @@ DEFINES += PYTHONQT_CATCH_ALL_EXCEPTIONS
3128
contains(QT_MAJOR_VERSION, 5) {
3229
QT += widgets core-private
3330
}
34-
35-
# Qt 5.4 adds this option, but this is not compatible with the Python API
36-
QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
3731

3832
INCLUDEPATH += $$PWD
3933

tests/tests.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mingw: TEST_TARGET_DIR = .
1717

1818
DEFINES += QT_NO_CAST_TO_ASCII
1919

20-
gcc: QMAKE_CXXFLAGS += -Wpedantic
20+
gcc: QMAKE_CXXFLAGS += -pedantic -ansi -Winit-self -Wuninitialized
2121

2222
contains(QT_MAJOR_VERSION, 5) {
2323
QT += widgets

0 commit comments

Comments
 (0)