mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1036894 part 4 - Allow to track library linkage for all kinds of programs and libraries. r=gps
This commit is contained in:
parent
e97e74b6eb
commit
e679e0b8b9
@ -1120,16 +1120,16 @@ class RecursiveMakeBackend(CommonBackend):
|
||||
backend_file.write('SDK_LIBRARY := %s\n' % libdef.import_name)
|
||||
|
||||
thisobjdir = libdef.objdir
|
||||
topobjdir = libdef.topobjdir.replace(os.sep, '/')
|
||||
for objdir, basename in libdef.static_libraries:
|
||||
topobjdir = mozpath.normsep(libdef.topobjdir)
|
||||
for obj in libdef.linked_libraries:
|
||||
# If this is an external objdir (i.e., comm-central), use the other
|
||||
# directory instead of $(DEPTH).
|
||||
if objdir.startswith(topobjdir + '/'):
|
||||
relpath = '$(DEPTH)/%s' % mozpath.relpath(objdir, topobjdir)
|
||||
if obj.objdir.startswith(topobjdir + '/'):
|
||||
relpath = '$(DEPTH)/%s' % mozpath.relpath(obj.objdir, topobjdir)
|
||||
else:
|
||||
relpath = mozpath.relpath(objdir, thisobjdir)
|
||||
backend_file.write('SHARED_LIBRARY_LIBS += %s/$(LIB_PREFIX)%s.$(LIB_SUFFIX)\n'
|
||||
% (relpath, basename))
|
||||
relpath = mozpath.relpath(obj.objdir, thisobjdir)
|
||||
backend_file.write('SHARED_LIBRARY_LIBS += %s/%s\n'
|
||||
% (relpath, obj.static_name))
|
||||
|
||||
def _process_host_library(self, libdef, backend_file):
|
||||
backend_file.write('HOST_LIBRARY_NAME = %s\n' % libdef.basename)
|
||||
|
@ -324,7 +324,30 @@ class ExampleWebIDLInterface(SandboxDerived):
|
||||
self.name = name
|
||||
|
||||
|
||||
class BaseProgram(SandboxDerived):
|
||||
class LinkageWrongKindError(Exception):
|
||||
"""Error thrown when trying to link objects of the wrong kind"""
|
||||
|
||||
|
||||
class Linkable(SandboxDerived):
|
||||
"""Generic sandbox container object for programs and libraries"""
|
||||
__slots__ = ('linked_libraries')
|
||||
|
||||
def __init__(self, sandbox):
|
||||
SandboxDerived.__init__(self, sandbox)
|
||||
self.linked_libraries = []
|
||||
|
||||
def link_library(self, obj):
|
||||
assert isinstance(obj, BaseLibrary)
|
||||
if obj.kind == obj.COMPONENT:
|
||||
raise LinkageWrongKindError(
|
||||
'Linkable.link_library() does not take components.')
|
||||
if obj.KIND != self.KIND:
|
||||
raise LinkageWrongKindError('%s != %s' % (obj.KIND, self.KIND))
|
||||
self.linked_libraries.append(obj)
|
||||
obj.refcount += 1
|
||||
|
||||
|
||||
class BaseProgram(Linkable):
|
||||
"""Sandbox container object for programs, which is a unicode string.
|
||||
|
||||
This class handles automatically appending a binary suffix to the program
|
||||
@ -336,7 +359,7 @@ class BaseProgram(SandboxDerived):
|
||||
__slots__ = ('program')
|
||||
|
||||
def __init__(self, sandbox, program):
|
||||
SandboxDerived.__init__(self, sandbox)
|
||||
Linkable.__init__(self, sandbox)
|
||||
|
||||
bin_suffix = sandbox['CONFIG'].get(self.SUFFIX_VAR, '')
|
||||
if not program.endswith(bin_suffix):
|
||||
@ -347,38 +370,37 @@ class BaseProgram(SandboxDerived):
|
||||
class Program(BaseProgram):
|
||||
"""Sandbox container object for PROGRAM"""
|
||||
SUFFIX_VAR = 'BIN_SUFFIX'
|
||||
KIND = 'target'
|
||||
|
||||
|
||||
class HostProgram(BaseProgram):
|
||||
"""Sandbox container object for HOST_PROGRAM"""
|
||||
SUFFIX_VAR = 'HOST_BIN_SUFFIX'
|
||||
KIND = 'host'
|
||||
|
||||
|
||||
class SimpleProgram(BaseProgram):
|
||||
"""Sandbox container object for each program in SIMPLE_PROGRAMS"""
|
||||
SUFFIX_VAR = 'BIN_SUFFIX'
|
||||
KIND = 'target'
|
||||
|
||||
|
||||
class HostSimpleProgram(BaseProgram):
|
||||
"""Sandbox container object for each program in HOST_SIMPLE_PROGRAMS"""
|
||||
SUFFIX_VAR = 'HOST_BIN_SUFFIX'
|
||||
KIND = 'host'
|
||||
|
||||
|
||||
class BaseLibrary(SandboxDerived):
|
||||
"""Generic sandbox container object for libraries.
|
||||
|
||||
The static_libraries member tracks the list of relative directory and
|
||||
library names of static libraries that are meant to be linked into
|
||||
the library defined by an instance of this class.
|
||||
"""
|
||||
class BaseLibrary(Linkable):
|
||||
"""Generic sandbox container object for libraries."""
|
||||
__slots__ = (
|
||||
'basename',
|
||||
'import_name',
|
||||
'is_sdk',
|
||||
'link_into',
|
||||
'shared_name',
|
||||
'static_name',
|
||||
'soname',
|
||||
'static_libraries',
|
||||
'refcount',
|
||||
)
|
||||
|
||||
@ -390,9 +412,10 @@ class BaseLibrary(SandboxDerived):
|
||||
MAX_TYPE = 6
|
||||
|
||||
def __init__(self, sandbox, basename, kind=None, soname=None,
|
||||
static_name=None, shared_name=None, is_sdk=False):
|
||||
static_name=None, shared_name=None, is_sdk=False,
|
||||
link_into=None):
|
||||
assert(kind in range(1, self.MAX_TYPE))
|
||||
SandboxDerived.__init__(self, sandbox)
|
||||
Linkable.__init__(self, sandbox)
|
||||
|
||||
self.basename = basename
|
||||
self.kind = kind
|
||||
@ -432,20 +455,20 @@ class BaseLibrary(SandboxDerived):
|
||||
else:
|
||||
self.soname = self.shared_name
|
||||
self.is_sdk = is_sdk
|
||||
self.link_into = link_into
|
||||
|
||||
self.refcount = 0
|
||||
self.static_libraries = []
|
||||
|
||||
def link_static_lib(self, objdir, basename):
|
||||
self.static_libraries.append((objdir, basename))
|
||||
|
||||
|
||||
class Library(BaseLibrary):
|
||||
"""Sandbox container object for a library"""
|
||||
KIND = 'target'
|
||||
|
||||
|
||||
class HostLibrary(BaseLibrary):
|
||||
"""Sandbox container object for a host library"""
|
||||
KIND = 'host'
|
||||
|
||||
def __init__(self, sandbox, basename):
|
||||
BaseLibrary.__init__(self, sandbox, basename,
|
||||
kind=self.STATIC)
|
||||
|
@ -38,6 +38,7 @@ from .data import (
|
||||
JARManifest,
|
||||
JavaScriptModules,
|
||||
Library,
|
||||
LinkageWrongKindError,
|
||||
LocalInclude,
|
||||
PerSourceFlag,
|
||||
PreprocessedTestWebIDLFile,
|
||||
@ -86,9 +87,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
k = k.encode('ascii')
|
||||
self.info[k] = v
|
||||
|
||||
self._libs = OrderedDefaultDict(OrderedDict)
|
||||
self._libs = OrderedDefaultDict(list)
|
||||
self._binaries = OrderedDict()
|
||||
self._final_libs = []
|
||||
|
||||
def emit(self, output):
|
||||
"""Convert the BuildReader output into data structures.
|
||||
@ -135,40 +135,45 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
yield ReaderSummary(file_count, sandbox_execution_time, emitter_time)
|
||||
|
||||
def _emit_libs_derived(self, sandboxes):
|
||||
for objdir, libname, final_lib in self._final_libs:
|
||||
if final_lib not in self._libs:
|
||||
for lib in (l for libs in self._libs.values() for l in libs):
|
||||
if not lib.link_into:
|
||||
continue
|
||||
if lib.link_into not in self._libs:
|
||||
raise Exception('FINAL_LIBRARY in %s (%s) does not match any '
|
||||
'LIBRARY_NAME' % (objdir, final_lib))
|
||||
libs = self._libs[final_lib]
|
||||
if len(libs) > 1:
|
||||
'LIBRARY_NAME' % (lib.objdir, lib.link_info))
|
||||
candidates = self._libs[lib.link_into]
|
||||
if len(candidates) > 1:
|
||||
raise Exception('FINAL_LIBRARY in %s (%s) matches a '
|
||||
'LIBRARY_NAME defined in multiple places (%s)' %
|
||||
(objdir, final_lib, ', '.join(libs.keys())))
|
||||
libs.values()[0].link_static_lib(objdir, libname)
|
||||
self._libs[libname][objdir].refcount += 1
|
||||
(lib.objdir, lib.link_into,
|
||||
', '.join(l.objdir for l in candidates)))
|
||||
# emit_from_sandbox ensures libraries with a FINAL_LIBRARY are
|
||||
# static.
|
||||
assert lib.KIND == 'target' and lib.kind == lib.STATIC
|
||||
candidates[0].link_library(lib)
|
||||
|
||||
# The refcount can't go above 1 right now. It might in the future,
|
||||
# but that will have to be specifically handled. At which point the
|
||||
# refcount might have to be a list of referencees, for better error
|
||||
# reporting.
|
||||
assert self._libs[libname][objdir].refcount <= 1
|
||||
assert lib.refcount <= 1
|
||||
|
||||
def recurse_libs(path, name):
|
||||
for p, n in self._libs[name][path].static_libraries:
|
||||
yield p
|
||||
for q in recurse_libs(p, n):
|
||||
def recurse_libs(lib):
|
||||
for obj in lib.linked_libraries:
|
||||
yield obj.objdir
|
||||
for q in recurse_libs(obj):
|
||||
yield q
|
||||
|
||||
for basename, libs in self._libs.items():
|
||||
for path, libdef in libs.items():
|
||||
# For all root libraries (i.e. libraries that don't have a
|
||||
# FINAL_LIBRARY), record, for each static library it links
|
||||
# (recursively), that its FINAL_LIBRARY is that root library.
|
||||
if not libdef.refcount:
|
||||
for p in recurse_libs(path, basename):
|
||||
passthru = VariablePassthru(sandboxes[p])
|
||||
passthru.variables['FINAL_LIBRARY'] = basename
|
||||
yield passthru
|
||||
yield libdef
|
||||
for lib in (l for libs in self._libs.values() for l in libs):
|
||||
# For all root libraries (i.e. libraries that don't have a
|
||||
# FINAL_LIBRARY), record, for each static library it links
|
||||
# (recursively), that its FINAL_LIBRARY is that root library.
|
||||
if not lib.refcount:
|
||||
for p in recurse_libs(lib):
|
||||
passthru = VariablePassthru(sandboxes[p])
|
||||
passthru.variables['FINAL_LIBRARY'] = lib.basename
|
||||
yield passthru
|
||||
yield lib
|
||||
|
||||
for obj in self._binaries.values():
|
||||
yield obj
|
||||
@ -391,8 +396,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
if host_libname == libname:
|
||||
raise SandboxValidationError('LIBRARY_NAME and '
|
||||
'HOST_LIBRARY_NAME must have a different value', sandbox)
|
||||
self._libs[host_libname][sandbox['OBJDIR']] = \
|
||||
HostLibrary(sandbox, host_libname)
|
||||
self._libs[host_libname].append(HostLibrary(sandbox, host_libname))
|
||||
|
||||
final_lib = sandbox.get('FINAL_LIBRARY')
|
||||
if not libname and final_lib:
|
||||
@ -410,6 +414,10 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
|
||||
soname = sandbox.get('SONAME')
|
||||
|
||||
args = {
|
||||
'kind': 0,
|
||||
}
|
||||
|
||||
if final_lib:
|
||||
if isinstance(sandbox, MozbuildSandbox):
|
||||
if static_lib:
|
||||
@ -428,13 +436,10 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
raise SandboxValidationError(
|
||||
'FINAL_LIBRARY conflicts with IS_COMPONENT. '
|
||||
'Please remove one.', sandbox)
|
||||
self._final_libs.append((sandbox['OBJDIR'], libname, final_lib))
|
||||
args['link_into'] = final_lib
|
||||
static_lib = True
|
||||
|
||||
if libname:
|
||||
args = {
|
||||
'kind': 0,
|
||||
}
|
||||
if is_component:
|
||||
if shared_lib:
|
||||
raise SandboxValidationError(
|
||||
@ -496,8 +501,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
if sandbox.get('SDK_LIBRARY'):
|
||||
args['is_sdk'] = True
|
||||
|
||||
self._libs[libname][sandbox['OBJDIR']] = \
|
||||
Library(sandbox, libname, **args)
|
||||
self._libs[libname].append(Library(sandbox, libname, **args))
|
||||
|
||||
|
||||
# While there are multiple test manifests, the behavior is very similar
|
||||
|
Loading…
Reference in New Issue
Block a user