-
Notifications
You must be signed in to change notification settings - Fork 163
/
SConstruct
713 lines (593 loc) · 24.7 KB
/
SConstruct
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
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
import distutils.sysconfig
import os
import re
import sys
def setup_config_variables():
""" Set up defaults values and load the configuration settings """
# Take a sensible default for pythonpath
must_be_specified = 'Must be specified ***'
boostpath = must_be_specified
if 'BOOSTPATH' in os.environ:
boostpath = os.environ['BOOSTPATH']
lootpath = must_be_specified
if 'LOOTPATH' in os.environ:
lootpath = os.environ['LOOTPATH']
pythonpath = must_be_specified
if 'PYTHONPATH' in os.environ:
pythonpath = os.environ['PYTHONPATH']
else:
pythonpath = distutils.sysconfig.EXEC_PREFIX
# Take qtdir from the os environment if set
qtdir = must_be_specified
if 'QTDIR' in os.environ:
qtdir = os.environ['QTDIR']
elif 'QT4DIR' in os.environ:
qtdir = os.environ['QT4DIR']
sevenzippath = must_be_specified
if 'SEVENZIPPATH' in os.environ:
sevenzippath = os.environ['SEVENZIPPATH']
zlibpath = must_be_specified
if 'ZLIBPATH' in os.environ:
zlibpath = os.environ['ZLIBPATH']
git = 'git'
if 'GIT' in os.environ:
git = os.environ['GIT']
mercurial = 'hg'
if 'MERCURIAL' in os.environ:
hg = os.environ['HG']
vars = Variables('scons_configure.py')
vars.AddVariables(
PathVariable('BOOSTPATH', 'Set to point to your boost directory',
boostpath, PathVariable.PathIsDir),
PathVariable('LOOTPATH', 'Set to point to your LOOT API directory',
lootpath, PathVariable.PathIsDir),
('MSVC_VERSION', 'Version of msvc, defaults to latest installed'),
PathVariable('PYTHONPATH', 'Path to python install', pythonpath,
PathVariable.PathIsDir),
PathVariable('QTDIR', 'Path to the version of QT to use', qtdir,
PathVariable.PathIsDir),
PathVariable('SEVENZIPPATH', 'Path to 7zip sources', sevenzippath,
PathVariable.PathIsDir),
PathVariable('ZLIBPATH', 'Path to zlib install', zlibpath,
PathVariable.PathIsDir),
PathVariable('GIT', 'Path to git executable', git,
PathVariable.PathIsFile),
PathVariable('MERCURIAL', 'Path to hg executable', mercurial,
PathVariable.PathIsFile),
PathVariable('IWYU', 'Path to include-what-you-use executable', None,
PathVariable.PathIsFile)
)
return vars
def add_moc_files(self, files):
"""
The QT4 tool only sets up moc for .cpp files. If there's a header file
with no corresponding source we have to do it ourselves. This makes it
easier.
Note: I could just supress the scanning and moc all the HEADER files...
"""
targets = []
for file in self.Flatten([files]):
contents = file.get_contents()
target = str(file)[:-1] + 'cpp'
if not os.path.exists(target):
if 'Q_OBJECT' in file.get_contents():
header = file.name
target = self['QT5_XMOCHPREFIX'] + header[:-2] + \
self['QT5_XMOCHSUFFIX']
targets.append(self.ExplicitMoc5(target, header))
return targets
def link_emitter_wrapper(target, source, env):
# This could be better written!
if '/DEBUG' in env['LINKFLAGS']:
name = str(target[0])[:-3] + 'pdb'
target.append(name)
return (target, source)
def shlib_emitter_wrapper(target, source, env):
if 'WINDOWS_EMBED_MANIFEST' in env:
env.AppendUnique(LINKFLAGS = '/MANIFEST')
return link_emitter_wrapper(target, source, env)
def fixup_qt4():
import SCons.Tool
oldpath = sys.path
sys.path = SCons.Tool.DefaultToolpath + sys.path
import qt4
def my_qrc_path(head, prefix, tail, suffix):
return "%s%s%s" % (prefix, tail, suffix)
qt4.__qrc_path = my_qrc_path
sys.path = oldpath
metadata = re.compile(r'Q_PLUGIN_METADATA\(IID *".*" *FILE *"(.*)"\)')
def json_emitter(target, source, env):
depends = []
for s in source:
match = metadata.search(s.get_contents())
if match:
depends += [ match.group(1) ]
env.Depends(target, depends)
return target, source
def fixup_qt5():
import SCons.Tool
oldpath = sys.path
sys.path = SCons.Tool.DefaultToolpath + sys.path
import qt5
def my_qrc_path(head, prefix, tail, suffix):
return "%s%s%s" % (prefix, tail, suffix)
qt5.__qrc_path = my_qrc_path
sys.path = oldpath
qt_env['BUILDERS']['Moc5'].builder.emitter = json_emitter
moduleDefines = {
'3Support' : [ 'QT_QT3SUPPORT_LIB', 'QT3_SUPPORT' ],
'Core' : [ 'QT_CORE_LIB' ],
'Declarative' : [ 'QT_DECLARATIVE_LIB' ],
'Gui' : [ 'QT_GUI_LIB' ],
'Network' : [ 'QT_NETWORK_LIB' ],
'OpenGL' : [ 'QT_OPENGL_LIB' ],
'Script' : [ 'QT_SCRIPT_LIB' ],
'Sql' : [ 'QT_SQL_LIB' ],
'Svg' : [ 'QT_SVG_LIB' ],
'WebKit' : [ 'QT_WEBKIT_LIB' ],
'Xml' : [ 'QT_XML_LIB' ],
'XmlPatterns' : [ 'QT_XMLPATTERNS_LIB' ],
# qt5
'Qml' : [ 'QT_QML_LIB' ],
'QuickWidgets' : [ 'QT_QUICKWIDGETS_LIB', 'QT_WIDGETS_LIB', 'QT_QUICK_LIB' ],
'Widgets' : [ 'QT_WIDGETS_LIB' ],
'WebKitWidgets' : [ 'QT_WEBKITWIDGETS_LIB' ],
'WinExtras' : [ 'QT_WINEXTRAS_LIB' ]
}
staticModules = [
'UiTools',
]
def get_qt_lib_info(env):
" Deal with the various QT naming conventions. sigh "
# For QT4, the libraries are QTlibname{,d}4
# For QT5, they are QT5libname{,d}
prefix = 'QT'
suffix = 'd' if env['CONFIG'] == 'debug' else ''
_suffix = suffix # Because they can't be consistent within a version,
# let alone between
version = env['QT_MAJOR_VERSION']
if version <= 4:
suffix += str(version)
else:
prefix += str(version)
return prefix, suffix, _suffix
def EnableQtModules(self, *modules):
""" Enable the specified QT modules, mainly by adding defines
and libraries
"""
self.AppendUnique(QT_USED_MODULES = modules)
for module in modules:
try:
self.AppendUnique(CPPDEFINES = moduleDefines[module])
if self['CONFIG'] == 'debug':
if module == 'Declarative':
self.AppendUnique(CPPDEFINES = 'QT_DECLARATIVE_DEBUG')
elif module == 'Qml':
self.AppendUnique(CPPDEFINES = 'QT_QML_DEBUG')
except:
print 'module', module, 'has no -D'
pass
if "Assistant" in modules:
self.AppendUnique(CPPPATH = [
os.path.join('$QTDIR', 'include', 'QtAssistant')
])
modules.remove('Assistant')
modules.append('AssistantClient')
prefix, suffix, _suffix = get_qt_lib_info(self)
self.AppendUnique(LIBS = [
prefix + lib + suffix for lib in modules if lib not in staticModules
])
self.PrependUnique(LIBS = [
lib + _suffix for lib in modules if lib in staticModules
])
if 'OpenGL' in modules:
self.AppendUnique(LIBS = [ 'opengl32' ])
self.AppendUnique(CPPPATH = [
os.path.join('$QTDIR', 'include', 'QT' + module) for module in modules
])
def DisableQtModules(self, *modules):
""" Disable the specified QT modules similar to enabling them """
for module in modules:
try:
self['QT_USED_MODULES'].remove(module)
self['CPPDEFINES'].remove(moduleDefines[module])
if self['CONFIG'] == 'debug' and module == 'Declarative':
self['CPPDEFINES'].remove('QT_DECLARATIVE_DEBUG')
except:
pass
if "Assistant" in modules:
self['CPPPATH'].remove(os.path.join('$QTDIR', 'include', 'QtAssistant'))
modules.remove('Assistant')
modules.append('AssistantClient')
prefix, suffix, _suffix = get_qt_lib_info(self)
for lib in modules:
self['LIBS'].remove(prefix + lib + suffix)
if 'OpenGL' in modules:
self['LIBS'].remove('opengl32')
for module in modules:
self['CPPPATH'].remove(os.path.join('$QTDIR', 'include', 'QT' + module))
def setup_IWYU(env):
import SCons.Defaults
import SCons.Builder
original_shared = SCons.Defaults.SharedObjectEmitter
original_static = SCons.Defaults.StaticObjectEmitter
def DoIWYU(env, source, target):
for i in range(len(source)):
s = source[i]
dir, name = os.path.split(str(s)) # I'm sure theres a way of getting this from scons
# Don't bother looking at moc files and 7zip source
if not name.startswith('moc_') and \
not dir.startswith(env['SEVENZIPPATH']):
# Put the .iwyu in the same place as the .obj
targ = os.path.splitext(str(target[i]))[0]
env.Depends(env.IWYU(targ + '.iwyu', s), target[i])
def shared_emitter(target, source, env):
DoIWYU(env, source, target)
return original_shared(target, source, env)
def static_emitter(target, source, env):
DoIWYU(env, source, target)
return original_static(target, source, env)
SCons.Defaults.SharedObjectEmitter = shared_emitter
SCons.Defaults.StaticObjectEmitter = static_emitter
def emitter(target, source, env):
env.Depends(target, env['IWYU_MAPPING_FILE'])
env.Depends(target, env['IWYU_MASSAGE'])
return target, source
def _concat_list(prefixes, list, suffixes, env, f=lambda x: x, target=None, source=None):
""" Creates a new list from 'list' by first interpolating each element
in the list using the 'env' dictionary and then calling f on the
list, and concatenate the 'prefix' and 'suffix' LISTS onto each element of the list.
A trailing space on the last element of 'prefix' or leading space on the
first element of 'suffix' will cause them to be put into separate list
elements rather than being concatenated.
"""
if not list:
return list
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
if l is not None:
list = l
# This bit replaces current concat_ixes
result = []
def process_stringlist(s):
return [ str(env.subst(p, SCons.Subst.SUBST_RAW))
for p in Flatten([s]) if p != '' ]
# ensure that prefix and suffix are strings
prefixes = process_stringlist(prefixes)
prefix = ''
if len(prefixes) != 0:
if prefixes[-1][-1] != ' ':
prefix = prefixes.pop()
suffixes = process_stringlist(suffixes)
suffix = ''
if len(suffixes) != 0:
if suffixes[-1][0] != ' ':
suffix = suffixes.pop(0)
for x in list:
if isinstance(x, SCons.Node.FS.File):
result.append(x)
continue
x = str(x)
if x:
result.append(prefixes)
if prefix:
if x[:len(prefix)] != prefix:
x = prefix + x
result.append(x)
if suffix:
if x[-len(suffix):] != suffix:
result[-1] = result[-1] + suffix
result.append(suffixes)
return result
env['_concat_list'] = _concat_list
# Note to self: command 2>&1 | other command appears to work as I would hope
# except it eats errors
iwyu = SCons.Builder.Builder(
action=[
'$IWYU_MASSAGE $TARGET $IWYU $IWYU_FLAGS $IWYU_MAPPINGS $IWYU_COMCOM $SOURCE'
],
emitter=emitter,
suffix='.iwyu',
src_suffix='.cpp')
env.Append(BUILDERS={'IWYU': iwyu})
# Sigh - IWYU is a right bum as it doesn't recognise /I so I have to
# duplicate most of the usual stuff
env['IWYU_FLAGS'] = [
# This might turn down the output a bit. I hope
'-Xiwyu', '--transitive_includes_only',
# Seem to be needed for a windows build
'-D_MT', '-D_DLL', '-m32',
# This is something to do with clang, windows and boost headers
'-DBOOST_USE_WINDOWS_H',
# There's a lot of this, disabled for now
'-Wno-inconsistent-missing-override',
# Mark boost and Qt headers as system headers to disable a lot of noise.
# I'm sure there has to be a better way than saying 'prefix=Q'
'--system-header-prefix=Q',
'--system-header-prefix=boost/',
# Should be able to get this info from our setup really
'-fmsc-version=1800', '-D_MSC_VER=1800',
# clang and qt don't agree about these because clang says its gcc 4.2
# and QT doesn't realise it's clang
'-DQ_COMPILER_INITIALIZER_LISTS',
'-DQ_COMPILER_DECLTYPE',
'-DQ_COMPILER_VARIADIC_TEMPLATES',
]
if env['CONFIG'] == 'debug':
env['IWYU_FLAGS'] += [ '-D_DEBUG' ]
env['IWYU_DEFPREFIX'] = '-D'
env['IWYU_DEFSUFFIX'] = ''
env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}'
env['IWYU_INCPREFIX'] = '-I'
env['IWYU_INCSUFFIX'] = ''
env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
env['IWYU_PCH_PREFIX'] = '-include' # Amazingly this works without a space
env['IWYU_PCH_SUFFIX'] = ''
env['IWYU_PCHFILES'] = '$( ${_concat(IWYU_PCH_PREFIX, PCHSTOP, IWYU_PCH_SUFFIX, __env__, target=TARGET, source=SOURCE)} $)'
env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $IWYU_PCHFILES $CCPDBFLAGS'
env['IWYU_MAPPING_PREFIX'] = ['-Xiwyu', '--mapping_file=']
env['IWYU_MAPPING_SUFFIX'] = ''
env['IWYU_MAPPINGS'] = '$( ${_concat_list(IWYU_MAPPING_PREFIX, IWYU_MAPPING_FILE, IWYU_MAPPING_SUFFIX, __env__, f=lambda l: [ str(x) for x in l], target=TARGET, source=SOURCE)} $)'
env['IWYU_MAPPING_FILE'] = [
env.File('#/modorganizer/qt5_4.imp'),
env.File('#/modorganizer/win.imp'),
env.File('#/modorganizer/mappings.imp')
]
env['IWYU_MASSAGE'] = env.File('#/modorganizer/massage_messages.py')
# Create base environment
vars = setup_config_variables()
env = Environment(variables = vars, TARGET_ARCH = 'x86')
# I'd really like to validate for unexpected settings in 'variables', but scons
# appears to throw them away
#ok = True
#for key, value in vars.UnknownVariables():
# print "unknown variable in scons_configure.py: %s=%s" % (key, value)
# ok = False
#if not ok:
# sys.exit(1)
# Patch scons to realise it's generating PDB files if /DEBUG is set
env.AppendUnique(PROGEMITTER = [ link_emitter_wrapper ])
# Ditto + windows_embed_manifest doesn't generate a manifest file
env.AppendUnique(SHLIBEMITTER = [ shlib_emitter_wrapper ])
# Work out where to find boost libraries
libdir = os.path.join(env['BOOSTPATH'], 'lib32-msvc-' + env['MSVC_VERSION'])
if not os.path.exists(libdir):
libdir = os.path.join(env['BOOSTPATH'], 'stage', 'lib')
env.AppendUnique(LIBPATH = libdir)
# Process command line to find out what/where we're building
config = ARGUMENTS.get('CONFIG', 'debug')
env['CONFIG'] = config
# I think this is a bug in scons. It returns 12.0 for studio 13
# This needs to match the QT specified version or bad things will happen!
msvs_version = int(env['MSVS_VERSION'].split('.')[0]) + 2000
if msvs_version > 2010:
msvs_version += 1
# Read the QT version info
with open(os.path.join(env['QTDIR'], 'mkspecs', 'qconfig.pri')) as qtinfo:
for line in qtinfo:
info = re.split(r'\s*=\s*', line.rstrip())
if info[0] == 'QT_VERSION':
env[info[0]] = info[1]
elif '_VERSION' in info[0]:
env[info[0]] = int(info[1])
build_dir = 'scons-ModOrganizer-QT_%s_%sfor_MSVS%d_32bit-%s' % (
env['QT_VERSION'].replace('.', '_'),
'OpenGL_' if 'opengl' in env['QTDIR'] else '',
msvs_version,
config.title())
# Put the sconsign file somewhere sane
env.SConsignFile(os.path.join(build_dir, '.sconsign.dblite'))
env.CacheDir(os.path.join(build_dir, '.cache'))
#this doesn't seem to work
#env.VariantDir('build/$CONFIG', 'source')
#env.VariantDir('build/$CONFIG', 'source', duplicate = 0)
# Ripped off from qmake.conf
# Compiler defines. Note that scons uses the same variables for C and C++
# defines and include paths so be careful if you mix languages.
# A note: QT puts _MSC_VER into the compile line, but I can see no earthly
# reason for this.
env.AppendUnique(CPPDEFINES = [
'UNICODE',
'WIN32',
'NOMINMAX' # Nukes boost all over the place
])
# Default warning level.
env['WARNING_LEVEL'] = 3
# C compiler flags
env.AppendUnique(CPPFLAGS = [
'/Zm200',
#'/Zc:wchar_t-', # 4 v 5
'/Zc:wchar_t',
'/W$WARNING_LEVEL'
])
# C++ compiler flags
env.AppendUnique(CXXFLAGS = [
'/w34100',
'/w34189',
'/EHsc', # STL on
'/GR' # RTTI on
])
"""
# qmake.conf
#QMAKE_CFLAGS_RELEASE = -O2 -MD
#QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
#QMAKE_CFLAGS_LTCG = -GL
#QMAKE_CFLAGS_MP = -MP
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF
QMAKE_LFLAGS_LTCG = /LTCG
# project
"""
env['WINDOWS_EMBED_MANIFEST'] = True
# Seriously, the linker doesn't apply these by default?
env.AppendUnique(LINKFLAGS = [
'/DYNAMICBASE',
'/NXCOMPAT'
])
# Display full path in messages. Sadly even this isn't good enough for Creator
# env.AppendUnique(CPPFLAGS = [ '/FC' ])
if env['CONFIG'] == 'debug':
env.AppendUnique(CPPFLAGS = [ '/MDd', '/Z7' ])
env.AppendUnique(LINKFLAGS = [ '/DEBUG' ]) #, '/OPT:REF'])
else:
env.AppendUnique(CPPFLAGS = [ '/O2', '/MD' ])
env.AppendUnique(LINKFLAGS = [ '/OPT:REF', '/OPT:ICF' ])
# Set up include what you use. Add this as an extra compile step. Note it
# doesn't currently generate an output file (use the output instead!).
if 'IWYU' in env:
setup_IWYU(env)
# /OPT:REF removes unreferenced code
# for release, use /OPT:ICF (comdat folding: coalesce identical blocks of code)
# We have to make the install path absolute. *sigh*. But it appears to have to
# be in build_dir...
env['INSTALL_PATH'] = os.path.join(os.getcwd(), build_dir, '_ModOrganizer')
# Create the environment for QT
qt_env = env.Clone()
# If you don't do this for the release build, QT gets very upset...
if qt_env['CONFIG'] != 'debug':
qt_env.AppendUnique(CPPDEFINES = [ 'QT_NO_DEBUG' ])
qt_env.Tool('qt%d' % qt_env['QT_MAJOR_VERSION'])
# FIXME See if I can work out how to get official scons qt to work. Appears
# to only work with QT5
fixup_qt5()
qt_env.AddMethod(add_moc_files, 'AddExtraMoc')
# A very strange rune which QT sets
qt_env['EXE_MANIFEST_DEPENDENCY'] =\
'/MANIFESTDEPENDENCY:"' + ' '.join(("type='win32'",
"name='Microsoft.Windows.Common-Controls'",
"version='6.0.0.0'",
"publicKeyToken='6595b64144ccf1df'",
"language='*'",
"processorArchitecture='*'")) + '"'
# Not sure how necessary this is. Moreover it says msvc but seems to expect
# the msvs number
qt_env.AppendUnique(CPPPATH = [
os.path.join(env['QTDIR'], 'mkspecs', 'win32-msvc%d' % msvs_version)
])
qt_env.AddMethod(EnableQtModules)
qt_env.AddMethod(DisableQtModules)
# This is a hack. we should redirect uic to uic4/uic5 and fix the scripts
def Uicc5(self, *args, **kwargs):
return self.Uic5(*args, **kwargs)
qt_env.AddMethod(Uicc5, 'Uic')
# Enable the base libraries.
qt_env.EnableQt5Modules([], debug = qt_env['CONFIG'] == 'debug')
# Causes too many problems if you don't do this
qt_env['QT%d_MOCCPPPATH' % qt_env['QT_MAJOR_VERSION']] = '$CPPPATH'
# Yechhh. Note: the the _VER depends on ms compiler version (and could
# be dragged from the qmake conf file or preferrably from ms compiler)
qt_env['QT%d_MOCDEFINES' % qt_env['QT_MAJOR_VERSION']] =\
'${_defines(QT5_MOCDEFPREFIX, MOCDEFINES+CPPDEFINES, QT5_MOCDEFSUFFIX, __env__)}'
qt_env['MOCDEFINES'] = [
'_MSC_VER=1800',
]
# QTCreator appears to add these automatically. Some of these look moderately
# dangerous if you're attempting to cross-compile
# only for qt4?
if qt_env['QT_MAJOR_VERSION'] <= 4:
qt_env.AppendUnique(CPPDEFINES = [
'QT_DLL',
'QT_HAVE_MMX',
'QT_HAVE_3DNOW',
'QT_HAVE_SSE',
'QT_HAVE_MMXEXT',
'QT_HAVE_SSE2',
'QT_THREAD_SUPPORT'
])
# It also adds this to the end of the include path.
# -I"c:\Apps\Qt\4.8.6\include\ActiveQt"
# Export environment. Rename it first to encourage instant Clone() calls
Export('env qt_env')
# And away we go
libs_to_install = env.SConscript('source/SConscript',
variant_dir = build_dir,
duplicate = 0)
libs_to_install = sorted(set(filter(lambda x: x is not None,
env.Flatten(libs_to_install))))
# There are some odd implicit dependencies
if qt_env['QT_MAJOR_VERSION'] > 4:
libs_to_install += [
'Multimedia',
'MultimediaWidgets',
'OpenGL',
'Positioning',
'PrintSupport',
'Quick',
'Sensors',
'WebChannel',
]
# Finally, set up rules to install the DLLs.
# use windeployqt.exe to install all required libraries
#SET(windeploy_parameters --no-translations --no-plugins --libdir dlls --release-with-debug-info --no-compiler-runtime)
#INSTALL(
# CODE
# "EXECUTE_PROCESS(
# COMMAND
# ${qt5bin}/windeployqt.exe ModOrganizer.exe ${windeploy_parameters}
# COMMAND
# ${qt5bin}/windeployqt.exe uibase.dll ${windeploy_parameters}
# WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin
# )"
#)
# this should probably be a rule though it seems to produce an awful lot of
# Stuff(TM). or a postaction
dll_path = os.path.join('$INSTALL_PATH', 'DLLs')
prefix, suffix, suffix_ = get_qt_lib_info(qt_env)
dlls_to_install = []
dlls_to_install = [
os.path.join(env['QTDIR'], 'bin', prefix + lib + suffix + '.dll')
for lib in libs_to_install
]
if env['CONFIG'] == 'debug':
dlls_to_install += [
os.path.join(env['QTDIR'], 'bin', prefix + lib + suffix + '.pdb')
for lib in libs_to_install
]
# There is something wrong with webkit4 and/or this build as it seems
# to need to live in the same directory as mod organiser.
if 'WebKit' in libs_to_install and qt_env['QT_MAJOR_VERSION'] == 4:
libname = prefix + 'WebKit' + suffix
env.Install(env['INSTALL_PATH'],
os.path.join(env['QTDIR'], 'bin', libname + '.dll'))
if env['CONFIG'] == 'debug':
env.Install(env['INSTALL_PATH'],
os.path.join(env['QTDIR'], 'bin', libname + '.pdb'))
if qt_env['QT_MAJOR_VERSION'] > 4:
# Guesswork a bit.
dlls_to_install += [
os.path.join(env['QTDIR'],
'bin',
'icu%s%d%d.dll' % (lib,
qt_env['QT_MAJOR_VERSION'],
qt_env['QT_MINOR_VERSION'] - 1))
for lib in ('dt','in', 'uc')
]
platform_dlls = []
if env['CONFIG'] == 'debug':
platform_dlls += [ 'qwindowsd.dll', 'qwindowsd.pdb' ]
else:
platform_dlls += [ 'qwindows.dll' ]
# Note: Appears to work fine in DLLs or at the top level, but I'm all for
# keeping the top directory a bit clean
env.Install(os.path.join(dll_path, 'platforms'),
[ os.path.join(env['QTDIR'], 'plugins', 'platforms', dll)
for dll in platform_dlls ])
image_dlls = []
for image in ('dds', 'gif', 'jpeg', 'tga'):
if env['CONFIG'] == 'debug':
image_dlls += [ 'q' + image + 'd.dll', 'q' + image + 'd.pdb' ]
else:
image_dlls += [ 'q' + image + '.dll' ]
env.Install(os.path.join(dll_path, 'imageformats'),
[ os.path.join(env['QTDIR'], 'plugins', 'imageformats', dll)
for dll in image_dlls ])
# Build your own?
dlls_to_install += [
os.path.join('tools', 'static_data', 'dlls', '7z.dll')
]
env.Install(dll_path, dlls_to_install)
# And loot which goes somewhere else (maybe this should be done in loot_cli?)
env.Install(os.path.join('${INSTALL_PATH}', 'loot'),
os.path.join('${LOOTPATH}', 'loot32.dll'))
# also pythondll and zip, boost python dll (all for python proxy!)
# the dll we can drag from the python install
# the zip i'm not sure about.