Improve the build speed by 2-3X by using PCH (#4746)

* Improve the build speed by 2-3X by using PCH. This avoids rebuilding large parts of QT and C++ std headers over and over.
* Unfortunately QMake is too opinionated for this to work on macOS so it is used on Windows and Linux only.
* Remove qwindowsvistastyle.dll opengl32sw.dll from QT6 as they're not needed.
* Revert fa84a37 since we don't need it anymore.
This commit is contained in:
Magnus Gille
2025-12-10 10:38:29 -08:00
committed by GitHub
parent 06ed87db09
commit bf20980dd1
9 changed files with 119 additions and 14 deletions

13
.gitignore vendored
View File

@@ -64,3 +64,16 @@ doc/contrib/WASP Packet Protocol.pdf
# Qt testlib
target_wrapper.sh
# Precompiled Headers
*.gch
*.pch
*.gch/
_pch/
# Generated Source Files
*_lex.cpp
*_yacc.cpp
*_yacc.h
qrc_*.cpp

View File

@@ -221,12 +221,12 @@ build_script:
# Windows
- cmd: qmake.exe build.pro -r -spec win32-msvc
- cmd: if not exist qwt\lib\qwt.lib jom -j1 sub-qwt & exit /b 1
- cmd: if not exist qwt\lib\qwt.lib jom -j1 sub-qwt
- cmd: jom -j2 sub-src
# Linux / macOS
- sh: qmake build.pro -r QMAKE_CXXFLAGS_WARN_ON+="-Wno-unused-private-field -Wno-c++11-narrowing -Wno-deprecated-declarations -Wno-deprecated-register -Wno-nullability-completeness -Wno-sign-compare -Wno-inconsistent-missing-override" QMAKE_CFLAGS_WARN_ON+="-Wno-deprecated-declarations -Wno-sign-compare"
- sh: if test ! -f qwt/lib/libqwt.a; then make sub-qwt; false; fi
- sh: if test ! -f qwt/lib/libqwt.a; then make sub-qwt; fi
- sh: make -j2 sub-src
after_build:

View File

@@ -14,6 +14,9 @@ include( $${QWT_ROOT}/qwtconfig.pri )
include( $${QWT_ROOT}/qwtbuild.pri )
include( $${QWT_ROOT}/qwtfunctions.pri )
# Fix for parallel build race condition where moc_predefs.h is missing
compiler_moc_header_make_all.depends += compiler_moc_predefs_make_all
QWT_OUT_ROOT = $${OUT_PWD}/..
TEMPLATE = lib

View File

@@ -41,6 +41,7 @@ class Perspective;
#include <QMetaType>
#include <QFrame>
#include <QtGui>
#include <QObject>
#include "GcWindowRegistry.h"
#include "TimeUtils.h"
@@ -121,10 +122,10 @@ private:
int oWidth, oHeight, oX, oY, mX, mY;
double oHeightFactor, oWidthFactor;
public slots:
public Q_SLOTS:
void _closeWindow();
signals:
Q_SIGNALS:
void controlsChanged(QWidget*);
void titleChanged(QString);
void subtitleChanged(QString);
@@ -302,7 +303,7 @@ public:
void setControls(QWidget *x);
void addHelper(QString name, QWidget *widget); // add to the overlay widget
public slots:
public Q_SLOTS:
void hideRevealControls();
void saveImage();
void saveChart();

View File

@@ -28,6 +28,7 @@
#include <QRadioButton>
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QObject>
QString interval_to_str(double secs); // output like 1h 2m 3s
double str_to_interval(QString s); // convert 1h 2m 3s -> 3123.0 , e.g.
@@ -81,7 +82,7 @@ class DateRange : QObject
bool isValid() const { return valid; }
signals:
Q_SIGNALS:
void changed(QDate from, QDate to);
protected:
@@ -133,10 +134,10 @@ class DateSettingsEdit : public QWidget
int prevN() { return prevperiod->value(); }
void setPrevN(int x) { return prevperiod->setValue(x); }
private slots:
private Q_SLOTS:
void setDateSettings();
signals:
Q_SIGNALS:
void useStandardRange();
void useThruToday();
void useCustomRange(DateRange);

View File

@@ -79,10 +79,10 @@ class RideFileCommand : public QObject
int undoCount();
int redoCount();
public slots:
public Q_SLOTS:
void clearHistory();
signals:
Q_SIGNALS:
void beginCommand(bool undo, RideCommand *cmd);
void endCommand(bool undo, RideCommand *cmd);

View File

@@ -127,7 +127,6 @@ Section "Golden Cheetah (required)" Sec1
SetOutPath "$INSTDIR\platforms"
File "platforms\qwindows.dll"
SetOutPath "$INSTDIR"
File "opengl32sw.dll"
File "OpenSSL License.txt"
SetOutPath "$INSTDIR\position"
File "position\qtposition_nmea.dll"
@@ -218,7 +217,6 @@ Section "Golden Cheetah (required)" Sec1
File "sqldrivers\qsqlpsql.dll"
SetOutPath "$INSTDIR\styles"
File "styles\qmodernwindowsstyle.dll"
File "styles\qwindowsvistastyle.dll"
SetOutPath "$INSTDIR\tls"
File "tls\qcertonlybackend.dll"
File "tls\qopensslbackend.dll"
@@ -369,7 +367,6 @@ Section Uninstall
Delete "$INSTDIR\license.txt"
Delete "$INSTDIR\multimedia\ffmpegmediaplugin.dll"
Delete "$INSTDIR\multimedia\windowsmediaplugin.dll"
Delete "$INSTDIR\opengl32sw.dll"
Delete "$INSTDIR\OpenSSL License.txt"
Delete "$INSTDIR\networkinformation\qnetworklistmanager.dll"
Delete "$INSTDIR\platforms\qwindows.dll"
@@ -454,7 +451,6 @@ Section Uninstall
Delete "$INSTDIR\sqldrivers\qsqlodbc.dll"
Delete "$INSTDIR\sqldrivers\qsqlpsql.dll"
Delete "$INSTDIR\styles\qmodernwindowsstyle.dll"
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
Delete "$INSTDIR\tls\qcertonlybackend.dll"
Delete "$INSTDIR\tls\qopensslbackend.dll"
Delete "$INSTDIR\tls\qschannelbackend.dll"

View File

@@ -45,6 +45,13 @@ greaterThan(QT_MAJOR_VERSION, 5) {
}
CONFIG += c++11
###==========================
### PRECOMPILED HEADER
###==========================
PRECOMPILED_HEADER = stable.h
CONFIG += precompile_header
###=======================================================================
### Directory Structure - Split into subdirs to be more manageable
@@ -155,6 +162,10 @@ macx {
HEADERS += Train/VideoWindow.h
SOURCES += Train/VideoWindow.cpp
# PCH crashes clang if we have multiple -arch flags (universal binary)
message("Disabling Precompiled Headers on macOS to avoid multi-arch Clang errors.")
CONFIG -= precompile_header
} else {
# not on mac we need our own full screen support and segment control button
@@ -165,6 +176,8 @@ macx {
SOURCES += Train/VideoWindow.cpp
}
# X11
if (defined(GC_WANT_X11)) {
LIBS += -lX11
@@ -587,6 +600,9 @@ LEXSOURCES += Core/DataFilter.l \
Train/WorkoutFilter.l \
Train/TrainerDayAPIQuery.l
# Fix parallel build races (YACC headers must exist before LEX runs)
compiler_lex_make_all.depends += compiler_yacc_decl_make_all
###=========================================
### HEADER FILES [scanned by qmake, for moc]
@@ -830,3 +846,17 @@ DEFERRES += Core/RouteWindow.h Core/RouteWindow.cpp Core/RouteItem.h Core/RouteI
OTHER_FILES += Resources/python/library.py Python/SIP/goldencheetah.sip
###============================================================================
### FIX: Disable Precompiled Header for C files
### The PCH contains C++ specific headers (Qt, STL) which causes compilation errors
### when the PCH is forced upon C files by gcc.
###============================================================================
for(src, SOURCES) {
contains(src, .*\.c$) {
eval($${src}.CONFIG -= precompile_header)
}
}

61
src/stable.h Normal file
View File

@@ -0,0 +1,61 @@
/*
* stable.h - Precompiled Header for GoldenCheetah
*
* PURPOSE:
* This file contains the "Precompiled Header" (PCH) for the project.
* It includes massive, stable headers (like Qt and standard library) that rarely change.
* The compiler parses this file ONCE and reuses the binary result for every other source file,
* significantly speeding up build times.
*
* HOW TO MODIFY:
* 1. ONLY add headers here that are:
* - Very commonly used (included in many files).
* - STABLE (they almost never change).
* 2. DO NOT add local project headers (e.g. "Athlete.h") unless they are extremely stable.
* If you change a header listed here, the ENTIRE project will rebuild from scratch.
* 3. After modifying this file, run `make clean` to ensure the PCH is regenerated.
*/
#ifndef STABLE_H
#define STABLE_H
#if defined(__cplusplus)
// C++ Standard Library
#include <vector>
#include <cmath>
#include <string>
#include <iostream>
// Qt Core
#include <QtCore>
#include <QObject>
#include <QString>
#include <QList>
#include <QVector>
#include <QMap>
#include <QDebug>
#include <QDateTime>
#include <QTimer>
#include <QFile>
#include <QDir>
#include <QSettings>
// Qt GUI / Widgets
#include <QtGui>
#include <QtWidgets>
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QLayout>
#include <QPainter>
#include <QPaintEvent>
#include <QColor>
#include <QFont>
#endif
#endif // STABLE_H