-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathQt.cmake
399 lines (341 loc) · 8.92 KB
/
Qt.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
#
# This is a helper script that I use to ease creation of CMake based project using
# Qt. It especially takes care of patching Qt's exported targets when you're using
# a statically built version of Qt (check Google for "Qt static link windows") to
# see what I mean :)
#
# Basically this script is used like so:
#
# ```
# set (QT_ROOT "path/to/your/Qt/library/folder/lib/cmake")
# set (QT_COMPONENTS Widgets)
# include ("./CMakeUtils/Qt.cmake")
# ```
#
# Here is more detailed explanation of the variables available to configure the script:
#
# QT_ROOT
# Can be either the folder where the CMake exported targets are located,
# or a list of such folders. This is passed to `find_package` as `HINTS`,
# optionally combined with the versions set in QT_VERSIONS.
#
# QT_VERSIONS
# Optional list of version strings. If this is set, the script will iterate
# on all the paths in QT_ROOT, and will combine each one with each version
# string set in QT_VERSIONS. The resulting strings are passed as `HINTS` to
# find_package.
#
# QT_SUFFIX
# When used, it's passed to `find_package` as `PATH_SUFFIXES`. It can be
# either a single string or a list.
#
# QT_MIN_VERSION
# Optional minimum version number. If omitted, defaults to `5`.
#
# QT_COMPONENTS
# The components you want to load.
#
# A more complete example, if you're working on a multiplatform project:
#
# ```
# # The paths on your various platforms or build machines:
# set (QT_ROOT
# "C:/Qt"
# "D:/Qt"
# "/usr/localQt"
# )
#
# # The various versions you support, from the most recent to the oldest
# set (QT_VERSIONS "5.13.2" "5.13.1" "5.13.0")
#
# # The suffixes (those are kinda standard when installing Qt from the online installer)
# set (QT_SUFFIX
# "msvc2017_64/lib/cmake"
# "gcc_64/lib/cmake"
# "clang_64/lib/cmake"
# )
#
# # Minimum version and components to use
# set (QT_MIN_VERSION 5.13)
# set (QT_COMPONENTS Widgets)
#
# # And finally include this script
# include ("./CMakeUtils/Qt.cmake")
# ```
#
#
# If we have some versions, combine them to the roots
#
if (DEFINED QT_VERSIONS)
set (ROOTS ${QT_ROOT})
foreach (ROOT IN ITEMS ${ROOTS})
foreach (VERSION IN ITEMS ${QT_VERSIONS})
list (APPEND QT_ROOT "${ROOT}/${VERSION}")
endforeach ()
endforeach ()
endif ()
#
# Check the version requirement, and handle the Qt major numbers.
#
if (NOT QT_MIN_VERSION)
# default to 5
set (QT_MIN_VERSION 5)
endif ()
set (CMAKE_PREFIX_PATH ${QT_DIR})
string (SUBSTRING "${QT_MIN_VERSION}" 0 1 QT_MAJOR)
set (QT "Qt${QT_MAJOR}")
#
# Find Qt.
#
find_path (QT_DIR ${QT}
HINTS
${QT_ROOT}
PATH_SUFFIXES
${QT_SUFFIX}
)
#
# Log / Error
#
if (NOT QT_DIR)
message (FATAL_ERROR "Couldn't find ${QT}. Root: ${QT_ROOT} Suffixes: ${QT_SUFFIX}")
else ()
message (STATUS "Found Qt in '${QT_DIR}'")
endif ()
#
# Find our Qt components
#
set (CMAKE_PREFIX_PATH ${QT_DIR})
find_package (${QT} ${QT_MIN_VERSION} COMPONENTS ${QT_COMPONENTS} REQUIRED)
#
# Check if Qt is a shared or static library
#
get_target_property (QT_CORE_TARGET_TYPE ${QT}::Core TYPE)
if (QT_CORE_TARGET_TYPE STREQUAL STATIC_LIBRARY)
set (QT_STATIC ON)
message (STATUS "Using a static Qt library, patching exported targets...")
else ()
set (QT_STATIC OFF)
endif ()
#
# When using static build, exported Qt targets miss a awefull lot of dependencies (on Windows
# at least, didn't check the other platforms) so to avoid bothering, patch ${QT}::Widgets
#
# Note that Qt6 doesn't need all this anymore! It seems to directly add the required plugin
# sources to your project, so you no longer need to do anything special CMake side or code side
# to use a static Qt version.
#
if (QT_STATIC AND QT_MAJOR STREQUAL "5")
#
# Set a few paths
#
set (QT_LIB_DIR "${QT_DIR}/..")
set (QT_PLUGIN_DIR "${QT_DIR}/../../plugins")
#
# Qt5::QWindowsIntegrationPlugin
#
if (TARGET Qt5::QWindowsIntegrationPlugin)
# find additional components needed by the windows platform plugin
find_package (Qt5 5
COMPONENTS
EventDispatcherSupport
FontDatabaseSupport
ThemeSupport
WindowsUIAutomationSupport
REQUIRED
)
# configure direct dependencies of the plugin
target_link_libraries(Qt5::QWindowsIntegrationPlugin
INTERFACE
# Qt targets
Qt5::EventDispatcherSupport
Qt5::FontDatabaseSupport
Qt5::ThemeSupport
Qt5::WindowsUIAutomationSupport
# Windows libs
Dwmapi.lib
Imm32.lib
Wtsapi32.lib
)
endif ()
#
# Qt5::QXcbGlxIntegrationPlugin
#
if (TARGET Qt5::QXcbGlxIntegrationPlugin)
# find additional components needed by the linux platform plugin
find_package (Qt5 5
COMPONENTS
GlxSupport
XcbQpa
REQUIRED
)
# configure direct dependencies of the plugin
target_link_libraries(Qt5::QXcbGlxIntegrationPlugin
INTERFACE
# Qt targets
Qt5::XcbQpa
Qt5::GlxSupport
Qt5::QXcbIntegrationPlugin
# System libs
xcb-glx
)
endif ()
#
# Qt5::QWindowsVistaStylePlugin
#
if (TARGET Qt5::QWindowsVistaStylePlugin)
target_link_libraries(Qt5::QWindowsVistaStylePlugin
INTERFACE
# System libs
UxTheme.lib
)
endif ()
#
# Qt5::QGtk3ThemePlugin
#
if (TARGET Qt5::QGtk3ThemePlugin)
target_link_libraries(Qt5::QGtk3ThemePlugin
INTERFACE
# System libs
gtk-3
gdk-3
pango-1.0
gobject-2.0
)
endif ()
#
# Qt5::FontDatabaseSupport
#
if (TARGET Qt5::FontDatabaseSupport)
target_link_libraries(Qt5::FontDatabaseSupport
INTERFACE
# Qt libs
$<$<PLATFORM_ID:Windows>:${QT_LIB_DIR}/qtfreetype.lib>
)
endif ()
#
# Qt5::Gui
#
if (TARGET Qt5::Gui)
target_link_libraries(Qt5::Gui
INTERFACE
# Qt targets
$<$<PLATFORM_ID:Windows>:Qt5::QWindowsIntegrationPlugin>
$<$<PLATFORM_ID:Linux>:Qt5::QXcbGlxIntegrationPlugin>
# Qt libs
$<$<PLATFORM_ID:Windows>:${QT_LIB_DIR}/qtharfbuzz.lib>
$<$<PLATFORM_ID:Windows>:${QT_LIB_DIR}/qtlibpng.lib>
)
endif ()
#
# Qt5::Core
#
if (TARGET Qt5::Core)
target_link_libraries(Qt5::Core
INTERFACE
# Qt libs
$<$<PLATFORM_ID:Windows>:${QT_LIB_DIR}/qtpcre2.lib>
# Windows libs
$<$<PLATFORM_ID:Windows>:Netapi32.lib>
$<$<PLATFORM_ID:Windows>:Ws2_32.lib>
$<$<PLATFORM_ID:Windows>:UserEnv.lib>
$<$<PLATFORM_ID:Windows>:Version.lib>
$<$<PLATFORM_ID:Windows>:Winmm.lib>
)
target_compile_definitions (Qt5::Core
INTERFACE
# Remove debug stuff from Qt
$<$<CONFIG:Release>:QT_NO_DEBUG>
$<$<CONFIG:Release>:QT_NO_DEBUG_OUTPUT>
$<$<CONFIG:Release>:QT_NO_INFO_OUTPUT>
$<$<CONFIG:Release>:QT_NO_WARNING_OUTPUT>
# Since Qt was built in release, we need to match it on Windows
$<$<PLATFORM_ID:Windows>:_ITERATOR_DEBUG_LEVEL=0>
)
endif ()
#
# Jpeg plugin
#
if (TARGET Qt5::QJpegPlugin)
target_link_libraries(Qt5::QJpegPlugin
INTERFACE
$<$<PLATFORM_ID:Linux>:-ljpeg>
)
endif ()
#
# Tiff plugin
#
if (TARGET Qt5::QTiffPlugin)
target_link_libraries(Qt5::QTiffPlugin
INTERFACE
$<$<PLATFORM_ID:Linux>:-ltiff>
)
endif ()
#
# Qt5::Svg
#
if (TARGET Qt5::Svg)
target_link_libraries(Qt5::Svg
INTERFACE
# Qt targets
$<$<PLATFORM_ID:Windows>:Qt5::QSvgIconPlugin>
$<$<PLATFORM_ID:Linux>:Qt5::QSvgPlugin>
)
endif ()
endif ()
#
# Usage: install_qt_target (TARGET QMLDIR <...>)
#
# This does 2 things: First, invoke the usual `install` CMake command.
# Then it will invoke the `windeployqt` helper tool to gather every dll, qml script,
# plugin, etc. that is needed to have a standalone target.
#
# The deploy step will only happen when linking against a dynamic Qt library,
# and on Windows (for the moment)
#
# TARGET : Name of the target to install
# QMLDIR : Root QML folder. This is passed to the deploy helper as --qmldir
# <...> : The rest of the arguments are forwarded to the normal CMake `install` command
#
function (install_qt_target TARGET QMLDIR)
# Install the target at the root of the install prefix
install (TARGETS ${TARGET}
${ARGN}
)
# Windows + shared Qt : deploy
if (WIN32 AND NOT QT_STATIC)
# find the windeployqt utility
find_program (QT_DEPLOY_TOOL
NAMES
windeployqt
HINTS
${QT_DIR}/../../bin
)
# error check
if (NOT QT_DEPLOY_TOOL)
message (WARNING "Couldn't find windeployqt tool in ${QT_DIR} - Deployment will not work.")
return ()
endif ()
# and execute the command
install (CODE "
message (STATUS \"Deploying ${TARGET}\")
execute_process (
COMMAND ${QT_DEPLOY_TOOL} --qmldir \"${QMLDIR}\" \"${CMAKE_INSTALL_PREFIX}/${TARGET}${CMAKE_EXECUTABLE_SUFFIX}\"
--no-compiler-runtime
--no-opengl-sw
--no-webkit2
--no-system-d3d-compiler
--no-translations
--no-qmltooling
WORKING_DIRECTORY ${QT_DIR}/bin
RESULT_VARIABLE QT_DEPLOY_RESULT
ERROR_VARIABLE QT_DEPLOY_OUTPUT
OUTPUT_VARIABLE QT_DEPLOY_OUTPUT
)
if (NOT \${QT_DEPLOY_RESULT} EQUAL 0)
message (WARNING \"Deployment failed with code \${QT_DEPLOY_RESULT}\${QT_DEPLOY_OUTPUT}\")
else ()
message (STATUS \"Deployment done\")
endif ()
")
endif ()
endfunction ()