
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7002 212acab6-be3b-0410-9dea-997c60f758d6
312 lines
9.5 KiB
Text
312 lines
9.5 KiB
Text
Import('defenv')
|
|
print("Using Microsoft tools configuration (%s)" % defenv.get('MSVS_VERSION','<Default>'))
|
|
|
|
### flags
|
|
|
|
import SCons
|
|
if SCons.__version__ == '1.3.0':
|
|
# 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
|
|
defenv.Tool('mssdk')
|
|
|
|
def entry(x,u):
|
|
if x == 'WinMain' and u:
|
|
x = 'w' + x
|
|
return '/entry:' + x
|
|
|
|
defenv['ENTRY_FLAG'] = entry
|
|
defenv['MAP_FLAG'] = '/map'
|
|
defenv['NODEFLIBS_FLAG'] = '/NODEFAULTLIB'
|
|
defenv['C_FLAG'] = '/TC'
|
|
defenv['CPP_FLAG'] = '/TP'
|
|
defenv['CPP_REQUIRES_STDLIB'] = 0
|
|
defenv['SUBSYS_CON'] = '/subsystem:console'
|
|
defenv['SUBSYS_WIN'] = '/subsystem:windows'
|
|
defenv['MSVCRT_FLAG'] = '/MD'
|
|
defenv['MSVCRT_NEEDSMANIFEST'] = False
|
|
defenv['STDCALL'] = '__stdcall'
|
|
|
|
msvs_version = float(defenv['MSVS_VERSION'].replace('Exp',''))
|
|
if msvs_version >= 8.0:
|
|
defenv['EXCEPTION_FLAG'] = '/EHsc'
|
|
defenv.Append(CCFLAGS = ['/GS-'])
|
|
defenv.Append(CPPDEFINES = ['_CRT_SECURE_NO_WARNINGS', '_CRT_NONSTDC_NO_WARNINGS', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NON_CONFORMING_SWPRINTFS'])
|
|
defenv['MSVCRT_FLAG'] = '/MT' # Avoid msvcr?0.dll dependency
|
|
else:
|
|
defenv['EXCEPTION_FLAG'] = '/GX'
|
|
if msvs_version < 10.0:
|
|
# not even /ALIGN:512 works for vc10... fails to load process
|
|
defenv.Append(LINKFLAGS = ['/opt:nowin98'])
|
|
if defenv['MSTOOLKIT'] and msvs_version < 8.0:
|
|
defenv['MSVCRT_FLAG'] = '/ML' # TK2003 does not have all libs
|
|
if msvs_version >= 11.0:
|
|
defenv['SUBSYS_CON'] = '/subsystem:console,5.01' # support windows xp
|
|
defenv['SUBSYS_WIN'] = '/subsystem:windows,5.01' # support windows xp
|
|
|
|
### defines
|
|
|
|
defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
|
|
|
|
### asm
|
|
|
|
if 'x86' in defenv.get('TARGET_ARCH','x86'):
|
|
defenv.Append(ASFLAGS = ['/coff']) # ML64 does not support /coff
|
|
|
|
### debug
|
|
|
|
if defenv['DEBUG']:
|
|
defenv.Append(CCFLAGS = ['/Zi'])
|
|
defenv.Append(CCFLAGS = ['/Fd${TARGET.dir}\\${TARGET.dir.file}.pdb'])
|
|
defenv.Append(LINKFLAGS = ['/debug'])
|
|
defenv['MSVCRT_FLAG'] = defenv['MSVCRT_FLAG'] + 'd'
|
|
elif msvs_version >= 14.0 or defenv['TARGET_ARCH'] == 'arm64':
|
|
defenv.Append(LINKFLAGS = ['/nocoffgrpinfo'])
|
|
|
|
### workarounds
|
|
|
|
# Some Platform SDK version includes a bad version of libcp.lib.
|
|
# if stl usage causes link failure, copy the good libcp.lib
|
|
# from one of the other lib folders and use it instead.
|
|
|
|
confenv = defenv.Clone()
|
|
conf = confenv.Configure()
|
|
|
|
# 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;
|
|
}
|
|
"""
|
|
|
|
conf.env.Prepend(LIBPATH = Dir('#/.sconf_temp').abspath)
|
|
conf.env.Append(CCFLAGS = ['$EXCEPTION_FLAG'])
|
|
|
|
if not conf.TryLink(libcptest % 'no change', '.cpp'):
|
|
import os, shutil
|
|
|
|
libdirs = (defenv['ENV']['LIB']).split(os.pathsep) + defenv['LIBPATH']
|
|
|
|
for libdir in libdirs:
|
|
libdir = confenv.subst(libdir)
|
|
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:
|
|
print("*** Couldn't find a good version of libcp.lib")
|
|
Exit(2)
|
|
|
|
conf.Finish()
|
|
|
|
# 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()
|
|
|
|
|
|
### unicode
|
|
tdefenv = defenv.Clone()
|
|
if tdefenv['UNICODE']:
|
|
tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
|
|
|
### stub environment
|
|
|
|
stub_env = defenv.Clone()
|
|
|
|
stub_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
if not defenv['DEBUG']:
|
|
stub_env.Append(CCFLAGS = ['/O1']) # optimize for size
|
|
stub_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
|
stub_env.Append(CCFLAGS = ['/FAcs']) # full listing files
|
|
stub_env.Append(CCFLAGS = ['/Fa${TARGET}.lst']) # listing file name
|
|
|
|
stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
|
|
stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
|
|
|
if msvs_version >= 10.0:
|
|
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
|
|
|
|
stub_uenv = stub_env.Clone()
|
|
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
|
|
|
### makensis environment
|
|
|
|
makensis_env = tdefenv.Clone()
|
|
|
|
makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
if not defenv['DEBUG']:
|
|
makensis_env.Append(CCFLAGS = ['/O2']) # optimize for speed
|
|
makensis_env.Append(CCFLAGS = ['$EXCEPTION_FLAG']) # enable exceptions
|
|
makensis_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
|
makensis_env.Append(CCFLAGS = ['/FAcs']) # full listing files
|
|
makensis_env.Append(CCFLAGS = ['/Fa${TARGET}.lst']) # listing file name
|
|
makensis_env.Append(CCFLAGS = [defenv['MSVCRT_FLAG']])
|
|
|
|
makensis_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
|
makensis_env.Append(LINKFLAGS = ['$SUBSYS_CON']) # console executable
|
|
if defenv['UNICODE']:
|
|
makensis_env.Append(LINKFLAGS = ['/STACK:2097152']) # need 2 MB of stack in Unicode (default is 1 MB)
|
|
|
|
### plugin environment
|
|
|
|
plugin_env = defenv.Clone(no_import_lib = 1)
|
|
|
|
if defenv['TARGET_ARCH'] == 'amd64':
|
|
plugin_env.Append(LINKFLAGS = ['/MACHINE:AMD64']) # Contrib\System\Resource will not link without this
|
|
|
|
if not defenv['DEBUG']:
|
|
plugin_env.Append(CCFLAGS = ['/O1']) # optimize for size
|
|
plugin_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
|
|
|
plugin_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
|
|
|
plugin_uenv = plugin_env.Clone()
|
|
plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
|
|
|
### util environment
|
|
|
|
util_env = tdefenv.Clone()
|
|
|
|
if not defenv['DEBUG']:
|
|
util_env.Append(CCFLAGS = ['/O1']) # optimize for speed
|
|
util_env.Append(CCFLAGS = ['/W3']) # level 3 warnings
|
|
util_env.Append(CCFLAGS = [defenv['MSVCRT_FLAG']])
|
|
|
|
util_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
|
|
|
### cross-platform util environment
|
|
|
|
cp_util_env = util_env.Clone()
|
|
|
|
cp_util_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
### test environment
|
|
|
|
test_env = defenv.Clone()
|
|
|
|
test_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
|
|
|
|
### weird compiler requirements
|
|
|
|
def check_requirement(ctx, func, trigger):
|
|
ctx.Message('Checking for %s requirement... ' % func)
|
|
|
|
flags = ctx.env['LINKFLAGS']
|
|
|
|
ctx.env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG'])
|
|
ctx.env.Append(LINKFLAGS = ['/entry:main'])
|
|
|
|
test = """
|
|
int main() {
|
|
%s
|
|
return 0;
|
|
}
|
|
""" % trigger
|
|
|
|
result = not ctx.TryLink(test, '.c')
|
|
ctx.Result(result)
|
|
|
|
ctx.env['LINKFLAGS'] = flags
|
|
|
|
return result
|
|
|
|
def add_file_to_emitter(env, emitter_name, file, obj_name=None):
|
|
if obj_name is None:
|
|
obj_name = emitter_name
|
|
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
|
|
|
|
return target, source + env.Object(obj_name, file)
|
|
|
|
env[emitter_name] = emitter
|
|
|
|
def add_file(file, obj_name=None):
|
|
file = File(file)
|
|
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)
|
|
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
conf = stub_env.Configure()
|
|
conf.env.Append(LINKFLAGS = ['/entry:WinMain'])
|
|
|
|
int64test = """
|
|
#include <windows.h>
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow) {
|
|
ULARGE_INTEGER *i = 0;
|
|
return (int)(i->QuadPart >> 10);
|
|
}
|
|
"""
|
|
|
|
if not conf.TryLink(int64test, '.c'):
|
|
stub_env.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
|
|
stub_uenv.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
|
|
|
|
conf.Finish()
|
|
|
|
#
|
|
# MSVC 2005 requires the memset CRT function to be present
|
|
# and the stubs might need memcpy (entry struct copy on x64)
|
|
# BUGBUG: The tests are currently broken on x64 and designed to fail!
|
|
#
|
|
|
|
conf = defenv.Configure(custom_tests = { 'CheckRequirement' : check_requirement })
|
|
if conf.CheckRequirement('memset', 'char c[128] = "test";switch(sizeof(void*)){case 8:break;case sizeof(void*):return 1;}'):
|
|
add_file('memset.c', 'memset')
|
|
|
|
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'])
|
|
|
|
conf.Finish()
|
|
|
|
### return
|
|
|
|
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv plugin_uenv')
|