diff options
Diffstat (limited to 'site_scons/site_tools/target_platform_windows.py')
-rw-r--r-- | site_scons/site_tools/target_platform_windows.py | 114 |
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' |