如何使用 mingw-w64 构建具有 link 时间优化的 Qt?

How can I build Qt with link-time optimization using mingw-w64?

使用 g++ 8.1.0 使用 mingw-w64 构建 Qt 5.12.3 效果很好。但是一旦我将选项 -ltcg 添加到 configure 参数,我就会遇到构建错误。

配置调用如下所示:

../qt5/configure -prefix ../qt5Install -release -recheck-all -ltcg -confirm-license -opensource -platform win32-g++ -opengl desktop -nomake examples -nomake tests -system-freetype -I /c/Libraries/OpenCascade/3rdPartyMingw64/freetype-2.6.3-mingw-64/include -L/c/Libraries/OpenCascade/3rdPartyMingw64/freetype-2.6.3-mingw-64/bin -skip qtconnectivity -skip qtdeclarative -skip qtlocation -skip qtmultimedia -skip qtquickcontrols -skip qtquickcontrols2 -skip qtsensors -skip qtwebsockets -skip qtwinextras -skip qtwebchannel -skip qtwebengine

有没有人设法使用 mingw-w64 构建具有 link 时间优化的 Qt?有什么诀窍?

这里的构建错误是:

g++ -Wl,-s -shared -fno-keep-inline-dllexport -O3 -std=c++1z -fno-exceptions -flto -Wl,-subsystem,windows -Wl,--out-implib,C:/Libraries/qt/qt5Build/qtbase/lib/libQt5Gui.a -o ../../lib/Qt5Gui.dll @object_script.Qt5Gui.Release  -LC:/Libraries/OpenCascade/3rdPartyMingw64/freetype-2.6.3-mingw-64/bin -LC:/Libraries/qt/qt5Build/qtbase/lib C:/Libraries/qt/qt5Build/qtbase/lib/libQt5Core.a .obj/release/Qt5Gui_resource_res.o C:/Libraries/qt/qt5Build/qtbase/lib/libqtlibpng.a -LC:/Libraries/OpenCascade/3rdPartyMingw64/freetype-2.6.3-mingw-64/bin C:/Libraries/qt/qt5Build/qtbase/lib/libqtharfbuzz.a C:/mingw-w64-8.1/mingw64/x86_64-w64-mingw32/lib/libz.a -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32 C:/mingw-w64-8.1/mingw64/x86_64-w64-mingw32/lib/libglu32.a C:/mingw-w64-8.1/mingw64/x86_64-w64-mingw32/lib/libopengl32.a C:/mingw-w64-8.1/mingw64/x86_64-w64-mingw32/lib/libgdi32.a C:/mingw-w64-8.1/mingw64/x86_64-w64-mingw32/lib/libuser32.a
.obj/release/qimage_compat.o (symbol from plugin):(.gnu.linkonce.t._ZTS12QPaintDevice+0x0): multiple definition of `typeinfo name for QPaintDevice'
.obj/release/qimage_ssse3.o:qimage_ssse3.cpp:(.rdata$_ZTS12QPaintDevice[_ZTS12QPaintDevice]+0x0): first defined here
.obj/release/qimage_compat.o (symbol from plugin):(.gnu.linkonce.t._ZTI12QPaintDevice+0x0): multiple definition of `typeinfo for QPaintDevice'
.obj/release/qimage_ssse3.o:qimage_ssse3.cpp:(.rdata$_ZTI12QPaintDevice[_ZTI12QPaintDevice]+0x0): first defined here
.obj/release/qimage_compat.o (symbol from plugin):(.gnu.linkonce.t._ZTS6QImage+0x0): multiple definition of `typeinfo name for QImage'
.obj/release/qimage_ssse3.o:qimage_ssse3.cpp:(.rdata$_ZTS6QImage[_ZTS6QImage]+0x0): first defined here

...

.obj/release/qimage.o (symbol from plugin):(.gnu.linkonce.t._ZTI18QRasterPaintEngine+0x0): multiple definition of `typeinfo for QRasterPaintEngine'
.obj/release/qdrawhelper_sse4.o:qdrawhelper_sse4.cpp:(.rdata$_ZTI18QRasterPaintEngine[_ZTI18QRasterPaintEngine]+0x0): first defined here
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: warning: '_hb_ot_shaper_shape_plan_data_create' violates the C++ One Definition Rule  [-Wodr]
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:171:1: note: return value type mismatch
 _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh:37:8: note: type name 'hb_ot_shape_plan_t' should match type name 'hb_ot_shaper_shape_plan_data_t'
 struct hb_ot_shape_plan_t
        ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: note: the incompatible type is defined here
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:171:1: note: '_hb_ot_shaper_shape_plan_data_create' was previously declared here
 _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: warning: '_hb_ot_shaper_shape_plan_data_destroy' violates the C++ One Definition Rule  [-Wodr]
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:200:1: note: type mismatch in parameter 1
 _hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh:37:8: note: type name 'hb_ot_shape_plan_t' should match type name 'hb_ot_shaper_shape_plan_data_t'
 struct hb_ot_shape_plan_t
        ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: note: the incompatible type is defined here
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:200:1: note: '_hb_ot_shaper_shape_plan_data_destroy' was previously declared here
 _hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: warning: '_hb_ot_shaper_face_data_destroy' violates the C++ One Definition Rule  [-Wodr]
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:140:1: note: type mismatch in parameter 1
 _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh:154:8: note: type name 'hb_ot_layout_t' should match type name 'hb_ot_shaper_face_data_t'
 struct hb_ot_layout_t
        ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh:43:1: note: the incompatible type is defined here
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
 ^
C:/Libraries/qt/qt5/qtbase/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc:140:1: note: '_hb_ot_shaper_face_data_destroy' was previously declared here
 _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
 ^
collect2.exe: error: ld returned 1 exit status
mingw32-make[4]: *** [Makefile.Release:1219: ../../lib/Qt5Gui.dll] Error 1

似乎我找到了一种构建 Qt 的方法 link-time 优化:通过将链接器标志行设置为

来修改文件 mkspecs/win32-g++/qmake.conf

QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG -Wl,-allow-multiple-definition

使用 mingw-w64 使 Qt 构建成功。我将为这个 link-time 优化问题注册一个 Qt 错误报告。

Link-time 优化将这里的平均 Qt DLL 大小减少了 9%。我看到的唯一缺点是库 Qt5OpenGL.dllQt5Xml.dll 略微增长了 0.3 % 和 3.0 %。