mirror of https://gitlab.com/ita1024/waf.git
Simplify manifest file processing
This commit is contained in:
parent
f18d481e75
commit
98f495bda1
|
@ -53,3 +53,5 @@ NEW IN WAF 1.9
|
||||||
that case all mappings/precedences must be present. These features were not used in Waf 1.8.
|
that case all mappings/precedences must be present. These features were not used in Waf 1.8.
|
||||||
- Do not truncate the _task suffix from Task class names
|
- Do not truncate the _task suffix from Task class names
|
||||||
- Task.exec_command will use @argfile when command-line limits are exceeded
|
- Task.exec_command will use @argfile when command-line limits are exceeded
|
||||||
|
- Task.exec_command will add tsk.env.PATH to the child process environment
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ as C/C++/D/Assembly/Go (this support module is almost never used alone).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os, re
|
import os, re
|
||||||
from waflib import Task, Utils, Node, Errors
|
from waflib import Task, Utils, Node, Errors, Logs
|
||||||
from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension
|
from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension
|
||||||
from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests
|
from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests
|
||||||
from waflib.Configure import conf
|
from waflib.Configure import conf
|
||||||
|
@ -172,6 +172,48 @@ class link_task(Task.Task):
|
||||||
target = base.find_or_declare(tmp)
|
target = base.find_or_declare(tmp)
|
||||||
self.set_outputs(target)
|
self.set_outputs(target)
|
||||||
|
|
||||||
|
def exec_command(self, *k, **kw):
|
||||||
|
ret = super(link_task, self).exec_command(*k, **kw)
|
||||||
|
if not ret and self.env.DO_MANIFEST:
|
||||||
|
ret = self.exec_mf()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def exec_mf(self):
|
||||||
|
"""
|
||||||
|
Create manifest files for VS-like compilers (msvc, ifort, ...)
|
||||||
|
"""
|
||||||
|
if not self.env.MT:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
manifest = None
|
||||||
|
for out_node in self.outputs:
|
||||||
|
if out_node.name.endswith('.manifest'):
|
||||||
|
manifest = out_node.abspath()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Should never get here. If we do, it means the manifest file was
|
||||||
|
# never added to the outputs list, thus we don't have a manifest file
|
||||||
|
# to embed, so we just return.
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# embedding mode. Different for EXE's and DLL's.
|
||||||
|
# see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx
|
||||||
|
mode = ''
|
||||||
|
for x in Utils.to_list(self.generator.features):
|
||||||
|
if x in ('cprogram', 'cxxprogram', 'fcprogram', 'fcprogram_test'):
|
||||||
|
mode = 1
|
||||||
|
elif x in ('cshlib', 'cxxshlib', 'fcshlib'):
|
||||||
|
mode = 2
|
||||||
|
|
||||||
|
Logs.debug('msvc: embedding manifest in mode %r', mode)
|
||||||
|
|
||||||
|
lst = [] + self.env.MT
|
||||||
|
lst.extend(Utils.to_list(self.env.MTFLAGS))
|
||||||
|
lst.extend(['-manifest', manifest])
|
||||||
|
lst.append('-outputresource:%s;%s' % (self.outputs[0].abspath(), mode))
|
||||||
|
|
||||||
|
return super(link_task, self).exec_command(lst)
|
||||||
|
|
||||||
class stlink_task(link_task):
|
class stlink_task(link_task):
|
||||||
"""
|
"""
|
||||||
Base for static link tasks, which use *ar* most of the time.
|
Base for static link tasks, which use *ar* most of the time.
|
||||||
|
|
|
@ -395,8 +395,6 @@ def apply_flags_ifort(self):
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
# split the manifest file processing from the link task, like for the rc processing
|
|
||||||
|
|
||||||
@feature('fcprogram', 'fcshlib', 'fcprogram_test')
|
@feature('fcprogram', 'fcshlib', 'fcprogram_test')
|
||||||
@after_method('apply_link')
|
@after_method('apply_link')
|
||||||
def apply_manifest_ifort(self):
|
def apply_manifest_ifort(self):
|
||||||
|
@ -408,75 +406,5 @@ def apply_manifest_ifort(self):
|
||||||
out_node = self.link_task.outputs[0]
|
out_node = self.link_task.outputs[0]
|
||||||
man_node = out_node.parent.find_or_declare(out_node.name + '.manifest')
|
man_node = out_node.parent.find_or_declare(out_node.name + '.manifest')
|
||||||
self.link_task.outputs.append(man_node)
|
self.link_task.outputs.append(man_node)
|
||||||
self.link_task.do_manifest = True
|
self.env.DO_MANIFEST = True
|
||||||
|
|
||||||
def exec_mf(self):
|
|
||||||
"""
|
|
||||||
Create the manifest file
|
|
||||||
"""
|
|
||||||
env = self.env
|
|
||||||
mtool = env['MT']
|
|
||||||
if not mtool:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
self.do_manifest = False
|
|
||||||
|
|
||||||
outfile = self.outputs[0].abspath()
|
|
||||||
|
|
||||||
manifest = None
|
|
||||||
for out_node in self.outputs:
|
|
||||||
if out_node.name.endswith('.manifest'):
|
|
||||||
manifest = out_node.abspath()
|
|
||||||
break
|
|
||||||
if manifest is None:
|
|
||||||
# Should never get here. If we do, it means the manifest file was
|
|
||||||
# never added to the outputs list, thus we don't have a manifest file
|
|
||||||
# to embed, so we just return.
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# embedding mode. Different for EXE's and DLL's.
|
|
||||||
# see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx
|
|
||||||
mode = ''
|
|
||||||
if 'fcprogram' in self.generator.features or 'fcprogram_test' in self.generator.features:
|
|
||||||
mode = '1'
|
|
||||||
elif 'fcshlib' in self.generator.features:
|
|
||||||
mode = '2'
|
|
||||||
|
|
||||||
Logs.debug('ifort: embedding manifest in mode %r', mode)
|
|
||||||
|
|
||||||
lst = [] + mtool
|
|
||||||
lst.extend(Utils.to_list(env['MTFLAGS']))
|
|
||||||
lst.extend(['-manifest', manifest])
|
|
||||||
lst.append('-outputresource:%s;%s' % (outfile, mode))
|
|
||||||
|
|
||||||
return super(self.__class__, self).exec_command(lst)
|
|
||||||
|
|
||||||
def wrap_class(class_name):
|
|
||||||
"""
|
|
||||||
Manifest file processing and @response file workaround for command-line length limits on Windows systems
|
|
||||||
The indicated task class is replaced by a subclass to prevent conflicts in case the class is wrapped more than once
|
|
||||||
"""
|
|
||||||
cls = Task.classes.get(class_name)
|
|
||||||
|
|
||||||
if not cls:
|
|
||||||
return None
|
|
||||||
|
|
||||||
derived_class = type(class_name, (cls,), {})
|
|
||||||
|
|
||||||
def exec_command(self, *k, **kw):
|
|
||||||
ret = super(self.__class__, self).exec_command(*k, **kw)
|
|
||||||
if not ret and self.env.IFORT_WIN32 and getattr(self, 'do_manifest', None):
|
|
||||||
ret = self.exec_mf()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
derived_class.exec_command = exec_command
|
|
||||||
derived_class.exec_mf = exec_mf
|
|
||||||
|
|
||||||
if hasattr(cls, 'hcode'):
|
|
||||||
derived_class.hcode = cls.hcode
|
|
||||||
|
|
||||||
return derived_class
|
|
||||||
|
|
||||||
for k in 'fcprogram fcprogram_test fcshlib fcstlib'.split():
|
|
||||||
wrap_class(k)
|
|
||||||
|
|
||||||
|
|
|
@ -923,8 +923,6 @@ def apply_flags_msvc(self):
|
||||||
install_to=self.install_task.install_to, install_from=pdbnode)
|
install_to=self.install_task.install_to, install_from=pdbnode)
|
||||||
break
|
break
|
||||||
|
|
||||||
# split the manifest file processing from the link task, like for the rc processing
|
|
||||||
|
|
||||||
@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib')
|
@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib')
|
||||||
@after_method('apply_link')
|
@after_method('apply_link')
|
||||||
def apply_manifest(self):
|
def apply_manifest(self):
|
||||||
|
@ -934,82 +932,11 @@ def apply_manifest(self):
|
||||||
the manifest file, the binaries are unusable.
|
the manifest file, the binaries are unusable.
|
||||||
See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx
|
See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None):
|
if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None):
|
||||||
out_node = self.link_task.outputs[0]
|
out_node = self.link_task.outputs[0]
|
||||||
man_node = out_node.parent.find_or_declare(out_node.name + '.manifest')
|
man_node = out_node.parent.find_or_declare(out_node.name + '.manifest')
|
||||||
self.link_task.outputs.append(man_node)
|
self.link_task.outputs.append(man_node)
|
||||||
self.link_task.do_manifest = True
|
self.env.DO_MANIFEST = True
|
||||||
|
|
||||||
def exec_mf(self):
|
|
||||||
"""
|
|
||||||
Create the manifest file
|
|
||||||
"""
|
|
||||||
env = self.env
|
|
||||||
mtool = env['MT']
|
|
||||||
if not mtool:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
self.do_manifest = False
|
|
||||||
|
|
||||||
outfile = self.outputs[0].abspath()
|
|
||||||
|
|
||||||
manifest = None
|
|
||||||
for out_node in self.outputs:
|
|
||||||
if out_node.name.endswith('.manifest'):
|
|
||||||
manifest = out_node.abspath()
|
|
||||||
break
|
|
||||||
if manifest is None:
|
|
||||||
# Should never get here. If we do, it means the manifest file was
|
|
||||||
# never added to the outputs list, thus we don't have a manifest file
|
|
||||||
# to embed, so we just return.
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# embedding mode. Different for EXE's and DLL's.
|
|
||||||
# see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx
|
|
||||||
mode = ''
|
|
||||||
if 'cprogram' in self.generator.features or 'cxxprogram' in self.generator.features:
|
|
||||||
mode = '1'
|
|
||||||
elif 'cshlib' in self.generator.features or 'cxxshlib' in self.generator.features:
|
|
||||||
mode = '2'
|
|
||||||
|
|
||||||
Logs.debug('msvc: embedding manifest in mode %r', mode)
|
|
||||||
|
|
||||||
lst = [] + mtool
|
|
||||||
lst.extend(Utils.to_list(env['MTFLAGS']))
|
|
||||||
lst.extend(['-manifest', manifest])
|
|
||||||
lst.append('-outputresource:%s;%s' % (outfile, mode))
|
|
||||||
|
|
||||||
return super(self.__class__, self).exec_command(lst)
|
|
||||||
|
|
||||||
def wrap_class(class_name):
|
|
||||||
"""
|
|
||||||
Manifest file processing and @response file workaround for command-line length limits on Windows systems
|
|
||||||
The indicated task class is replaced by a subclass to prevent conflicts in case the class is wrapped more than once
|
|
||||||
"""
|
|
||||||
cls = Task.classes.get(class_name)
|
|
||||||
|
|
||||||
if not cls:
|
|
||||||
return None
|
|
||||||
|
|
||||||
derived_class = type(class_name, (cls,), {})
|
|
||||||
|
|
||||||
def exec_command(self, *k, **kw):
|
|
||||||
ret = super(self.__class__, self).exec_command(*k, **kw)
|
|
||||||
if not ret and self.env.CC_NAME == 'msvc' and getattr(self, 'do_manifest', None):
|
|
||||||
ret = self.exec_mf()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
derived_class.exec_command = exec_command
|
|
||||||
derived_class.exec_mf = exec_mf
|
|
||||||
|
|
||||||
if hasattr(cls, 'hcode'):
|
|
||||||
derived_class.hcode = cls.hcode
|
|
||||||
|
|
||||||
return derived_class
|
|
||||||
|
|
||||||
for k in 'cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
|
|
||||||
wrap_class(k)
|
|
||||||
|
|
||||||
def make_winapp(self, family):
|
def make_winapp(self, family):
|
||||||
append = self.env.append_unique
|
append = self.env.append_unique
|
||||||
|
|
Loading…
Reference in New Issue