diff --git a/db/sqlite3/src/Makefile.in b/db/sqlite3/src/Makefile.in index 4b5041cd2fcd..12364e94025f 100644 --- a/db/sqlite3/src/Makefile.in +++ b/db/sqlite3/src/Makefile.in @@ -5,6 +5,8 @@ LIB_IS_C_ONLY = 1 +include $(topsrcdir)/config/config.mk + ifeq ($(OS_ARCH),WINNT) DEFFILE = $(CURDIR)/sqlite-processed.def @@ -20,10 +22,25 @@ sqlite-version.h: sqlite-version.py sqlite3.h # We have to preprocess our def file because we need different symbols in debug # builds exposed that are not built in non-debug builds. $(DEFFILE): sqlite.def - @$(call py_action,preprocessor,$(DEFINES) \ + @$(call py_action,preprocessor,$(DEFINES) $(XULPPFLAGS) \ $(srcdir)/sqlite.def -o $(DEFFILE)) export:: sqlite-version.h +else +ifndef MOZ_FOLD_LIBS +ifdef GCC_USE_GNU_LD + +GARBAGE += \ + $(LD_VERSION_SCRIPT) \ + $(NULL) + +# Convert to the format we need for ld. +$(LD_VERSION_SCRIPT): $(srcdir)/sqlite.def + @$(call py_action,convert_def_file, \ + $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) -o $@ $^) + +endif +endif endif ifeq (Darwin,$(OS_TARGET)) diff --git a/db/sqlite3/src/moz.build b/db/sqlite3/src/moz.build index f899190436ea..14c79b48f067 100644 --- a/db/sqlite3/src/moz.build +++ b/db/sqlite3/src/moz.build @@ -74,6 +74,11 @@ if CONFIG['OS_ARCH'] == 'WINNT': RCFILE = 'sqlite.rc' RESFILE = 'sqlite.res' +if CONFIG['OS_ARCH'] == 'Linux' and \ + not CONFIG['MOZ_FOLD_LIBS'] and \ + CONFIG['GCC_USE_GNU_LD']: + LD_VERSION_SCRIPT = 'sqlite-processed.def' + # Suppress warnings in third-party code. if CONFIG['GNU_CC']: CFLAGS += [ diff --git a/db/sqlite3/src/sqlite.def b/db/sqlite3/src/sqlite.def index 5eeb52257ae1..c9f741a5796f 100644 --- a/db/sqlite3/src/sqlite.def +++ b/db/sqlite3/src/sqlite.def @@ -126,6 +126,9 @@ EXPORTS sqlite3_step sqlite3_stmt_readonly sqlite3_stmt_status +#ifdef XP_UNIX + sqlite3_temp_directory +#endif sqlite3_thread_cleanup sqlite3_total_changes sqlite3_trace @@ -151,7 +154,7 @@ EXPORTS sqlite3_vfs_unregister sqlite3_vfs_register sqlite3_vmprintf -#ifdef SQLITE_DEBUG +#ifdef DEBUG sqlite3_mutex_held sqlite3_mutex_notheld #endif diff --git a/python/mozbuild/mozbuild/action/convert_def_file.py b/python/mozbuild/mozbuild/action/convert_def_file.py new file mode 100644 index 000000000000..e0a87a6f10b2 --- /dev/null +++ b/python/mozbuild/mozbuild/action/convert_def_file.py @@ -0,0 +1,107 @@ +# 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/. + +# Convert Windows-style export files into a single Unix-style linker +# script, applying any necessary preprocessing. + +import itertools +import re +import sys +from StringIO import StringIO + +from mozbuild.preprocessor import Preprocessor +from mozbuild.util import FileAvoidWrite + +def preprocess_file(pp, deffile): + output = StringIO() + with open(deffile, 'r') as input: + pp.processFile(input=input, output=output) + return output.getvalue().splitlines() + +# NSS .def files serve multiple masters, as this copied comment indicates: +# +# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS +# 1. For all unix platforms, the string ";-" means "remove this line" +# 2. For all unix platforms, the string " DATA " will be removed from any +# line on which it occurs. +# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. +# On AIX, lines containing ";+" will be removed. +# 4. For all unix platforms, the string ";;" will have the ";;" removed. +# 5. For all unix platforms, after the above processing has taken place, +# all characters after the first ";" on the line will be removed. +# And for AIX, the first ";" will also be removed. +# This file is passed directly to windows. Since ';' is a comment, all UNIX +# directives are hidden behind ";", ";+", and ";-" +# +# We don't care about rule 1, as that mainly serves to eliminate LIBRARY +# and EXPORTS lines. We don't want to enforce rule 3, as we know how to +# eliminate comments. ';+' also tends to hide Unix linker-script specific +# things, which we don't want to deal with here. Rule 5 is also unnecessary; +# later comment-aware processing will deal with that. +# +# We do need to handle rule 2, since our symbol extraction doesn't want to +# see DATA keywords. We also need to handle rule 4, since ';;' often hides +# things marked with DATA. +def nss_preprocess_file(deffile): + with open(deffile, 'r') as input: + for line in input: + # Rule 2, and then rule 4. + yield line.replace(' DATA ', '').replace(';;', '') + +COMMENT = re.compile(';.*') + +def extract_symbols(lines): + # Filter comments. + nocomments = iter(COMMENT.sub('', s).strip() for s in lines) + lines = iter(s for s in nocomments if len(s)) + + exports = itertools.dropwhile(lambda s: 'EXPORTS' not in s, lines) + symbols = set() + for line in exports: + if 'EXPORTS' in line: + # Handle the case where symbols are specified along with EXPORT. + fields = line.split()[1:] + if len(fields) == 0: + continue + else: + fields = line.split() + + # We don't support aliases or keywords (ordinals, PRIVATE, etc.) for + # symbols. But since aliases can also be specified as 'SYM=ALIAS' + # with no whitespace, we need extra checks on the original symbol. + if len(fields) != 1 or '=' in fields[0]: + raise 'aliases and keywords are not supported' + + symbols.add(fields[0]) + + return symbols + +def main(args): + pp = Preprocessor() + optparser = pp.getCommandLineParser() + optparser.add_option('--nss-file', action='append', + type='string', dest='nss_files', default=[], + help='Specify a .def file that should have NSS\'s processing rules applied to it') + options, deffiles = optparser.parse_args(args) + + symbols = set() + for f in options.nss_files: + symbols |= extract_symbols(nss_preprocess_file(f)) + for f in deffiles: + # Start each deffile off with a clean slate. + defpp = pp.clone() + symbols |= extract_symbols(preprocess_file(defpp, f)) + + script = """{ +global: + %s +local: + *; +}; +""" + with FileAvoidWrite(options.output) as f: + f.write(script % '\n '.join("%s;" % s for s in sorted(symbols))) + +if __name__ == '__main__': + main(sys.argv[1:])