NSIS/SCons/Config/ms
kichik 55cb9be2be more
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6922 212acab6-be3b-0410-9dea-997c60f758d6
2017-10-06 19:30:20 +00:00

310 lines
9.3 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'
### 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:
# no relocations that our resource editor ignores
stub_env.Append(LINKFLAGS = ['/FIXED'])
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')