summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/action/generate_symbols_file.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/action/generate_symbols_file.py')
-rw-r--r--python/mozbuild/mozbuild/action/generate_symbols_file.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/action/generate_symbols_file.py b/python/mozbuild/mozbuild/action/generate_symbols_file.py
new file mode 100644
index 0000000000..955a676c08
--- /dev/null
+++ b/python/mozbuild/mozbuild/action/generate_symbols_file.py
@@ -0,0 +1,95 @@
+# 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/.
+
+import argparse
+import os
+from io import StringIO
+
+import buildconfig
+
+from mozbuild.preprocessor import Preprocessor
+from mozbuild.util import DefinesAction
+
+
+def generate_symbols_file(output, *args):
+ """ """
+ parser = argparse.ArgumentParser()
+ parser.add_argument("input")
+ parser.add_argument("-D", action=DefinesAction)
+ parser.add_argument("-U", action="append", default=[])
+ args = parser.parse_args(args)
+ input = os.path.abspath(args.input)
+
+ pp = Preprocessor()
+ pp.context.update(buildconfig.defines["ALLDEFINES"])
+ if args.D:
+ pp.context.update(args.D)
+ for undefine in args.U:
+ if undefine in pp.context:
+ del pp.context[undefine]
+ # Hack until MOZ_DEBUG_FLAGS are simply part of buildconfig.defines
+ if buildconfig.substs.get("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()]
+
+ libname, ext = os.path.splitext(os.path.basename(output.name))
+
+ if 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.
+ assert ext == ".def"
+ output.write("LIBRARY %s\nEXPORTS\n %s\n" % (libname, "\n ".join(symbols)))
+ elif (
+ buildconfig.substs.get("GCC_USE_GNU_LD")
+ or buildconfig.substs["OS_TARGET"] == "SunOS"
+ ):
+ # A linker version script is generated for GNU LD that looks like the
+ # following:
+ # liblibrary.so {
+ # global:
+ # symbol1;
+ # symbol2;
+ # ...
+ # local:
+ # *;
+ # };
+ output.write(
+ "%s {\nglobal:\n %s;\nlocal:\n *;\n};" % (libname, ";\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))
+
+ return set(pp.includes)