diff options
author | Gary Oberbrunner <garyo@oberbrunner.com> | 2011-03-02 01:53:21 (GMT) |
---|---|---|
committer | Gary Oberbrunner <garyo@oberbrunner.com> | 2011-03-02 01:53:21 (GMT) |
commit | b25e8d31d6d60f73780309ff9a00cb1b23a58f73 (patch) | |
tree | 3075c0d3885023d45b802e3787d437537ac6f50e /src | |
parent | 8a1ad1c1942246536c33c11adf2eeb4b6ac68638 (diff) | |
download | SCons-b25e8d31d6d60f73780309ff9a00cb1b23a58f73.zip SCons-b25e8d31d6d60f73780309ff9a00cb1b23a58f73.tar.gz SCons-b25e8d31d6d60f73780309ff9a00cb1b23a58f73.tar.bz2 |
Support automatically embedding manifests in EXEs and DLLs on Windows.
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 4 | ||||
-rw-r--r-- | src/RELEASE.txt | 4 | ||||
-rw-r--r-- | src/engine/SCons/Tool/mslink.py | 66 | ||||
-rw-r--r-- | src/engine/SCons/Tool/mslink.xml | 37 |
4 files changed, 104 insertions, 7 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 2aa48b3..8bb1bb7 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -7,6 +7,10 @@ RELEASE 2.1.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE + From Gary Oberbrunner and Sohail Somani: + - new construction variable WINDOWS_EMBED_MANIFEST to automatically + embed manifests in Windows EXEs and DLLs. + From Gary Oberbrunner: - Adding None to an Action no longer fails (just returns original action) diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 306403d..f8db734 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -31,6 +31,9 @@ NEW FUNCTIONALITY + - SCons can now automatically embed manifests in Windows executables + and DLLs, by setting WINDOWS_EMBED_MANIFEST in the environment. + - SCons now searches for site_scons dirs in several system-wide and per-user locations, in addition to the SConstruct top dir. This should enable much easier use of third-party (non-core) @@ -120,6 +123,7 @@ Rob Managan, Gary Oberbrunner, Evgeny Podjachev, + Sohail Somani, Anatoly Techtonik, Allen Weeks, Russel Winder, diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index e0eec8c..07af49e 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -116,8 +116,9 @@ def _dllEmitter(target, source, env, paramtp): "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")) version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) - if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): - # MSVC 8 automatically generates .manifest files that must be installed + if version_num >= 8.0 and \ + (env.get('WINDOWS_INSERT_MANIFEST', 0) or env.get('WINDOWS_EMBED_MANIFEST', 0)): + # MSVC 8 and above automatically generate .manifest files that must be installed extratargets.append( env.ReplaceIxes(dll, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, @@ -164,8 +165,9 @@ def prog_emitter(target, source, env): raise SCons.Errors.UserError("An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")) version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) - if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): - # MSVC 8 automatically generates .manifest files that have to be installed + if version_num >= 8.0 and \ + (env.get('WINDOWS_INSERT_MANIFEST', 0) or env.get('WINDOWS_EMBED_MANIFEST', 0)): + # MSVC 8 and above automatically generate .manifest files that have to be installed extratargets.append( env.ReplaceIxes(exe, "PROGPREFIX", "PROGSUFFIX", @@ -188,12 +190,50 @@ def RegServerFunc(target, source, env): return ret return 0 +# These are the actual actions run to embed the manifest. +# They are only called from the Check versions below. +embedManifestExeAction = SCons.Action.Action('$MTEXECOM') +embedManifestDllAction = SCons.Action.Action('$MTSHLIBCOM') + +def embedManifestDllCheck(target, source, env): + """Function run by embedManifestDllCheckAction to check for existence of manifest + and other conditions, and embed the manifest by calling embedManifestDllAction if so.""" + if env.get('WINDOWS_EMBED_MANIFEST', 0): + manifestSrc = target[0].abspath + '.manifest' + if os.path.exists(manifestSrc): + ret = (embedManifestDllAction) ([target[0]],None,env) + if ret: + raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0]) + return ret + else: + print '(embed: no %s.manifest found; not embedding.)'%str(target[0]) + return 0 + +def embedManifestExeCheck(target, source, env): + """Function run by embedManifestExeCheckAction to check for existence of manifest + and other conditions, and embed the manifest by calling embedManifestExeAction if so.""" + if env.get('WINDOWS_EMBED_MANIFEST', 0): + manifestSrc = target[0].abspath + '.manifest' + if os.path.exists(manifestSrc): + ret = (embedManifestExeAction) ([target[0]],None,env) + if ret: + raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0]) + return ret + else: + print '(embed: no %s.manifest found; not embedding.)'%str(target[0]) + return 0 + +embedManifestDllCheckAction = SCons.Action.Action(embedManifestDllCheck, None) +embedManifestExeCheckAction = SCons.Action.Action(embedManifestExeCheck, None) + regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR") regServerCheck = SCons.Action.Action(RegServerFunc, None) shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}') -compositeShLinkAction = shlibLinkAction + regServerCheck +compositeShLinkAction = shlibLinkAction + regServerCheck + embedManifestDllCheckAction ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}') -compositeLdmodAction = ldmodLinkAction + regServerCheck +compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckAction +exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}') +compositeLinkAction = exeLinkAction + embedManifestExeCheckAction def generate(env): """Add Builders and construction variables for ar to an Environment.""" @@ -209,7 +249,7 @@ def generate(env): env['LINK'] = 'link' env['LINKFLAGS'] = SCons.Util.CLVar('/nologo') env['_PDB'] = pdbGenerator - env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}' + env['LINKCOM'] = compositeLinkAction env.Append(PROGEMITTER = [prog_emitter]) env['LIBDIRPREFIX']='/LIBPATH:' env['LIBDIRSUFFIX']='' @@ -238,6 +278,18 @@ def generate(env): env['REGSVRFLAGS'] = '/s ' env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}' + env['WINDOWS_EMBED_MANIFEST'] = 0 + env['MT'] = 'mt' + #env['MTFLAGS'] = ['-hashupdate'] + env['MTFLAGS'] = SCons.Util.CLVar('/nologo') + # Note: use - here to prevent build failure if no manifest produced. + # This seems much simpler than a fancy system using a function action to see + # if the manifest actually exists before trying to run mt with it. + env['MTEXECOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;1' + env['MTSHLIBCOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;2' + # Future work garyo 27-Feb-11 + env['_MANIFEST_SOURCES'] = None # _windowsManifestSources + # Set-up ms tools paths msvc_setup_env_once(env) diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml index a2105db..35e8b64 100644 --- a/src/engine/SCons/Tool/mslink.xml +++ b/src/engine/SCons/Tool/mslink.xml @@ -94,6 +94,43 @@ see the entry for that variable for specific examples. </summary> </cvar> +<cvar name="WINDOWS_EMBED_MANIFEST"> +<summary> +Set this variable to True or 1 to embed the compiler-generated manifest +(normally <literal>${TARGET}.manifest</literal>) +into all Windows exes and DLLs built with this environment, +as a resource during their link step. +This is done using &cv-link-MT; and &cv-link-MTEXECOM; and &cv-link-MTSHLIBCOM;. +</summary> +</cvar> + +<cvar name="MT"> +<summary> +The program used on Windows systems to embed manifests into DLLs and EXEs. +See also &cv-link-WINDOWS_EMBED_MANIFEST;. +</summary> +</cvar> + +<cvar name="MTFLAGS"> +<summary> +Flags passed to the &cv-link-MT; manifest embedding program (Windows only). +</summary> +</cvar> + +<cvar name="MTEXECOM"> +<summary> +The Windows command line used to embed manifests into executables. +See also &cv-link-MTSHLIBCOM;. +</summary> +</cvar> + +<cvar name="MTSHLIBCOM"> +<summary> +The Windows command line used to embed manifests into shared libraries (DLLs). +See also &cv-link-MTEXECOM;. +</summary> +</cvar> + <cvar name="REGSVR"> <summary> The program used on Windows systems |