summaryrefslogtreecommitdiffstats
path: root/toolkit/library/build
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/library/build')
-rw-r--r--toolkit/library/build/Makefile.in9
-rw-r--r--toolkit/library/build/dependentlibs.py151
-rw-r--r--toolkit/library/build/moz.build42
3 files changed, 202 insertions, 0 deletions
diff --git a/toolkit/library/build/Makefile.in b/toolkit/library/build/Makefile.in
new file mode 100644
index 0000000000..6ddd3c2d41
--- /dev/null
+++ b/toolkit/library/build/Makefile.in
@@ -0,0 +1,9 @@
+# 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/.
+
+include $(topsrcdir)/config/config.mk
+
+include $(topsrcdir)/config/rules.mk
+
+DUMP_SYMBOLS_FLAGS = --count-ctors
diff --git a/toolkit/library/build/dependentlibs.py b/toolkit/library/build/dependentlibs.py
new file mode 100644
index 0000000000..7523dd9554
--- /dev/null
+++ b/toolkit/library/build/dependentlibs.py
@@ -0,0 +1,151 @@
+# 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/.
+
+"""Given a library, dependentlibs.py prints the list of libraries it depends
+upon that are in the same directory, followed by the library itself.
+"""
+
+import os
+import re
+import subprocess
+import sys
+import mozpack.path as mozpath
+from collections import OrderedDict
+from mozpack.executables import (
+ get_type,
+ ELF,
+ MACHO,
+)
+from buildconfig import substs
+
+
+def dependentlibs_win32_objdump(lib):
+ proc = subprocess.Popen(
+ [substs["LLVM_OBJDUMP"], "--private-headers", lib],
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ deps = []
+ for line in proc.stdout:
+ match = re.match(r"\s+DLL Name: (\S+)", line)
+ if match:
+ # The DLL Name found might be mixed-case or upper-case. When cross-compiling,
+ # the actual DLLs in dist/bin are all lowercase, whether they are produced
+ # by the build system or copied from WIN32_REDIST_DIR. By turning everything
+ # to lowercase, we ensure we always find the files.
+ # At runtime, when Firefox reads the dependentlibs.list file on Windows, the
+ # case doesn't matter.
+ deps.append(match.group(1).lower())
+ proc.wait()
+ return deps
+
+
+def dependentlibs_readelf(lib):
+ """Returns the list of dependencies declared in the given ELF .so"""
+ proc = subprocess.Popen(
+ [substs.get("READELF", "readelf"), "-d", lib],
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ deps = []
+ for line in proc.stdout:
+ # Each line has the following format:
+ # tag (TYPE) value
+ # or with BSD readelf:
+ # tag TYPE value
+ # Looking for NEEDED type entries
+ tmp = line.strip().split(" ", 3)
+ if len(tmp) > 3 and "NEEDED" in tmp[1]:
+ # NEEDED lines look like:
+ # 0x00000001 (NEEDED) Shared library: [libname]
+ # or with BSD readelf:
+ # 0x00000001 NEEDED Shared library: [libname]
+ match = re.search(r"\[(.*)\]", tmp[3])
+ if match:
+ deps.append(match.group(1))
+ proc.wait()
+ return deps
+
+
+def dependentlibs_mac_objdump(lib):
+ """Returns the list of dependencies declared in the given MACH-O dylib"""
+ proc = subprocess.Popen(
+ [substs["LLVM_OBJDUMP"], "--private-headers", lib],
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ deps = []
+ cmd = None
+ for line in proc.stdout:
+ # llvm-objdump --private-headers output contains many different
+ # things. The interesting data
+ # is under "Load command n" sections, with the content:
+ # cmd LC_LOAD_DYLIB
+ # cmdsize 56
+ # name libname (offset 24)
+ tmp = line.split()
+ if len(tmp) < 2:
+ continue
+ if tmp[0] == "cmd":
+ cmd = tmp[1]
+ elif cmd == "LC_LOAD_DYLIB" and tmp[0] == "name":
+ deps.append(re.sub("@(?:rpath|executable_path)/", "", tmp[1]))
+ proc.wait()
+ return deps
+
+
+def dependentlibs(lib, libpaths, func):
+ """For a given library, returns the list of recursive dependencies that can
+ be found in the given list of paths, followed by the library itself."""
+ assert libpaths
+ assert isinstance(libpaths, list)
+ deps = OrderedDict()
+ for dep in func(lib):
+ if dep in deps or os.path.isabs(dep):
+ continue
+ for dir in libpaths:
+ deppath = os.path.join(dir, dep)
+ if os.path.exists(deppath):
+ deps.update(dependentlibs(deppath, libpaths, func))
+ # Black list the ICU data DLL because preloading it at startup
+ # leads to startup performance problems because of its excessive
+ # size (around 10MB).
+ if not dep.startswith(("icu")):
+ deps[dep] = deppath
+ break
+
+ return deps
+
+
+def gen_list(output, lib):
+ libpaths = [os.path.join(substs["DIST"], "bin")]
+ binary_type = get_type(lib)
+ if binary_type == ELF:
+ func = dependentlibs_readelf
+ elif binary_type == MACHO:
+ func = dependentlibs_mac_objdump
+ else:
+ ext = os.path.splitext(lib)[1]
+ assert ext == ".dll"
+ func = dependentlibs_win32_objdump
+
+ deps = dependentlibs(lib, libpaths, func)
+ base_lib = mozpath.basename(lib)
+ deps[base_lib] = mozpath.join(libpaths[0], base_lib)
+ output.write("\n".join(deps.keys()) + "\n")
+
+ with open(output.name + ".gtest", "w") as gtest_out:
+ libs = list(deps.keys())
+ libs[-1] = "gtest/" + libs[-1]
+ gtest_out.write("\n".join(libs) + "\n")
+
+ return set(deps.values())
+
+
+def main():
+ gen_list(sys.stdout, sys.argv[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/toolkit/library/build/moz.build b/toolkit/library/build/moz.build
new file mode 100644
index 0000000000..df0afaab84
--- /dev/null
+++ b/toolkit/library/build/moz.build
@@ -0,0 +1,42 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+USE_LIBS += [
+ "static:xul",
+]
+
+# This library is entirely composed of Rust code, and needs to come after
+# all the C++ code so any possible C++ -> Rust calls can be resolved.
+USE_LIBS += ["gkrust"]
+
+Libxul("xul-real")
+
+if CONFIG["COMPILE_ENVIRONMENT"]:
+ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
+ full_libname = SHARED_LIBRARY_NAME
+ else:
+ full_libname = "%s%s%s" % (
+ CONFIG["DLL_PREFIX"],
+ SHARED_LIBRARY_NAME,
+ CONFIG["DLL_SUFFIX"],
+ )
+ GeneratedFile(
+ "dependentlibs.list",
+ "dependentlibs.list.gtest",
+ script="dependentlibs.py",
+ entry_point="gen_list",
+ inputs=["!%s" % full_libname],
+ )
+ FINAL_TARGET_FILES += ["!dependentlibs.list", "!dependentlibs.list.gtest"]
+
+# Generate GDB pretty printer-autoload files only on Linux. OSX's GDB is
+# too old to support Python pretty-printers; if this changes, we could
+# make this 'ifdef __GNUC__'.
+if CONFIG["OS_ARCH"] == "Linux":
+ # Create a GDB Python auto-load file alongside the libxul shared library
+ # in the build directory.
+ DEFINES["topsrcdir"] = TOPSRCDIR
+ OBJDIR_FILES.toolkit.library.build += ["../libxul.so-gdb.py"]