diff options
Diffstat (limited to 'toolkit/library/build')
-rw-r--r-- | toolkit/library/build/Makefile.in | 9 | ||||
-rw-r--r-- | toolkit/library/build/dependentlibs.py | 151 | ||||
-rw-r--r-- | toolkit/library/build/moz.build | 42 |
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"] |