2005-04-16 18:48:50 +00:00
|
|
|
Import('defenv')
|
2017-10-06 19:30:20 +00:00
|
|
|
print("Using Microsoft tools configuration (%s)" % defenv.get('MSVS_VERSION','<Default>'))
|
2005-04-16 18:48:50 +00:00
|
|
|
|
|
|
|
### flags
|
|
|
|
|
2010-04-17 22:58:47 +00:00
|
|
|
import SCons
|
|
|
|
if SCons.__version__ == '1.3.0':
|
2011-11-15 23:12:24 +00:00
|
|
|
# workaround for http://scons.tigris.org/issues/show_bug.cgi?id=2614
|
|
|
|
# force inclusion of Platform SDK, sometimes ignored by SCons 1.3.0 due to environment contamination
|
2010-04-17 22:58:47 +00:00
|
|
|
defenv.Tool('mssdk')
|
|
|
|
|
2012-10-13 01:47:50 +00:00
|
|
|
def entry(x,u):
|
|
|
|
if x == 'WinMain' and u:
|
|
|
|
x = 'w' + x
|
|
|
|
return '/entry:' + x
|
|
|
|
|
|
|
|
defenv['ENTRY_FLAG'] = entry
|
2005-05-21 13:13:36 +00:00
|
|
|
defenv['MAP_FLAG'] = '/map'
|
2005-04-16 18:48:50 +00:00
|
|
|
defenv['NODEFLIBS_FLAG'] = '/NODEFAULTLIB'
|
|
|
|
defenv['C_FLAG'] = '/TC'
|
|
|
|
defenv['CPP_FLAG'] = '/TP'
|
2005-05-21 13:03:51 +00:00
|
|
|
defenv['CPP_REQUIRES_STDLIB'] = 0
|
2006-01-27 17:53:00 +00:00
|
|
|
defenv['SUBSYS_CON'] = '/subsystem:console'
|
2012-10-13 01:47:50 +00:00
|
|
|
defenv['SUBSYS_WIN'] = '/subsystem:windows'
|
2007-03-02 11:17:08 +00:00
|
|
|
defenv['MSVCRT_FLAG'] = '/MD'
|
2015-11-03 23:28:08 +00:00
|
|
|
defenv['MSVCRT_NEEDSMANIFEST'] = False
|
2008-12-09 22:42:12 +00:00
|
|
|
defenv['STDCALL'] = '__stdcall'
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2010-11-13 21:13:49 +00:00
|
|
|
msvs_version = float(defenv['MSVS_VERSION'].replace('Exp',''))
|
|
|
|
if msvs_version >= 8.0:
|
2006-11-13 14:10:11 +00:00
|
|
|
defenv['EXCEPTION_FLAG'] = '/EHsc'
|
2008-11-15 21:54:24 +00:00
|
|
|
defenv.Append(CCFLAGS = ['/GS-'])
|
2010-03-24 17:22:56 +00:00
|
|
|
defenv.Append(CPPDEFINES = ['_CRT_SECURE_NO_WARNINGS', '_CRT_NONSTDC_NO_WARNINGS', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NON_CONFORMING_SWPRINTFS'])
|
2013-12-08 14:34:38 +00:00
|
|
|
defenv['MSVCRT_FLAG'] = '/MT' # Avoid msvcr?0.dll dependency
|
2006-11-13 14:10:11 +00:00
|
|
|
else:
|
|
|
|
defenv['EXCEPTION_FLAG'] = '/GX'
|
2010-11-13 21:13:49 +00:00
|
|
|
if msvs_version < 10.0:
|
|
|
|
# not even /ALIGN:512 works for vc10... fails to load process
|
|
|
|
defenv.Append(LINKFLAGS = ['/opt:nowin98'])
|
2014-01-21 14:21:26 +00:00
|
|
|
if defenv['MSTOOLKIT'] and msvs_version < 8.0:
|
2013-12-08 14:34:38 +00:00
|
|
|
defenv['MSVCRT_FLAG'] = '/ML' # TK2003 does not have all libs
|
2014-10-30 03:13:08 +00:00
|
|
|
if msvs_version >= 11.0:
|
2014-10-05 20:55:20 +00:00
|
|
|
defenv['SUBSYS_CON'] = '/subsystem:console,5.01' # support windows xp
|
|
|
|
defenv['SUBSYS_WIN'] = '/subsystem:windows,5.01' # support windows xp
|
2006-11-13 14:10:11 +00:00
|
|
|
|
2008-12-09 22:42:12 +00:00
|
|
|
### defines
|
|
|
|
|
2008-12-14 23:56:10 +00:00
|
|
|
defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
|
2008-12-09 22:42:12 +00:00
|
|
|
|
|
|
|
### asm
|
|
|
|
|
2014-03-03 18:10:53 +00:00
|
|
|
if 'x86' in defenv.get('TARGET_ARCH','x86'):
|
|
|
|
defenv.Append(ASFLAGS = ['/coff']) # ML64 does not support /coff
|
2008-11-20 21:04:23 +00:00
|
|
|
|
2005-04-21 17:40:58 +00:00
|
|
|
### debug
|
|
|
|
|
|
|
|
if defenv['DEBUG']:
|
2008-11-15 21:54:24 +00:00
|
|
|
defenv.Append(CCFLAGS = ['/Zi'])
|
|
|
|
defenv.Append(CCFLAGS = ['/Fd${TARGET.dir}\\${TARGET.dir.file}.pdb'])
|
|
|
|
defenv.Append(LINKFLAGS = ['/debug'])
|
2013-12-08 14:34:38 +00:00
|
|
|
defenv['MSVCRT_FLAG'] = defenv['MSVCRT_FLAG'] + 'd'
|
2018-06-03 23:53:51 +00:00
|
|
|
elif msvs_version >= 14.0 or defenv['TARGET_ARCH'] == 'arm64':
|
|
|
|
defenv.Append(LINKFLAGS = ['/nocoffgrpinfo'])
|
2005-04-21 17:40:58 +00:00
|
|
|
|
2005-10-13 13:16:38 +00:00
|
|
|
### workarounds
|
|
|
|
|
2006-10-29 14:52:22 +00:00
|
|
|
# Some Platform SDK version includes a bad version of libcp.lib.
|
2005-10-13 13:16:38 +00:00
|
|
|
# if stl usage causes link failure, copy the good libcp.lib
|
|
|
|
# from one of the other lib folders and use it instead.
|
|
|
|
|
2006-11-17 11:38:15 +00:00
|
|
|
confenv = defenv.Clone()
|
|
|
|
conf = confenv.Configure()
|
|
|
|
|
2010-03-24 17:22:56 +00:00
|
|
|
# For VS 2005 and up, the single threaded version of C runtime
|
|
|
|
# need not be explicitly linked.
|
|
|
|
if float(defenv['MSVS_VERSION'].replace('Exp','')) < 8.0:
|
|
|
|
libcptest = """
|
|
|
|
#include <fstream>
|
|
|
|
int main() {
|
|
|
|
// %s
|
|
|
|
std::ofstream header("test", std::ofstream::out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2012-10-15 02:34:25 +00:00
|
|
|
conf.env.Prepend(LIBPATH = Dir('#/.sconf_temp').abspath)
|
2010-03-24 17:22:56 +00:00
|
|
|
conf.env.Append(CCFLAGS = ['$EXCEPTION_FLAG'])
|
|
|
|
|
|
|
|
if not conf.TryLink(libcptest % 'no change', '.cpp'):
|
|
|
|
import os, shutil
|
|
|
|
|
2012-10-15 02:34:25 +00:00
|
|
|
libdirs = (defenv['ENV']['LIB']).split(os.pathsep) + defenv['LIBPATH']
|
2010-03-24 17:22:56 +00:00
|
|
|
|
|
|
|
for libdir in libdirs:
|
2012-10-15 02:34:25 +00:00
|
|
|
libdir = confenv.subst(libdir)
|
2010-03-24 17:22:56 +00:00
|
|
|
try:
|
|
|
|
libcp = r'%s\libcp.lib' % libdir
|
|
|
|
shutil.copy(libcp, Dir('#/.sconf_temp').abspath)
|
|
|
|
if conf.TryLink(libcptest % (r'using %s' % libcp), '.cpp'):
|
|
|
|
defenv.PrependENVPath('LIB', Dir('#/.sconf_temp').abspath)
|
|
|
|
break
|
|
|
|
except IOError:
|
|
|
|
continue
|
|
|
|
else:
|
2017-10-06 19:30:20 +00:00
|
|
|
print("*** Couldn't find a good version of libcp.lib")
|
2010-03-24 17:22:56 +00:00
|
|
|
Exit(2)
|
2006-11-17 11:38:15 +00:00
|
|
|
|
|
|
|
conf.Finish()
|
2005-10-13 13:16:38 +00:00
|
|
|
|
2015-11-03 23:28:08 +00:00
|
|
|
# Linking to msvcr?0.dll (/MD) might require a manifest
|
|
|
|
|
|
|
|
confenv = defenv.Clone()
|
|
|
|
conf = confenv.Configure()
|
|
|
|
if msvs_version >= 7.0:
|
|
|
|
conf.env.Append(CCFLAGS = [defenv['MSVCRT_FLAG']])
|
|
|
|
code = """
|
|
|
|
#include <stdlib.h>
|
|
|
|
int main() { return atoi("0"); }
|
|
|
|
"""
|
|
|
|
result = True # TryLink should not fail but default to True just in case so distribution will fail as well
|
|
|
|
if conf.TryLink(code, '.cpp'):
|
|
|
|
import os
|
|
|
|
result = os.path.exists('%s.manifest' % conf.lastTarget)
|
|
|
|
defenv['MSVCRT_NEEDSMANIFEST'] = result
|
|
|
|
conf.Finish()
|
|
|
|
|
|
|
|
|
2012-11-11 04:33:52 +00:00
|
|
|
### unicode
|
|
|
|
tdefenv = defenv.Clone()
|
|
|
|
if tdefenv['UNICODE']:
|
|
|
|
tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
2010-03-24 17:22:56 +00:00
|
|
|
|
2005-04-16 18:48:50 +00:00
|
|
|
### stub environment
|
|
|
|
|
2006-11-11 13:04:35 +00:00
|
|
|
stub_env = defenv.Clone()
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2009-02-04 14:05:48 +00:00
|
|
|
stub_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
|
2005-04-21 17:40:58 +00:00
|
|
|
if not defenv['DEBUG']:
|
2013-12-08 14:34:38 +00:00
|
|
|
stub_env.Append(CCFLAGS = ['/O1']) # optimize for size
|
2008-11-15 21:54:24 +00:00
|
|
|
stub_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
2010-11-13 21:13:49 +00:00
|
|
|
stub_env.Append(CCFLAGS = ['/FAcs']) # full listing files
|
|
|
|
stub_env.Append(CCFLAGS = ['/Fa${TARGET}.lst']) # listing file name
|
2010-03-24 17:22:56 +00:00
|
|
|
|
2008-11-15 21:54:24 +00:00
|
|
|
stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
|
|
|
|
stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2014-12-04 07:15:01 +00:00
|
|
|
if msvs_version >= 10.0:
|
2018-06-03 21:00:53 +00:00
|
|
|
if stub_env['TARGET_ARCH'] != 'arm64': # LNK1246: '/FIXED' not compatible with 'ARM64' target machine
|
|
|
|
stub_env.Append(LINKFLAGS = ['/FIXED']) # no relocations that our resource editor ignores
|
2014-12-04 07:15:01 +00:00
|
|
|
|
2010-06-14 10:07:22 +00:00
|
|
|
stub_uenv = stub_env.Clone()
|
|
|
|
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
|
|
|
|
2005-04-16 18:48:50 +00:00
|
|
|
### makensis environment
|
|
|
|
|
2010-06-14 10:07:22 +00:00
|
|
|
makensis_env = tdefenv.Clone()
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2009-02-04 14:05:48 +00:00
|
|
|
makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
|
2005-04-21 17:40:58 +00:00
|
|
|
if not defenv['DEBUG']:
|
2008-11-15 21:54:24 +00:00
|
|
|
makensis_env.Append(CCFLAGS = ['/O2']) # optimize for speed
|
|
|
|
makensis_env.Append(CCFLAGS = ['$EXCEPTION_FLAG']) # enable exceptions
|
|
|
|
makensis_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
2010-03-24 17:22:56 +00:00
|
|
|
makensis_env.Append(CCFLAGS = ['/FAcs']) # full listing files
|
|
|
|
makensis_env.Append(CCFLAGS = ['/Fa${TARGET}.lst']) # listing file name
|
2013-12-08 14:34:38 +00:00
|
|
|
makensis_env.Append(CCFLAGS = [defenv['MSVCRT_FLAG']])
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2008-11-15 21:54:24 +00:00
|
|
|
makensis_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
2014-10-05 21:04:19 +00:00
|
|
|
makensis_env.Append(LINKFLAGS = ['$SUBSYS_CON']) # console executable
|
2010-04-14 10:15:40 +00:00
|
|
|
if defenv['UNICODE']:
|
2010-04-15 12:11:06 +00:00
|
|
|
makensis_env.Append(LINKFLAGS = ['/STACK:2097152']) # need 2 MB of stack in Unicode (default is 1 MB)
|
2005-04-16 18:48:50 +00:00
|
|
|
|
|
|
|
### plugin environment
|
|
|
|
|
2006-11-11 13:04:35 +00:00
|
|
|
plugin_env = defenv.Clone(no_import_lib = 1)
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2014-02-08 00:13:52 +00:00
|
|
|
if defenv['TARGET_ARCH'] == 'amd64':
|
|
|
|
plugin_env.Append(LINKFLAGS = ['/MACHINE:AMD64']) # Contrib\System\Resource will not link without this
|
|
|
|
|
2005-04-21 17:40:58 +00:00
|
|
|
if not defenv['DEBUG']:
|
2008-11-15 21:54:24 +00:00
|
|
|
plugin_env.Append(CCFLAGS = ['/O1']) # optimize for size
|
|
|
|
plugin_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2008-11-15 21:54:24 +00:00
|
|
|
plugin_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2010-06-14 10:07:22 +00:00
|
|
|
plugin_uenv = plugin_env.Clone()
|
|
|
|
plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
|
|
|
|
2005-04-16 18:48:50 +00:00
|
|
|
### util environment
|
|
|
|
|
2010-06-14 10:07:22 +00:00
|
|
|
util_env = tdefenv.Clone()
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2005-04-21 17:40:58 +00:00
|
|
|
if not defenv['DEBUG']:
|
2008-11-15 21:54:24 +00:00
|
|
|
util_env.Append(CCFLAGS = ['/O1']) # optimize for speed
|
|
|
|
util_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
2013-12-08 14:34:38 +00:00
|
|
|
util_env.Append(CCFLAGS = [defenv['MSVCRT_FLAG']])
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2008-11-15 21:54:24 +00:00
|
|
|
util_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2005-09-17 09:43:10 +00:00
|
|
|
### cross-platform util environment
|
|
|
|
|
2006-11-11 13:04:35 +00:00
|
|
|
cp_util_env = util_env.Clone()
|
2005-09-17 09:43:10 +00:00
|
|
|
|
2009-02-04 14:05:48 +00:00
|
|
|
cp_util_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
|
2006-02-01 06:01:11 +00:00
|
|
|
### test environment
|
|
|
|
|
2006-11-11 13:04:35 +00:00
|
|
|
test_env = defenv.Clone()
|
2006-02-01 06:01:11 +00:00
|
|
|
|
2009-02-04 14:05:48 +00:00
|
|
|
test_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
|
2006-03-17 12:01:17 +00:00
|
|
|
### weird compiler requirements
|
|
|
|
|
2006-10-29 11:50:31 +00:00
|
|
|
def check_requirement(ctx, func, trigger):
|
|
|
|
ctx.Message('Checking for %s requirement... ' % func)
|
|
|
|
|
|
|
|
flags = ctx.env['LINKFLAGS']
|
|
|
|
|
2008-11-15 21:54:24 +00:00
|
|
|
ctx.env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG'])
|
|
|
|
ctx.env.Append(LINKFLAGS = ['/entry:main'])
|
2006-10-29 11:50:31 +00:00
|
|
|
|
|
|
|
test = """
|
2006-10-30 20:50:30 +00:00
|
|
|
int main() {
|
2006-10-29 11:50:31 +00:00
|
|
|
%s
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
""" % trigger
|
|
|
|
|
|
|
|
result = not ctx.TryLink(test, '.c')
|
|
|
|
ctx.Result(result)
|
|
|
|
|
|
|
|
ctx.env['LINKFLAGS'] = flags
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
2014-02-08 00:13:52 +00:00
|
|
|
def add_file_to_emitter(env, emitter_name, file, obj_name=None):
|
|
|
|
if obj_name is None:
|
|
|
|
obj_name = emitter_name
|
2006-10-29 11:50:31 +00:00
|
|
|
try:
|
|
|
|
original_emitter = env[emitter_name]
|
|
|
|
if type(original_emitter) == list:
|
|
|
|
original_emitter = original_emitter[0]
|
|
|
|
except KeyError:
|
|
|
|
original_emitter = None
|
|
|
|
|
|
|
|
def emitter(target, source, env):
|
|
|
|
if original_emitter:
|
|
|
|
target, source = original_emitter(target, source, env)
|
|
|
|
|
|
|
|
if '$NODEFLIBS_FLAG' not in env['LINKFLAGS']:
|
|
|
|
return target, source
|
|
|
|
|
2014-02-08 00:13:52 +00:00
|
|
|
return target, source + env.Object(obj_name, file)
|
2006-10-29 11:50:31 +00:00
|
|
|
|
|
|
|
env[emitter_name] = emitter
|
|
|
|
|
2014-02-08 00:13:52 +00:00
|
|
|
def add_file(file, obj_name=None):
|
2006-10-29 11:50:31 +00:00
|
|
|
file = File(file)
|
2014-02-08 00:13:52 +00:00
|
|
|
add_file_to_emitter(stub_env, 'PROGEMITTER', file, obj_name)
|
|
|
|
add_file_to_emitter(stub_uenv, 'PROGEMITTER', file, obj_name)
|
|
|
|
add_file_to_emitter(util_env, 'PROGEMITTER', file, obj_name)
|
|
|
|
add_file_to_emitter(plugin_env, 'SHLIBEMITTER', file, obj_name)
|
|
|
|
add_file_to_emitter(plugin_uenv, 'SHLIBEMITTER', file, obj_name)
|
2006-10-29 11:50:31 +00:00
|
|
|
|
2006-03-17 12:01:17 +00:00
|
|
|
#
|
|
|
|
# MSVC 6 SP6 doesn't like direct shifting of 64-bit integers.
|
|
|
|
# It generates a call to ___aullshr which requires libc, which
|
|
|
|
# we don't like. However, it does agree to work properly with
|
|
|
|
# a call to Int64ShrlMod32.
|
|
|
|
#
|
|
|
|
|
2006-10-30 20:50:30 +00:00
|
|
|
conf = stub_env.Configure()
|
2014-06-23 19:15:59 +00:00
|
|
|
conf.env.Append(LINKFLAGS = ['/entry:WinMain'])
|
2006-03-17 12:01:17 +00:00
|
|
|
|
2012-10-13 01:47:50 +00:00
|
|
|
int64test = """
|
|
|
|
#include <windows.h>
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow) {
|
|
|
|
ULARGE_INTEGER *i = 0;
|
|
|
|
return (int)(i->QuadPart >> 10);
|
|
|
|
}
|
|
|
|
"""
|
2006-03-17 12:01:17 +00:00
|
|
|
|
|
|
|
if not conf.TryLink(int64test, '.c'):
|
|
|
|
stub_env.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
|
2010-06-14 10:07:22 +00:00
|
|
|
stub_uenv.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
|
2006-10-30 20:50:30 +00:00
|
|
|
|
2012-10-13 01:47:50 +00:00
|
|
|
conf.Finish()
|
2006-10-30 20:50:30 +00:00
|
|
|
|
2006-10-29 11:50:31 +00:00
|
|
|
#
|
|
|
|
# MSVC 2005 requires the memset CRT function to be present
|
2014-02-08 00:13:52 +00:00
|
|
|
# and the stubs might need memcpy (entry struct copy on x64)
|
|
|
|
# BUGBUG: The tests are currently broken on x64 and designed to fail!
|
2006-10-29 11:50:31 +00:00
|
|
|
#
|
2006-03-17 12:01:17 +00:00
|
|
|
|
2006-10-30 20:50:30 +00:00
|
|
|
conf = defenv.Configure(custom_tests = { 'CheckRequirement' : check_requirement })
|
2014-02-08 00:13:52 +00:00
|
|
|
if conf.CheckRequirement('memset', 'char c[128] = "test";switch(sizeof(void*)){case 8:break;case sizeof(void*):return 1;}'):
|
|
|
|
add_file('memset.c', 'memset')
|
2006-10-30 20:50:30 +00:00
|
|
|
|
2014-02-08 00:13:52 +00:00
|
|
|
memcpy_test = """
|
|
|
|
switch(sizeof(void*)){case 8:break;case sizeof(void*):return 1;}
|
|
|
|
"""
|
|
|
|
if conf.CheckRequirement('memcpy', memcpy_test):
|
|
|
|
add_file('memcpy.c', 'memcpy')
|
|
|
|
stub_env.Append(CPPDEFINES = ['_NSIS_NODEFLIB_CRTMEMCPY'])
|
|
|
|
stub_uenv.Append(CPPDEFINES = ['_NSIS_NODEFLIB_CRTMEMCPY'])
|
2006-10-29 11:50:31 +00:00
|
|
|
|
2012-10-13 01:47:50 +00:00
|
|
|
conf.Finish()
|
2006-03-17 12:01:17 +00:00
|
|
|
|
|
|
|
### return
|
2005-04-16 18:48:50 +00:00
|
|
|
|
2010-06-14 10:07:22 +00:00
|
|
|
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv plugin_uenv')
|