mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1235132 - Add support for a more-or-less cross-platform symbols file. r=gps
Currently, one needs to define DEFFILE or LD_VERSION_SCRIPT appropriately, and somehow deal with the fact that their input format is different, which currently relies on manual invocations of the convert_def_file script, with awkward aggregations. This simplifies the problem by using a simple list of symbols, with preprocessing, allowing #includes.
This commit is contained in:
parent
0ff76be786
commit
84bdf4908c
@ -462,6 +462,19 @@ EXTRA_DEPS += $(LD_VERSION_SCRIPT)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef SYMBOLS_FILE
|
||||
ifdef GCC_USE_GNU_LD
|
||||
EXTRA_DSO_LDOPTS += -Wl,--version-script,$(SYMBOLS_FILE)
|
||||
else
|
||||
ifeq ($(OS_TARGET),Darwin)
|
||||
EXTRA_DSO_LDOPTS += -Wl,-exported_symbols_list,$(SYMBOLS_FILE)
|
||||
endif
|
||||
ifeq ($(OS_TARGET),WINNT)
|
||||
EXTRA_DSO_LDOPTS += -DEF:$(call normalizepath,$(SYMBOLS_FILE))
|
||||
endif
|
||||
endif
|
||||
EXTRA_DEPS += $(SYMBOLS_FILE)
|
||||
endif
|
||||
#
|
||||
# GNU doesn't have path length limitation
|
||||
#
|
||||
|
79
python/mozbuild/mozbuild/action/generate_symbols_file.py
Normal file
79
python/mozbuild/mozbuild/action/generate_symbols_file.py
Normal file
@ -0,0 +1,79 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import buildconfig
|
||||
import os
|
||||
from StringIO import StringIO
|
||||
from mozbuild.preprocessor import Preprocessor
|
||||
|
||||
|
||||
def generate_symbols_file(output, input):
|
||||
''' '''
|
||||
input = os.path.abspath(input)
|
||||
|
||||
pp = Preprocessor()
|
||||
pp.context.update(buildconfig.defines)
|
||||
# Hack until MOZ_DEBUG_FLAGS are simply part of buildconfig.defines
|
||||
if buildconfig.substs['MOZ_DEBUG']:
|
||||
pp.context['DEBUG'] = '1'
|
||||
# Ensure @DATA@ works as expected (see the Windows section further below)
|
||||
if buildconfig.substs['OS_TARGET'] == 'WINNT':
|
||||
pp.context['DATA'] = 'DATA'
|
||||
else:
|
||||
pp.context['DATA'] = ''
|
||||
pp.out = StringIO()
|
||||
pp.do_filter('substitution')
|
||||
pp.do_include(input)
|
||||
|
||||
symbols = [s.strip() for s in pp.out.getvalue().splitlines() if s.strip()]
|
||||
|
||||
if buildconfig.substs['GCC_USE_GNU_LD']:
|
||||
# A linker version script is generated for GNU LD that looks like the
|
||||
# following:
|
||||
# {
|
||||
# global:
|
||||
# symbol1;
|
||||
# symbol2;
|
||||
# ...
|
||||
# local:
|
||||
# *;
|
||||
# };
|
||||
output.write('{\nglobal:\n %s;\nlocal:\n *;\n};'
|
||||
% ';\n '.join(symbols))
|
||||
elif buildconfig.substs['OS_TARGET'] == 'Darwin':
|
||||
# A list of symbols is generated for Apple ld that simply lists all
|
||||
# symbols, with an underscore prefix.
|
||||
output.write(''.join('_%s\n' % s for s in symbols))
|
||||
elif buildconfig.substs['OS_TARGET'] == 'WINNT':
|
||||
# A def file is generated for MSVC link.exe that looks like the
|
||||
# following:
|
||||
# LIBRARY library.dll
|
||||
# EXPORTS
|
||||
# symbol1
|
||||
# symbol2
|
||||
# ...
|
||||
#
|
||||
# link.exe however requires special markers for data symbols, so in
|
||||
# that case the symbols look like:
|
||||
# data_symbol1 DATA
|
||||
# data_symbol2 DATA
|
||||
# ...
|
||||
#
|
||||
# In the input file, this is just annotated with the following syntax:
|
||||
# data_symbol1 @DATA@
|
||||
# data_symbol2 @DATA@
|
||||
# ...
|
||||
# The DATA variable is "simply" expanded by the preprocessor, to
|
||||
# nothing on non-Windows, such that we only get the symbol name on
|
||||
# those platforms, and to DATA on Windows, so that the "DATA" part
|
||||
# is, in fact, part of the symbol name as far as the symbols variable
|
||||
# is concerned.
|
||||
libname, ext = os.path.splitext(os.path.basename(output.name))
|
||||
assert ext == '.symbols'
|
||||
output.write('LIBRARY %s\nEXPORTS\n %s\n'
|
||||
% (libname, '\n '.join(symbols)))
|
||||
|
||||
return set(pp.includes)
|
@ -1171,6 +1171,8 @@ INSTALL_TARGETS += %(prefix)s
|
||||
backend_file.write('DSO_SONAME := %s\n' % libdef.soname)
|
||||
if libdef.is_sdk:
|
||||
backend_file.write('SDK_LIBRARY := %s\n' % libdef.import_name)
|
||||
if libdef.symbols_file:
|
||||
backend_file.write('SYMBOLS_FILE := %s\n' % libdef.symbols_file)
|
||||
|
||||
def _process_static_library(self, libdef, backend_file):
|
||||
backend_file.write_once('LIBRARY_NAME := %s\n' % libdef.basename)
|
||||
|
@ -1213,6 +1213,16 @@ VARIABLES = {
|
||||
This variable can only be used on Linux.
|
||||
""", None),
|
||||
|
||||
'SYMBOLS_FILE': (SourcePath, unicode,
|
||||
"""A file containing a list of symbols to export from a shared library.
|
||||
|
||||
The given file contains a list of symbols to be exported, and is
|
||||
preprocessed.
|
||||
A special marker "@DATA@" must be added after a symbol name if it
|
||||
points to data instead of code, so that the Windows linker can treat
|
||||
them correctly.
|
||||
""", None),
|
||||
|
||||
'BRANDING_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list,
|
||||
"""List of files to be installed into the branding directory.
|
||||
|
||||
|
@ -461,6 +461,7 @@ class SharedLibrary(Library):
|
||||
__slots__ = (
|
||||
'soname',
|
||||
'variant',
|
||||
'symbols_file',
|
||||
)
|
||||
|
||||
FRAMEWORK = 1
|
||||
@ -468,7 +469,7 @@ class SharedLibrary(Library):
|
||||
MAX_VARIANT = 3
|
||||
|
||||
def __init__(self, context, basename, real_name=None, is_sdk=False,
|
||||
soname=None, variant=None):
|
||||
soname=None, variant=None, symbols_file=False):
|
||||
assert(variant in range(1, self.MAX_VARIANT) or variant is None)
|
||||
Library.__init__(self, context, basename, real_name, is_sdk)
|
||||
self.variant = variant
|
||||
@ -497,6 +498,11 @@ class SharedLibrary(Library):
|
||||
else:
|
||||
self.soname = self.lib_name
|
||||
|
||||
if symbols_file:
|
||||
self.symbols_file = '%s.symbols' % self.lib_name
|
||||
else:
|
||||
self.symbols_file = None
|
||||
|
||||
|
||||
class ExternalLibrary(object):
|
||||
"""Empty mixin for libraries built by an external build system."""
|
||||
|
@ -507,6 +507,23 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
'STATIC_LIBRARY_NAME. Please change one of them.',
|
||||
context)
|
||||
|
||||
symbols_file = context.get('SYMBOLS_FILE')
|
||||
if symbols_file:
|
||||
if not shared_lib:
|
||||
raise SandboxValidationError(
|
||||
'SYMBOLS_FILE can only be used with a SHARED_LIBRARY.',
|
||||
context)
|
||||
if context.get('DEFFILE') or context.get('LD_VERSION_SCRIPT'):
|
||||
raise SandboxValidationError(
|
||||
'SYMBOLS_FILE cannot be used along DEFFILE or '
|
||||
'LD_VERSION_SCRIPT.', context)
|
||||
if not os.path.exists(symbols_file.full_path):
|
||||
raise SandboxValidationError(
|
||||
'Path specified in SYMBOLS_FILE does not exist: %s '
|
||||
'(resolved to %s)' % (symbols_file,
|
||||
symbols_file.full_path), context)
|
||||
shared_args['symbols_file'] = True
|
||||
|
||||
if shared_lib:
|
||||
lib = SharedLibrary(context, libname, **shared_args)
|
||||
self._libs[libname].append(lib)
|
||||
@ -515,6 +532,13 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||
yield ChromeManifestEntry(context,
|
||||
'components/components.manifest',
|
||||
ManifestBinaryComponent('components', lib.lib_name))
|
||||
if symbols_file:
|
||||
script = mozpath.join(
|
||||
mozpath.dirname(mozpath.dirname(__file__)),
|
||||
'action', 'generate_symbols_file.py')
|
||||
yield GeneratedFile(context, script,
|
||||
'generate_symbols_file', lib.symbols_file,
|
||||
[symbols_file.full_path])
|
||||
if static_lib:
|
||||
lib = StaticLibrary(context, libname, **static_args)
|
||||
self._libs[libname].append(lib)
|
||||
|
Loading…
Reference in New Issue
Block a user