summaryrefslogtreecommitdiffstats
path: root/site_scons/site_tools/target_platform_windows.py
diff options
context:
space:
mode:
Diffstat (limited to 'site_scons/site_tools/target_platform_windows.py')
-rw-r--r--site_scons/site_tools/target_platform_windows.py114
1 files changed, 84 insertions, 30 deletions
diff --git a/site_scons/site_tools/target_platform_windows.py b/site_scons/site_tools/target_platform_windows.py
index f225435..a0a70e8 100644
--- a/site_scons/site_tools/target_platform_windows.py
+++ b/site_scons/site_tools/target_platform_windows.py
@@ -78,14 +78,14 @@ def WaitForWritable(target, source, env):
return 1
-def RunManifest(target, source, env, resource_num):
+def RunManifest(target, source, env, cmd):
"""Run the Microsoft Visual Studio manifest tool (mt.exe).
Args:
target: List of target nodes.
source: List of source nodes.
env: Environment context.
- resource_num: Resource number to modify in target (1=exe, 2=dll).
+ cmd: Command to run.
Returns:
Zero if success, nonzero if error.
@@ -101,12 +101,7 @@ def RunManifest(target, source, env, resource_num):
with mt.exe returning an errorlevel (return code) of 31. The workaround is
to retry running mt.exe after a short delay.
"""
-
- cmdline = env.subst(
- 'mt.exe -nologo -manifest "$MANIFEST_FILE" -outputresource:"$TARGET";%d'
- % resource_num,
- target=target, source=source)
- print cmdline
+ cmdline = env.subst(cmd, target=target, source=source)
for retry in range(5):
# If this is a retry, print a message and delay first
@@ -129,17 +124,21 @@ def RunManifest(target, source, env, resource_num):
def RunManifestExe(target, source, env):
"""Calls RunManifest for updating an executable (resource_num=1)."""
- return RunManifest(target, source, env, resource_num=1)
+ return RunManifest(target, source, env, cmd='$MANIFEST_COM')
def RunManifestDll(target, source, env):
"""Calls RunManifest for updating a dll (resource_num=2)."""
- return RunManifest(target, source, env, resource_num=2)
+ return RunManifest(target, source, env, cmd='$SHMANIFEST_COM')
def ComponentPlatformSetup(env, builder_name):
"""Hook to allow platform to modify environment inside a component builder.
+ This is called on a clone of the environment passed into the component
+ builder, and is the last modification done to that environment before using
+ it to call the underlying SCons builder (env.Program(), env.Library(), etc.)
+
Args:
env: Environment to modify
builder_name: Name of the builder
@@ -172,6 +171,34 @@ def ComponentPlatformSetup(env, builder_name):
LINKFLAGS=['/SUBSYSTEM:CONSOLE'],
)
+ # Make sure link methods are lists, so we can append to them below
+ env['LINKCOM'] = [env['LINKCOM']]
+ env['SHLINKCOM'] = [env['SHLINKCOM']]
+
+ # Support manifest file generation and consumption
+ if env.get('MANIFEST_FILE'):
+ env.Append(
+ LINKCOM=[SCons.Script.Action(RunManifestExe, '$MANIFEST_COMSTR')],
+ SHLINKCOM=[SCons.Script.Action(RunManifestDll, '$SHMANIFEST_COMSTR')],
+ )
+
+ # If manifest file should be autogenerated, add the -manifest link line and
+ # delete the generated manfest after running mt.exe.
+ if env.get('MANFEST_FILE_GENERATED_BY_LINK'):
+ env.Append(
+ LINKFLAGS=['-manifest'],
+ LINKCOM=[SCons.Script.Delete('$MANFEST_FILE_GENERATED_BY_LINK')],
+ SHLINKCOM=[SCons.Script.Delete('$MANFEST_FILE_GENERATED_BY_LINK')],
+ )
+
+ # Wait for the output file to be writable before releasing control to
+ # SCons. Windows virus scanners temporarily lock modified executable files
+ # for scanning, which causes SCons's env.Install() to fail intermittently.
+ env.Append(
+ LINKCOM=[SCons.Script.Action(WaitForWritable, None)],
+ SHLINKCOM=[SCons.Script.Action(WaitForWritable, None)],
+ )
+
#------------------------------------------------------------------------------
@@ -222,8 +249,48 @@ def generate(env):
# A better rebuild command (actually cleans, then rebuild)
MSVSREBUILDCOM=''.join(['$MSVSSCONSCOM -c "$MSVSBUILDTARGET" && ',
'$MSVSSCONSCOM "$MSVSBUILDTARGET"']),
+ )
- CCFLAG_INCLUDE='/FI', # Command line option to include a header
+ env.SetDefault(
+ # Command line option to include a header
+ CCFLAG_INCLUDE='/FI',
+
+ # Generate PDBs matching target name by default.
+ PDB='${TARGET.base}.pdb',
+
+ # Code coverage related.
+ COVERAGE_LINKFLAGS='/PROFILE', # Requires vc_80 or higher.
+ COVERAGE_LINKCOM_EXTRAS='$COVERAGE_VSINSTR /COVERAGE $TARGET',
+ # NOTE: need to ignore error in return type here, the tool has issues.
+ # Thus a - is added.
+ COVERAGE_START_CMD=[
+ # If a previous build was cancelled or crashed, VSPerfCmd may still
+ # be running, which causes future coverage runs to fail. Make sure
+ # it's shut down before starting coverage up again.
+ '-$COVERAGE_VSPERFCMD -shutdown',
+ '$COVERAGE_VSPERFCMD -start:coverage '
+ '-output:${COVERAGE_OUTPUT_FILE}.pre'],
+ COVERAGE_STOP_CMD=[
+ '-$COVERAGE_VSPERFCMD -shutdown',
+ '$COVERAGE_ANALYZER -sym_path=. ${COVERAGE_OUTPUT_FILE}.pre.coverage',
+ SCons.Script.Copy('$COVERAGE_OUTPUT_FILE',
+ '${COVERAGE_OUTPUT_FILE}.pre.coverage.lcov'),
+ ],
+ COVERAGE_EXTRA_PATHS=['$COVERAGE_ANALYZER_DIR'],
+
+ # Manifest options
+ # When link.exe is run with '-manifest', it always generated a manifest
+ # with this name.
+ MANFEST_FILE_GENERATED_BY_LINK='${TARGET}.manifest',
+ # Manifest file to use as input to mt.exe. Can be overridden to pass in
+ # a pregenerated manifest file.
+ MANIFEST_FILE='$MANFEST_FILE_GENERATED_BY_LINK',
+ MANIFEST_COM=('mt.exe -nologo -manifest "$MANIFEST_FILE" '
+ '-outputresource:"$TARGET";1'),
+ MANIFEST_COMSTR='$MANIFEST_COM',
+ SHMANIFEST_COM=('mt.exe -nologo -manifest "$MANIFEST_FILE" '
+ '-outputresource:"$TARGET";2'),
+ SHMANIFEST_COMSTR='$SHMANIFEST_COM',
)
env.Append(
@@ -233,7 +300,7 @@ def generate(env):
# Turn up the warning level
CCFLAGS=['/W3'],
- # Force x86 platform for now
+ # Force x86 platform, generate manifests
LINKFLAGS=['/MACHINE:X86'],
ARFLAGS=['/MACHINE:X86'],
@@ -251,27 +318,14 @@ def generate(env):
'/MT', # link with LIBCMT.LIB (multi-threaded, static linked crt)
'/GS', # enable security checks
],
+ LINKFLAGS_OPTIMIZED=['/PDBPATH:none'],
# Settings for component_builders
COMPONENT_LIBRARY_LINK_SUFFIXES=['.lib'],
COMPONENT_LIBRARY_DEBUG_SUFFIXES=['.pdb'],
)
- # Add manifests to EXEs and DLLs
- env['MANIFEST_FILE'] = '${TARGET}.manifest' # To allow override.
- wait_action = SCons.Script.Action(WaitForWritable,
- lambda target, source, env: ''),
- env['LINKCOM'] = [
- env['LINKCOM'],
- SCons.Script.Action(RunManifestExe, lambda target, source, env: ''),
- SCons.Script.Delete('${TARGET}.manifest'),
- wait_action,
- ]
- env['SHLINKCOM'] = [
- env['SHLINKCOM'],
- SCons.Script.Action(RunManifestDll, lambda target, source, env: ''),
- SCons.Script.Delete('${TARGET}.manifest'),
- wait_action,
- ]
- env['WINDOWS_INSERT_MANIFESTS'] = True
- env.Append(LINKFLAGS=['-manifest'])
+ # TODO(sgk): mslink.py creates a shlibLinkAction which doesn't specify
+ # '$SHLINKCOMSTR' as its command string. This breaks --brief. For now,
+ # hack into the existing action and override its command string.
+ env['SHLINKCOM'].list[0].cmdstr = '$SHLINKCOMSTR'