summaryrefslogtreecommitdiffstats
path: root/toolkit/library
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/library')
-rw-r--r--toolkit/library/build/Makefile.in20
-rw-r--r--toolkit/library/build/dependentlibs.py153
-rw-r--r--toolkit/library/build/moz.build42
-rw-r--r--toolkit/library/dummydll/dummydll.cpp12
-rw-r--r--toolkit/library/dummydll/moz.build20
-rw-r--r--toolkit/library/gecko.natvis151
-rw-r--r--toolkit/library/gen_buildid.py41
-rw-r--r--toolkit/library/gtest/TestUCRTDepends.cpp142
-rw-r--r--toolkit/library/gtest/moz.build26
-rw-r--r--toolkit/library/gtest/rust/Cargo.toml34
-rw-r--r--toolkit/library/gtest/rust/lib.rs16
-rw-r--r--toolkit/library/gtest/rust/moz.build16
-rw-r--r--toolkit/library/libxul.so-gdb.py35
-rw-r--r--toolkit/library/moz.build417
-rw-r--r--toolkit/library/nsDllMain.cpp38
-rw-r--r--toolkit/library/rust/Cargo.toml31
-rw-r--r--toolkit/library/rust/gkrust-features.mozbuild81
-rw-r--r--toolkit/library/rust/lib.rs9
-rw-r--r--toolkit/library/rust/moz.build58
-rw-r--r--toolkit/library/rust/shared/Cargo.toml156
-rw-r--r--toolkit/library/rust/shared/lib.rs159
-rw-r--r--toolkit/library/symverscript.in4
-rw-r--r--toolkit/library/xulrunner.rc6
23 files changed, 1667 insertions, 0 deletions
diff --git a/toolkit/library/build/Makefile.in b/toolkit/library/build/Makefile.in
new file mode 100644
index 0000000000..474c42518c
--- /dev/null
+++ b/toolkit/library/build/Makefile.in
@@ -0,0 +1,20 @@
+# 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
+
+ifdef CLANG_CL
+ifdef MOZ_PROFILE_USE
+ifeq (x86,$(CPU_ARCH))
+PGO_LDFLAGS += -ORDER:@$(topsrcdir)/build/win32/orderfile.txt
+endif
+ifeq (x86_64,$(CPU_ARCH))
+PGO_LDFLAGS += -ORDER:@$(topsrcdir)/build/win64/orderfile.txt
+endif
+endif
+endif
diff --git a/toolkit/library/build/dependentlibs.py b/toolkit/library/build/dependentlibs.py
new file mode 100644
index 0000000000..d7559844d4
--- /dev/null
+++ b/toolkit/library/build/dependentlibs.py
@@ -0,0 +1,153 @@
+# 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("\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("\[(.*)\]", 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("^@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). Same thing with d3dcompiler_47.dll, but
+ # to a lesser extent, and we were going to dynamically load it
+ # anyway.
+ if not dep.startswith(("icu", "d3dcompiler_47")):
+ 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"]
diff --git a/toolkit/library/dummydll/dummydll.cpp b/toolkit/library/dummydll/dummydll.cpp
new file mode 100644
index 0000000000..47605279e3
--- /dev/null
+++ b/toolkit/library/dummydll/dummydll.cpp
@@ -0,0 +1,12 @@
+/* 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 <windows.h>
+
+BOOL WINAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpvReserved) {
+ if (dwReason == DLL_PROCESS_ATTACH) {
+ ::DisableThreadLibraryCalls((HMODULE)hModule);
+ }
+ return TRUE;
+}
diff --git a/toolkit/library/dummydll/moz.build b/toolkit/library/dummydll/moz.build
new file mode 100644
index 0000000000..4dd71bf38d
--- /dev/null
+++ b/toolkit/library/dummydll/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; c-basic-offset: 4; 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/.
+
+# Bug 1294650 - populate our install with a shim dll to work around a
+# 3rd party code injection crash.
+
+SOURCES += [
+ "dummydll.cpp",
+]
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+ GeckoSharedLibrary("qipcap64")
+else:
+ GeckoSharedLibrary("qipcap")
+
+NoVisibilityFlags()
+NO_PGO = True
diff --git a/toolkit/library/gecko.natvis b/toolkit/library/gecko.natvis
new file mode 100644
index 0000000000..dfd1da6b04
--- /dev/null
+++ b/toolkit/library/gecko.natvis
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <!-- Mozilla Gecko Visualizers -->
+
+ <Type Name="mozilla::Maybe&lt;*&gt;">
+ <DisplayString Condition="mIsSome == false">Nothing</DisplayString>
+ <DisplayString Condition="mIsSome == true">Some({*($T1 *)&amp;mStorage.val})</DisplayString>
+ <Expand>
+ <ExpandedItem Condition="mIsSome == true">*($T1 *)&amp;mStorage.val</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="mozilla::Result&lt;*,*&gt;">
+ <DisplayString>{mImpl}</DisplayString>
+ </Type>
+
+ <Type Name="mozilla::detail::ResultImplementation&lt;*,*,mozilla::detail::PackingStrategy::Variant&gt;">
+ <DisplayString Condition="mStorage.tag == false">ok: {*($T1 *)(mStorage.rawData)}</DisplayString>
+ <DisplayString Condition="mStorage.tag == true">err: {*($T2 *)(mStorage.rawData)}</DisplayString>
+ <DisplayString>%% invalid storage tag in variant %%</DisplayString>
+ <Expand>
+ <ExpandedItem Condition="mStorage.tag == false">*($T1 *)(mStorage.rawData)</ExpandedItem>
+ <ExpandedItem Condition="mStorage.tag == true">*($T2 *)(mStorage.rawData)</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <!-- nsTArray -->
+ <Type Name="nsTArray&lt;*&gt;">
+ <DisplayString Condition="mHdr-&gt;mLength == 0 &amp;&amp; mHdr-&gt;mCapacity == 0">empty</DisplayString>
+ <DisplayString Condition="mHdr-&gt;mLength == mHdr-&gt;mCapacity">size = {mHdr-&gt;mLength}</DisplayString>
+ <DisplayString>size = {mHdr-&gt;mLength}, capacity = {mHdr-&gt;mCapacity}</DisplayString>
+ <Expand>
+ <ArrayItems Condition="mHdr->mLength &gt; 0">
+ <Size>mHdr-&gt;mLength</Size>
+ <ValuePointer>($T1*)(mHdr + 1)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- refcounts -->
+ <Type Name="nsAutoRefCnt">
+ <DisplayString>{mValue}</DisplayString>
+ </Type>
+
+ <Type Name="nsCycleCollectingAutoRefCnt">
+ <!-- this value needs to be updated if NS_NUMBER_OF_FLAGS_IN_REFCNT in xpcom/glue/nsISupportsImpl.h changes -->
+ <DisplayString>{mValue >> 2}</DisplayString>
+ <Expand>
+ <Synthetic Name="In Purple Buffer"><DisplayString>{mValue &amp; 1 != 0}</DisplayString></Synthetic>
+ <Synthetic Name="Is Purple"><DisplayString>{mValue &amp; 2 != 0}</DisplayString></Synthetic>
+ </Expand>
+ </Type>
+
+ <Type Name="mozilla::ThreadSafeAutoRefCnt">
+ <DisplayString>{mValue.mValue._My_val}</DisplayString>
+ </Type>
+
+ <!-- smart pointer/refcount pointer things -->
+ <Type Name="nsRefPtr&lt;*&gt;">
+ <AlternativeType Name="nsCOMPtr&lt;*&gt;" />
+ <AlternativeType Name="nsAutoPtr&lt;*&gt;" />
+ <AlternativeType Name="mozilla::WebGLRefPtr&lt;*&gt;" />
+
+ <DisplayString Condition="mRawPtr == 0">NULL</DisplayString>
+ <DisplayString>{*($T1*)mRawPtr}</DisplayString>
+ <Expand>
+ <ExpandedItem>($T1*)mRawPtr</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <!-- strings -->
+ <Type Name="nsTString&lt;char&gt;">
+ <AlternativeType Name="nsTLiteralString&lt;char&gt;" />
+ <AlternativeType Name="mozilla::detail::nsTStringRepr&lt;char&gt;" />
+ <AlternativeType Name="nsTSubstring&lt;char&gt;" />
+
+ <DisplayString>{mData,s}</DisplayString>
+ <StringView>mData,s</StringView>
+ <Expand>
+ <Item Name="Length">mLength</Item>
+ <Item Name="Flags">mDataFlags</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="nsTSubstringTuple&lt;char&gt;">
+ <DisplayString Condition="mHead != nullptr">{mHead,na} {mFragB-&gt;mData,s}</DisplayString>
+ <DisplayString Condition="mHead == nullptr">{mFragA-&gt;mData,s} {mFragB-&gt;mData,s}</DisplayString>
+ </Type>
+
+ <Type Name="nsTString&lt;char16_t&gt;">
+ <AlternativeType Name="nsTLiteralString&lt;char16_t&gt;" />
+ <AlternativeType Name="mozilla::detail::nsTStringRepr&lt;char16_t&gt;" />
+ <AlternativeType Name="nsTSubstring&lt;char16_t&gt;" />
+
+ <DisplayString>{mData,su}</DisplayString>
+ <StringView>mData,su</StringView>
+ <Expand>
+ <Item Name="Length">mLength</Item>
+ <Item Name="Flags">mDataFlags</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="nsTSubstringTuple&lt;char16_t&gt;">
+ <DisplayString Condition="mHead != nullptr">{mHead,na} {mFragB-&gt;mData,su}</DisplayString>
+ <DisplayString Condition="mHead == nullptr">{mFragA-&gt;mData,su} {mFragB-&gt;mData,su}</DisplayString>
+ </Type>
+
+ <!-- rects, points, etc. -->
+ <Type Name="mozilla::gfx::BaseRect&lt;*,*,*,*,*&gt;">
+ <AlternativeType Name="mozilla::gfx::Rect" />
+ <DisplayString>x={x}, y={y}, width={width}, height={height}</DisplayString>
+ </Type>
+
+ <Type Name="mozilla::gfx::BaseSize&lt;*,*&gt;">
+ <AlternativeType Name="mozilla::gfx::Size" />
+ <AlternativeType Name="nsIntSize" />
+ <DisplayString>width={width}, height={height}</DisplayString>
+ </Type>
+
+ <Type Name="mozilla::gfx::BasePoint&lt;*,*&gt;">
+ <AlternativeType Name="mozilla::gfx::Point" />
+ <DisplayString>x={x}, y={y}</DisplayString>
+ </Type>
+
+ <Type Name="mozilla::gfx::Matrix4x4">
+ <AlternativeType Name="gfx3DMatrix" />
+ <DisplayString Condition="(_11==_22==_33==_44==1) &amp;&amp; (_12==_13==_14==_21==_23==_24==_31==_32==_34==_41==_42==_43==0)">[Identity]</DisplayString>
+ <DisplayString Condition="(_11==_22==_33==_44==1) &amp;&amp; (_12==_13==_14==_21==_23==_24==_31==_32==_34==0)">[Translate: ({_41}, {_42}, {_43})]</DisplayString>
+ <DisplayString Condition="_44==1 &amp;&amp; (_12==_13==_14==_21==_23==_24==_31==_32==_34==_41==_42==_43==0)">[Scale: ({_11}, {_22}, {_33})]</DisplayString>
+ <DisplayString>[4x4 Matrix]</DisplayString>
+
+ <Expand>
+ <Synthetic Name="R1"><DisplayString>[{_11}, {_12}, {_13}, {_14}]</DisplayString></Synthetic>
+ <Synthetic Name="R2"><DisplayString>[{_21}, {_22}, {_23}, {_24}]</DisplayString></Synthetic>
+ <Synthetic Name="R3"><DisplayString>[{_31}, {_32}, {_33}, {_34}]</DisplayString></Synthetic>
+ <Synthetic Name="R4"><DisplayString>[{_41}, {_42}, {_43}, {_44}]</DisplayString></Synthetic>
+ </Expand>
+ </Type>
+
+ <!-- JS types -->
+ <Type Name="JS::Handle&lt;*&gt;">
+ <DisplayString Condition="ptr == 0">NULL</DisplayString>
+ <DisplayString>{*($T1*)ptr}</DisplayString>
+ <Expand>
+ <ExpandedItem>($T1*)ptr</ExpandedItem>
+ </Expand>
+ </Type>
+
+
+</AutoVisualizer>
diff --git a/toolkit/library/gen_buildid.py b/toolkit/library/gen_buildid.py
new file mode 100644
index 0000000000..9943ad2539
--- /dev/null
+++ b/toolkit/library/gen_buildid.py
@@ -0,0 +1,41 @@
+# 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/.
+
+# -*- 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 distibuted with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+import os
+from io import StringIO
+
+import buildconfig
+from mozbuild.preprocessor import Preprocessor
+
+
+def main(output, input_file):
+ with open(input_file) as fh:
+ if buildconfig.substs["EXPAND_LIBS_LIST_STYLE"] == "linkerscript":
+
+ def cleanup(line):
+ assert line.startswith('INPUT("')
+ assert line.endswith('")')
+ return line[len('INPUT("') : -len('")')]
+
+ objs = [cleanup(l.strip()) for l in fh.readlines()]
+ else:
+ objs = [l.strip() for l in fh.readlines()]
+
+ pp = Preprocessor()
+ pp.out = StringIO()
+ pp.do_include(os.path.join(buildconfig.topobjdir, "buildid.h"))
+ buildid = pp.context["MOZ_BUILDID"]
+ output.write('extern const char gToolkitBuildID[] = "%s";' % buildid)
+ return set(
+ os.path.join("build", o)
+ for o in objs
+ if os.path.splitext(os.path.basename(o))[0] != "buildid"
+ )
diff --git a/toolkit/library/gtest/TestUCRTDepends.cpp b/toolkit/library/gtest/TestUCRTDepends.cpp
new file mode 100644
index 0000000000..a2faaf5ce3
--- /dev/null
+++ b/toolkit/library/gtest/TestUCRTDepends.cpp
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include "gtest/gtest.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Unused.h"
+#include "mozilla/WindowsVersion.h"
+#include "nsDependentString.h"
+#include "nsReadableUtils.h"
+#include "nsUnicharUtils.h"
+#include "nsWindowsHelpers.h"
+
+using namespace mozilla;
+
+constexpr const WCHAR pattern[] = L"\\api-*.dll";
+
+static LPWSTR GetModuleFileDir(HMODULE module, LPWSTR path, DWORD size) {
+ DWORD chars = GetModuleFileNameW(module, path, size);
+ if (chars <= 0 || chars >= MAX_PATH) {
+ return nullptr;
+ }
+
+ // Split the base name from the directory.
+ LPWSTR basename = wcsrchr(path, L'\\');
+ if (!basename) {
+ return nullptr; // at least one path separator must be present
+ }
+ *basename++ = L'\0';
+ return basename;
+}
+
+// Make sure that Universal CRT forwarder DLLs are not in app directory if it
+// is in Api Sets.
+TEST(TestUCRTDepends, AppDir)
+{
+ WCHAR appdir[MAX_PATH];
+ ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH));
+
+ WCHAR path[MAX_PATH + ArrayLength(pattern)];
+ swprintf(path, L"%s%s", appdir, pattern);
+
+ WIN32_FIND_DATAW wfd;
+ HANDLE hFind = FindFirstFileW(path, &wfd);
+#if defined(_M_ARM64) // We do not ship Universal CRT DLLs on aarch64.
+ if (hFind == INVALID_HANDLE_VALUE) {
+ EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_FILE_NOT_FOUND));
+ return;
+ }
+#else
+ ASSERT_NE(hFind, INVALID_HANDLE_VALUE);
+#endif
+ do {
+ nsModuleHandle module(LoadLibraryW(wfd.cFileName));
+ EXPECT_TRUE(module);
+ if (!module) {
+ continue;
+ }
+
+ // Get a full path of the loaded module.
+ LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH);
+ ASSERT_TRUE(basename);
+
+ // If the module is in Api Sets, GetModuleFileName returns the redirected
+ // DLL path, so filenames will not match.
+ bool inApiSets = wcsicmp(wfd.cFileName, basename);
+ if (IsWin10OrLater()) {
+ // All files must be in Api Sets on Windows 10.
+ EXPECT_TRUE(inApiSets);
+ continue;
+ }
+ if (IsWin8OrLater()) {
+ if (inApiSets) {
+ continue; // This file is in Api Sets, OK.
+ }
+ // Universal CRT files are not in Api Sets on Windows 8.
+ EXPECT_TRUE(StringBeginsWith(nsDependentString(wfd.cFileName),
+ u"api-ms-win-crt-"_ns,
+ nsCaseInsensitiveStringComparator));
+ } else { // Windows 7
+ // All files must not be in Api Sets on Windows 7.
+ EXPECT_FALSE(inApiSets);
+ }
+ // Files must be loaded from appdir
+ EXPECT_TRUE(!wcsicmp(path, appdir));
+ } while (FindNextFileW(hFind, &wfd));
+ EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_NO_MORE_FILES));
+ BOOL ret = FindClose(hFind);
+ EXPECT_TRUE(ret);
+}
+
+// Make sure that we do not depend on Universal CRT forwarder DLLs in the
+// system directory.
+TEST(TestUCRTDepends, SystemDir)
+{
+ WCHAR appdir[MAX_PATH];
+ ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH));
+
+ WCHAR path[MAX_PATH + ArrayLength(pattern)];
+ UINT chars = GetSystemDirectoryW(path, MAX_PATH);
+ ASSERT_TRUE(chars > 0 && chars < MAX_PATH);
+ wcscat(path, pattern);
+
+ WIN32_FIND_DATAW wfd;
+ HANDLE hFind = FindFirstFileW(path, &wfd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_FILE_NOT_FOUND));
+ EXPECT_TRUE(IsWin8OrLater());
+ return; // Not found in the system directory, OK.
+ }
+ // Api Sets forwarders must not be present on Windows 10.
+ EXPECT_FALSE(IsWin10OrLater());
+ do {
+ HMODULE module = GetModuleHandleW(wfd.cFileName);
+ if (!module) {
+ continue; // We are not using this file, OK.
+ }
+
+ // Get a full path of the loaded module.
+ LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH);
+ ASSERT_TRUE(basename);
+
+ // If the module is in Api Sets, GetModuleFileName returns the redirected
+ // DLL path, so filenames will not match.
+ if (wcsicmp(wfd.cFileName, basename)) {
+ // If this file is in Api Sets, it must not be present in appdir.
+ swprintf(path, L"%s\\%s", appdir, wfd.cFileName);
+ EXPECT_EQ(GetFileAttributesW(path), INVALID_FILE_ATTRIBUTES);
+ } else {
+ // If this file is not in Api Sets, it must be loaded from appdir.
+ EXPECT_TRUE(!wcsicmp(path, appdir));
+ }
+ } while (FindNextFileW(hFind, &wfd));
+ EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_NO_MORE_FILES));
+ BOOL ret = FindClose(hFind);
+ EXPECT_TRUE(ret);
+}
diff --git a/toolkit/library/gtest/moz.build b/toolkit/library/gtest/moz.build
new file mode 100644
index 0000000000..1a0f692bc7
--- /dev/null
+++ b/toolkit/library/gtest/moz.build
@@ -0,0 +1,26 @@
+# -*- 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/.
+
+FINAL_TARGET = "dist/bin/gtest"
+
+if CONFIG["ENABLE_TESTS"]:
+ USE_LIBS += [
+ "gkrust-gtest",
+ ]
+
+ if CONFIG["OS_ARCH"] == "WINNT":
+ UNIFIED_SOURCES += [
+ "TestUCRTDepends.cpp",
+ ]
+
+USE_LIBS += [
+ "static:xul",
+]
+
+Libxul(
+ "xul-gtest",
+ output_category=None if CONFIG["LINK_GTEST_DURING_COMPILE"] else "gtest",
+)
diff --git a/toolkit/library/gtest/rust/Cargo.toml b/toolkit/library/gtest/rust/Cargo.toml
new file mode 100644
index 0000000000..a97956ef7e
--- /dev/null
+++ b/toolkit/library/gtest/rust/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+name = "gkrust-gtest"
+version = "0.1.0"
+authors = ["The Mozilla Project Developers"]
+license = "MPL-2.0"
+description = "Testing code for libgkrust"
+
+[dependencies]
+bench-collections-gtest = { path = "../../../../xpcom/rust/gtest/bench-collections" }
+l10nregistry-ffi-gtest = { path = "../../../../intl/l10n/rust/gtest" }
+moz_task-gtest = { path = "../../../../xpcom/rust/gtest/moz_task" }
+mp4parse-gtest = { path = "../../../../dom/media/gtest" }
+nsstring-gtest = { path = "../../../../xpcom/rust/gtest/nsstring" }
+xpcom-gtest = { path = "../../../../xpcom/rust/gtest/xpcom" }
+gkrust-shared = { path = "../../rust/shared" }
+gecko-fuzz-targets = { path = "../../../../tools/fuzzing/rust", optional = true }
+fog-gtest = { path = "../../../components/glean/tests/gtest" }
+dap_ffi-gtest = { path = "../../../components/telemetry/dap/ffi-gtest" }
+dllservices-gtest = { path = "../../../xre/dllservices/tests/gtest/rust" }
+
+# Workarounds for https://github.com/rust-lang/rust/issues/58393
+mozglue-static = { path = "../../../../mozglue/static/rust" }
+swgl = { path = "../../../../gfx/wr/swgl" }
+lmdb-rkv-sys = "0.11"
+
+[lib]
+path = "lib.rs"
+crate-type = ["staticlib"]
+test = false
+doctest = false
+bench = false
+doc = false
+plugin = false
+harness = false
diff --git a/toolkit/library/gtest/rust/lib.rs b/toolkit/library/gtest/rust/lib.rs
new file mode 100644
index 0000000000..218353ee2e
--- /dev/null
+++ b/toolkit/library/gtest/rust/lib.rs
@@ -0,0 +1,16 @@
+// 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/.
+
+extern crate bench_collections_gtest;
+extern crate dap_ffi_gtest;
+extern crate fog_gtest;
+#[cfg(feature = "gecko-fuzz-targets")]
+extern crate gecko_fuzz_targets;
+extern crate gkrust_shared;
+extern crate l10nregistry_ffi_gtest;
+extern crate moz_task_gtest;
+extern crate mp4parse_gtest;
+extern crate nsstring_gtest;
+extern crate xpcom_gtest;
+extern crate dllservices_gtest;
diff --git a/toolkit/library/gtest/rust/moz.build b/toolkit/library/gtest/rust/moz.build
new file mode 100644
index 0000000000..8b98fbfda0
--- /dev/null
+++ b/toolkit/library/gtest/rust/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; c-basic-offset: 4; 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/.
+
+include("../../rust/gkrust-features.mozbuild")
+
+if CONFIG["LIBFUZZER"]:
+ gkrust_features += ["gecko-fuzz-targets"]
+
+RustLibrary(
+ "gkrust-gtest",
+ gkrust_features,
+ output_category=None if CONFIG["LINK_GTEST_DURING_COMPILE"] else "gtest",
+)
diff --git a/toolkit/library/libxul.so-gdb.py b/toolkit/library/libxul.so-gdb.py
new file mode 100644
index 0000000000..d84aead1c3
--- /dev/null
+++ b/toolkit/library/libxul.so-gdb.py
@@ -0,0 +1,35 @@
+# 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/.
+
+""" GDB Python customization auto-loader for libxul """
+
+import re
+from os.path import abspath, dirname, exists
+
+# Add the toplevel objdir to the gdb source search path.
+
+# In development builds, $objdir/dist/bin/libxul.so is a symlink to
+# $objdir/toolkit/library/build/libxul.so, and the latter path is what gdb uses
+# to search for gdb scripts.
+#
+# For artifact builds, libxul.so will be a regular file in $objdir/dist/bin.
+# Look both places.
+
+libxul_dir = dirname(__file__)
+objdir = None
+for relpath in ("../../..", "../.."):
+ objdir = abspath(libxul_dir + "/" + relpath)
+ if exists(objdir + "/build/.gdbinit"):
+ break
+else:
+ gdb.write("Warning: Gecko objdir not found\n")
+
+if objdir is not None:
+ m = re.search(r"[\w ]+: (.*)", gdb.execute("show dir", False, True))
+ if m and objdir not in m.group(1).split(":"):
+ gdb.execute("set dir {}:{}".format(objdir, m.group(1)))
+
+ # When running from a random directory, the toplevel Gecko .gdbinit may
+ # not have been loaded. Load it now.
+ gdb.execute("source -s build/.gdbinit.loader")
diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build
new file mode 100644
index 0000000000..0f9d7e95bf
--- /dev/null
+++ b/toolkit/library/moz.build
@@ -0,0 +1,417 @@
+# -*- 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/.
+
+
+@template
+def Libxul_defines():
+ LIBRARY_DEFINES["MOZILLA_INTERNAL_API"] = True
+ LIBRARY_DEFINES["IMPL_LIBXUL"] = True
+ if not CONFIG["JS_SHARED_LIBRARY"]:
+ LIBRARY_DEFINES["STATIC_EXPORTABLE_JS_API"] = True
+
+
+@template
+def Libxul(name, output_category=None):
+ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
+ # This is going to be a framework named "XUL", not an ordinary library named
+ # "libxul.dylib"
+ GeckoFramework(name, output_category=output_category, linkage=None)
+ SHARED_LIBRARY_NAME = "XUL"
+ else:
+ GeckoSharedLibrary(name, output_category=output_category, linkage=None)
+ SHARED_LIBRARY_NAME = "xul"
+
+ DELAYLOAD_DLLS += [
+ "avrt.dll",
+ "comdlg32.dll",
+ "credui.dll",
+ "d3d11.dll",
+ "D3DCompiler_47.dll",
+ "dhcpcsvc.dll",
+ "dnsapi.dll",
+ "dwmapi.dll",
+ "dxgi.dll",
+ "gdi32.dll",
+ "hid.dll",
+ "imm32.dll",
+ "iphlpapi.dll",
+ "msi.dll",
+ "msimg32.dll",
+ "netapi32.dll",
+ "ole32.dll",
+ "oleaut32.dll",
+ "secur32.dll",
+ "setupapi.dll",
+ "shell32.dll",
+ "shlwapi.dll",
+ "urlmon.dll",
+ "user32.dll",
+ "userenv.dll",
+ "usp10.dll",
+ "uxtheme.dll",
+ "wininet.dll",
+ "winmm.dll",
+ "winspool.drv",
+ "wtsapi32.dll",
+ ]
+
+ if CONFIG["ACCESSIBILITY"]:
+ DELAYLOAD_DLLS += ["oleacc.dll"]
+
+ if CONFIG["MOZ_WEBRTC"]:
+ DELAYLOAD_DLLS += ["msdmo.dll"]
+
+ if CONFIG["OS_ARCH"] == "WINNT":
+ DELAYLOAD_DLLS += [
+ "api-ms-win-core-winrt-l1-1-0.dll",
+ "api-ms-win-core-winrt-string-l1-1-0.dll",
+ ]
+
+ if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["ACCESSIBILITY"]:
+ LOCAL_INCLUDES += ["!/accessible/interfaces/gecko/"]
+
+ if CONFIG["OS_ARCH"] == "WINNT":
+ LOCAL_INCLUDES += [
+ "/widget/windows",
+ "/xpcom/base",
+ ]
+ RCINCLUDE = "/toolkit/library/xulrunner.rc"
+
+ # Show a breakdown of linker time. (Too verbose for local builds.)
+ if CONFIG["CC_TYPE"] == "clang-cl" and not CONFIG["DEVELOPER_OPTIONS"]:
+ LDFLAGS += ["-time"]
+
+ Libxul_defines()
+
+ if CONFIG["MOZ_NEEDS_LIBATOMIC"]:
+ OS_LIBS += ["atomic"]
+
+ # TouchBar-related classes are only available in the 10.12.2 SDK and later.
+ # We need to weak link these classes until we've upgraded our SDK to at
+ # least 10.12.2.
+ # We're also linking against libresolv to solve bug 1367932.
+ if CONFIG["OS_ARCH"] == "Darwin":
+ LDFLAGS += ["-Wl,-U,_OBJC_CLASS_$_NSTouchBar"]
+ LDFLAGS += ["-Wl,-U,_OBJC_CLASS_$_NSSharingServicePickerTouchBarItem"]
+ LDFLAGS += ["-Wl,-U,_OBJC_METACLASS_$_NSTouchBar"]
+ LDFLAGS += ["-Wl,-U,_OBJC_CLASS_$_NSCustomTouchBarItem"]
+ LDFLAGS += ["-Wl,-U,_OBJC_CLASS_$_NSPopoverTouchBarItem"]
+ LDFLAGS += ["-lresolv"]
+
+ if CONFIG["MOZ_DEBUG_SYMBOLS"] and CONFIG["CC_TYPE"] == "clang-cl":
+ LDFLAGS += ["-NATVIS:%s/toolkit/library/gecko.natvis" % TOPSRCDIR]
+ if CONFIG["RUSTC_NATVIS_LDFLAGS"]:
+ LDFLAGS += CONFIG["RUSTC_NATVIS_LDFLAGS"]
+
+ if CONFIG["OS_ARCH"] == "Linux" and CONFIG["OS_TARGET"] != "Android":
+ GeneratedFile(
+ "symverscript",
+ script="/build/gen_symverscript.py",
+ inputs=["../symverscript.in"],
+ flags=["xul%s" % CONFIG["MOZILLA_SYMBOLVERSION"]],
+ )
+ SYMBOLS_FILE = "!symverscript"
+
+
+# The real libxul definition is in ./build/moz.build, but we define a
+# xul library here such that # FINAL_LIBRARY = 'xul' refers to here, which
+# is then linked to both build/libxul and gtest/libxul.
+Library("xul")
+
+STATIC_LIBRARY_NAME = "xul_s"
+
+# Use a FINAL_LIBRARY for Libxul_defines to propagate from there. They wouldn't
+# propagate from here.
+FINAL_LIBRARY = "xul-real"
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ SOURCES += [
+ "nsDllMain.cpp",
+ ]
+
+LOCAL_INCLUDES += [
+ "/config",
+ # need widget/windows for resource.h (included from widget.rc)
+ "/widget/windows",
+]
+
+if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["CC_TYPE"] not in ("clang", "gcc"):
+ LOCAL_INCLUDES += [
+ "/xpcom/base",
+ ]
+
+DIRS += [
+ "build",
+ "gtest",
+]
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ DIRS += ["dummydll"]
+
+# js needs to come after xul for now, because it is an archive and its content
+# is discarded when it comes first.
+USE_LIBS += [
+ "js",
+]
+
+USE_LIBS += [
+ "lgpllibs",
+ "nspr",
+ "nss",
+ "psshparser",
+ "sqlite",
+ "zlib",
+]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
+ # The mozgtk library is a workaround that makes Gtk+ use libwayland-client
+ # instead of mozwayland. The reason it works is that by being a dependency
+ # of libxul, mozgtk appears in dependentlibs.list, preceding mozwayland
+ # (which is important and guaranteed by the USE_LIBS order in this file).
+ # That, in turn, makes firefox dlopen() mozgtk before mozwayland, which
+ # will trigger the loading of the Gtk+ libraries (mozgtk depending on them).
+ # Those libraries, if they depend on libwayland-client, will use the symbols
+ # from libwayland-client because mozwayland is not loaded yet.
+ # When eventually libxul is loaded after both mozgtk and mozwayland, it will
+ # get symbols from libwayland-client too.
+ # In the case where Gtk+ doesn't have wayland support, libwayland-client is
+ # not loaded, and libxul ends up using the mozwayland symbols.
+ USE_LIBS += [
+ "mozgtk",
+ ]
+ OS_LIBS += CONFIG["MOZ_GTK3_LIBS"]
+
+if CONFIG["MOZ_WAYLAND"]:
+ USE_LIBS += [
+ "mozwayland",
+ ]
+
+if CONFIG["MOZ_JPROF"]:
+ USE_LIBS += [
+ "jprof",
+ ]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk" or CONFIG["MOZ_TREE_FREETYPE"]:
+ USE_LIBS += [
+ "freetype",
+ ]
+
+if CONFIG["MOZ_WEBRTC"]:
+ if CONFIG["OS_TARGET"] == "WINNT":
+ OS_LIBS += [
+ "secur32",
+ "iphlpapi",
+ "strmiids",
+ "dmoguids",
+ "wmcodecdspuuid",
+ "amstrmid",
+ "msdmo",
+ "wininet",
+ ]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
+ OS_LIBS += [
+ "-framework Foundation",
+ "-framework CoreFoundation",
+ "-framework CoreLocation",
+ "-framework QuartzCore",
+ "-framework Carbon",
+ "-framework CoreAudio",
+ "-framework CoreVideo",
+ "-framework AudioToolbox",
+ "-framework AudioUnit",
+ "-framework AddressBook",
+ "-framework OpenGL",
+ "-framework Security",
+ "-framework ServiceManagement",
+ "-framework CoreServices",
+ "-framework ApplicationServices",
+ "-framework AppKit",
+ "-framework CoreMIDI",
+ "-framework SystemConfiguration",
+ "-framework AVFoundation",
+ "-framework CoreMedia",
+ "-framework IOKit",
+ "-F%s" % CONFIG["MACOS_PRIVATE_FRAMEWORKS_DIR"],
+ "-framework CoreUI",
+ "-framework CoreSymbolication",
+ "cups",
+ ]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "uikit":
+ OS_LIBS += [
+ "-framework Foundation",
+ "-framework CoreFoundation",
+ "-framework CoreGraphics",
+ "-framework CoreText",
+ "-framework AVFoundation",
+ "-framework AudioToolbox",
+ "-framework CoreMedia",
+ "-framework CoreVideo",
+ "-framework OpenGLES",
+ "-framework QuartzCore",
+ ]
+
+if CONFIG["MOZ_WMF"]:
+ OS_LIBS += [
+ "mfuuid",
+ "wmcodecdspuuid",
+ "strmiids",
+ ]
+
+if CONFIG["OS_ARCH"] == "FreeBSD":
+ OS_LIBS += [
+ "util",
+ ]
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ OS_LIBS += [
+ "crypt32",
+ "gdi32",
+ "shell32",
+ "ntdll",
+ "ole32",
+ "version",
+ "winspool",
+ "userenv",
+ "uuid",
+ ]
+
+if CONFIG["OS_ARCH"] == "Linux" and CONFIG["OS_TARGET"] != "Android":
+ OS_LIBS += [
+ "rt",
+ ]
+
+if CONFIG["MOZ_ANDROID_GOOGLE_VR"]:
+ OS_LIBS += [
+ "-L%s" % CONFIG["MOZ_ANDROID_GOOGLE_VR_LIBS"],
+ "-lgvr",
+ ]
+
+if CONFIG["MOZ_SYSTEM_JPEG"]:
+ OS_LIBS += CONFIG["MOZ_JPEG_LIBS"]
+
+if CONFIG["MOZ_SYSTEM_PNG"]:
+ OS_LIBS += CONFIG["MOZ_PNG_LIBS"]
+
+if CONFIG["MOZ_SYSTEM_WEBP"]:
+ OS_LIBS += CONFIG["MOZ_WEBP_LIBS"]
+
+if CONFIG["MOZ_SYSTEM_LIBEVENT"]:
+ OS_LIBS += CONFIG["MOZ_LIBEVENT_LIBS"]
+
+if CONFIG["MOZ_SYSTEM_LIBVPX"]:
+ OS_LIBS += CONFIG["MOZ_LIBVPX_LIBS"]
+
+if not CONFIG["MOZ_TREE_PIXMAN"]:
+ OS_LIBS += CONFIG["MOZ_PIXMAN_LIBS"]
+
+if CONFIG["HAVE_CLOCK_MONOTONIC"]:
+ OS_LIBS += CONFIG["REALTIME_LIBS"]
+
+OS_LIBS += CONFIG["ICONV_LIBS"]
+
+if CONFIG["OS_ARCH"] == "OpenBSD":
+ OS_LIBS += [
+ "sndio",
+ ]
+
+if CONFIG["MOZ_ENABLE_DBUS"]:
+ OS_LIBS += CONFIG["MOZ_DBUS_GLIB_LIBS"]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk" and CONFIG["COMPILE_ENVIRONMENT"]:
+ OS_LIBS += [l for l in CONFIG["MOZ_GTK3_LIBS"] if l not in ("-lgtk-3", "-lgdk-3")]
+ OS_LIBS += CONFIG["MOZ_X11_LIBS"]
+ OS_LIBS += CONFIG["MOZ_PANGO_LIBS"]
+
+if CONFIG["MOZ_ENABLE_LIBPROXY"]:
+ OS_LIBS += CONFIG["MOZ_LIBPROXY_LIBS"]
+
+if CONFIG["OS_ARCH"] == "FreeBSD":
+ OS_LIBS += [
+ "util",
+ ]
+
+if CONFIG["OS_ARCH"] == "Darwin":
+ OS_LIBS += [
+ # Link to Metal as required by the Metal gfx-hal backend
+ "-weak_framework Metal",
+ "-weak_framework MediaPlayer",
+ ]
+
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ OS_LIBS += [
+ "shell32",
+ "ole32",
+ "version",
+ "winspool",
+ "comdlg32",
+ "imm32",
+ "msimg32",
+ "netapi32",
+ "shlwapi",
+ "ws2_32",
+ "dnsapi",
+ "dwmapi",
+ "iphlpapi",
+ "uxtheme",
+ "setupapi",
+ "secur32",
+ "sensorsapi",
+ "portabledeviceguids",
+ "wininet",
+ "wintrust",
+ "wtsapi32",
+ "locationapi",
+ "sapi",
+ "dxguid",
+ "dhcpcsvc",
+ # gfx-rs supports D3D11 and D3D12, but we are not linking to them implicitly
+ # "d3d11", # should be explicitly linked by gfx-backend-d3d11
+ #'d3d12', # should be explicitly linked by d3d12-rs
+ "d3dcompiler",
+ ]
+
+ if CONFIG["CC_TYPE"] == "clang-cl":
+ OS_LIBS += [
+ "runtimeobject",
+ ]
+
+ if CONFIG["ACCESSIBILITY"]:
+ OS_LIBS += [
+ "oleacc",
+ ]
+
+ # Prevent winapi-rs from statically linking
+ LIBRARY_DEFINES["WINAPI_NO_BUNDLED_LIBRARIES"] = True
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
+ OS_LIBS += [
+ "usp10",
+ "oleaut32",
+ ]
+
+# The buildid is refreshed on every (incremental) build. But we want to avoid
+# rebuilding libxul every time, so instead of having a source file that
+# #include's buildid.h, which would have a dependency on it, and that would
+# thus trigger make to rebuild everything, we generate a source with the
+# buildid hard coded in it. Then we make that source file depend on all the
+# objects files that constitute libxul, so that if any of the files linked into
+# libxul is rebuilt, we refresh the buildid and link it into libxul.
+
+if CONFIG["COMPILE_ENVIRONMENT"]:
+ SOURCES += ["!buildid.cpp"]
+ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
+ libxul_list = "XUL"
+ else:
+ libxul_list = "%sxul_%s" % (
+ CONFIG["DLL_PREFIX"],
+ CONFIG["DLL_SUFFIX"].lstrip(".").replace(".", "_"),
+ )
+ GeneratedFile(
+ "buildid.cpp", script="gen_buildid.py", inputs=["!build/%s.list" % libxul_list]
+ )
diff --git a/toolkit/library/nsDllMain.cpp b/toolkit/library/nsDllMain.cpp
new file mode 100644
index 0000000000..396005b184
--- /dev/null
+++ b/toolkit/library/nsDllMain.cpp
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 <windows.h>
+#include "nsToolkit.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/WindowsVersion.h"
+
+#if defined(__GNUC__)
+// If DllMain gets name mangled, it won't be seen.
+extern "C" {
+#endif
+
+BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved) {
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ nsToolkit::Startup((HINSTANCE)hModule);
+ break;
+
+ case DLL_THREAD_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ break;
+
+ case DLL_PROCESS_DETACH:
+ nsToolkit::Shutdown();
+ break;
+ }
+
+ return TRUE;
+}
+
+#if defined(__GNUC__)
+} // extern "C"
+#endif
diff --git a/toolkit/library/rust/Cargo.toml b/toolkit/library/rust/Cargo.toml
new file mode 100644
index 0000000000..a7eee7999d
--- /dev/null
+++ b/toolkit/library/rust/Cargo.toml
@@ -0,0 +1,31 @@
+[package]
+name = "gkrust"
+version = "0.1.0"
+authors = ["The Mozilla Project Developers"]
+license = "MPL-2.0"
+description = "Rust code for libxul"
+
+[dependencies]
+gkrust-shared = { path = "shared" }
+mozilla-central-workspace-hack = { path = "../../../build/workspace-hack" }
+
+# Workarounds for https://github.com/rust-lang/rust/issues/58393
+mozglue-static = { path = "../../../mozglue/static/rust" }
+swgl = { path = "../../../gfx/wr/swgl" }
+lmdb-rkv-sys = "0.11"
+
+[dev-dependencies]
+stylo_tests = { path = "../../../servo/ports/geckolib/tests/" }
+
+[lib]
+path = "lib.rs"
+crate-type = ["staticlib"]
+test = false
+doctest = false
+bench = false
+doc = false
+plugin = false
+harness = false
+
+[package.metadata.cargo-udeps.ignore]
+normal = ["mozilla-central-workspace-hack"]
diff --git a/toolkit/library/rust/gkrust-features.mozbuild b/toolkit/library/rust/gkrust-features.mozbuild
new file mode 100644
index 0000000000..2c1c4bbd6a
--- /dev/null
+++ b/toolkit/library/rust/gkrust-features.mozbuild
@@ -0,0 +1,81 @@
+# -*- Mode: python; c-basic-offset: 4; 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/.
+
+gkrust_features = []
+
+if CONFIG['MOZ_DEBUG']:
+ gkrust_features += [
+ 'gecko_debug',
+ 'gecko_refcount_logging',
+ ]
+
+if CONFIG['MOZ_TSAN']:
+ gkrust_features += ['thread_sanitizer']
+
+if CONFIG['MOZ_WEBRENDER_DEBUGGER']:
+ gkrust_features += ['webrender_debugger']
+
+if CONFIG['MOZ_PULSEAUDIO']:
+ gkrust_features += ['cubeb_pulse_rust']
+
+if CONFIG['MOZ_AUDIOUNIT_RUST']:
+ gkrust_features += ['cubeb_coreaudio_rust']
+
+if CONFIG['MOZ_RUST_SIMD']:
+ gkrust_features += ['simd-accel']
+
+# This feature is not yet supported on all platforms, and this check needs to
+# match MOZ_CUBEB_REMOTING in CubebUtils.cpp.
+if (CONFIG['OS_ARCH'] == 'Linux' and CONFIG['OS_TARGET'] != 'Android') or CONFIG['OS_ARCH'] == 'Darwin' or CONFIG['OS_ARCH'] == 'WINNT':
+ gkrust_features += ['cubeb-remoting']
+
+if CONFIG['MOZ_MEMORY']:
+ gkrust_features += ['moz_memory']
+
+if CONFIG['MOZ_PLACES']:
+ gkrust_features += ['moz_places']
+
+if CONFIG['JS_ENABLE_SMOOSH']:
+ gkrust_features += ['smoosh']
+
+if CONFIG['MOZ_GECKO_PROFILER']:
+ gkrust_features += ['gecko_profiler']
+
+if CONFIG['MOZ_GECKO_PROFILER_PARSE_ELF']:
+ gkrust_features += ['gecko_profiler_parse_elf']
+
+if CONFIG['MOZ_BITS_DOWNLOAD']:
+ gkrust_features += ['bitsdownload']
+
+if CONFIG['LIBFUZZER']:
+ gkrust_features += ['libfuzzer']
+
+if CONFIG['MOZ_WEBRTC']:
+ gkrust_features += ['webrtc']
+
+# We need to tell Glean it is being built with Gecko.
+gkrust_features += ['glean_with_gecko']
+
+if not CONFIG['MOZILLA_OFFICIAL']:
+ gkrust_features += ['glean_disable_upload']
+
+if CONFIG['OS_TARGET'] != 'Android':
+ gkrust_features += ['glean_million_queue']
+
+if CONFIG['MOZ_ENABLE_DBUS']:
+ gkrust_features += ['with_dbus']
+
+if CONFIG["MOZ_CRASHREPORTER"] and CONFIG['MOZ_OXIDIZED_BREAKPAD']:
+ gkrust_features += ['oxidized_breakpad']
+
+if CONFIG["MOZ_WEBMIDI_MIDIR_IMPL"]:
+ gkrust_features += ['webmidi_midir_impl']
+
+if CONFIG["MOZ_UNIFFI_FIXTURES"]:
+ gkrust_features += ['uniffi_fixtures']
+
+# This must remain last.
+gkrust_features = ["gkrust-shared/%s" % f for f in gkrust_features]
diff --git a/toolkit/library/rust/lib.rs b/toolkit/library/rust/lib.rs
new file mode 100644
index 0000000000..815413a5da
--- /dev/null
+++ b/toolkit/library/rust/lib.rs
@@ -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/.
+
+// You should not be adding code to this crate; you will almost certainly
+// get link errors when linking libxul-gtest. Add any |extern crate|
+// declarations or similar to the gkrust-shared crate in
+// toolkit/library/rust/shared/lib.rs.
+extern crate gkrust_shared;
diff --git a/toolkit/library/rust/moz.build b/toolkit/library/rust/moz.build
new file mode 100644
index 0000000000..0ce6e469c6
--- /dev/null
+++ b/toolkit/library/rust/moz.build
@@ -0,0 +1,58 @@
+# -*- Mode: python; c-basic-offset: 4; 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/.
+
+include("gkrust-features.mozbuild")
+
+RustLibrary("gkrust", gkrust_features, is_gkrust=True)
+
+for feature in gkrust_features:
+ # We don't want to enable refcount logging during rusttests, since the
+ # relevant FFI symbols wouldn't be found.
+ # Nor do we want Glean to assume there are Gecko symbols.
+ if feature not in (
+ "gkrust-shared/gecko_refcount_logging",
+ "gkrust-shared/glean_with_gecko",
+ ):
+ RUST_TEST_FEATURES.append(feature)
+
+# Target directory doesn't matter a lot here, since we can't share panic=abort
+# compilation artifacts with gkrust.
+RUST_TESTS = [
+ "firefox-on-glean",
+ "l10nregistry",
+ "selectors",
+ "servo_arc",
+ "qcms",
+ # this does nothing, but is needed so that `gkrust_features` are recognized
+ # also see: https://github.com/rust-lang/cargo/issues/9856
+ "gkrust",
+]
+
+# Code coverage builds link a bunch of Gecko bindings code from the style
+# crate, which is not used by our tests but would cause link errors.
+#
+# Bug 1768874 tracks improving the setup to potentially remove these
+# altogether.
+if not CONFIG["MOZ_CODE_COVERAGE"]:
+ RUST_TESTS += ["stylo_tests"]
+ # Same happens for the style tests, except the windows linker is not great
+ # at eliminating dead code, so we end up with some missing symbols too.
+ if CONFIG["OS_TARGET"] != "WINNT":
+ RUST_TESTS += ["style"]
+
+if CONFIG["CPU_ARCH"] != "x86":
+ # malloc_size_of_derive is a build dependency, so if we are doing
+ # cross-compile for x86, this may not run correctly.
+ RUST_TESTS += ["malloc_size_of_derive"]
+
+if CONFIG["MOZ_BITS_DOWNLOAD"]:
+ RUST_TESTS += ["bits_client"]
+
+# Export the `rure` crate's included .h file. The symbols defined in that file
+# will be exported from the `gkrust-shared` crate.
+EXPORTS += [
+ "/third_party/rust/rure/include/rure.h",
+]
diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml
new file mode 100644
index 0000000000..2a63b594f4
--- /dev/null
+++ b/toolkit/library/rust/shared/Cargo.toml
@@ -0,0 +1,156 @@
+
+[package]
+name = "gkrust-shared"
+version = "0.1.0"
+authors = ["The Mozilla Project Developers"]
+license = "MPL-2.0"
+description = "Shared Rust code for libxul"
+
+[dependencies]
+moz_asserts = "0.1"
+mozglue-static = { path = "../../../../mozglue/static/rust" }
+geckoservo = { path = "../../../../servo/ports/geckolib" }
+kvstore = { path = "../../../components/kvstore" }
+lmdb-rkv-sys = { version = "0.11", features = ["mdb_idl_logn_9"] }
+mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "cf8b0e04de9c60f38f7f057f9f29c74d19336d0c", features = ["missing-pixi-permitted"] }
+nserror = { path = "../../../../xpcom/rust/nserror" }
+nsstring = { path = "../../../../xpcom/rust/nsstring" }
+netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
+xpcom = { path = "../../../../xpcom/rust/xpcom" }
+prefs_parser = { path = "../../../../modules/libpref/parser" }
+static_prefs = { path = "../../../../modules/libpref/init/static_prefs" }
+profiler_helper = { path = "../../../../tools/profiler/rust-helper", optional = true }
+mozurl = { path = "../../../../netwerk/base/mozurl" }
+webrender_bindings = { path = "../../../../gfx/webrender_bindings" }
+cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "93b5c01a131f65c83c11aeb317f4583405c5eb79", optional = true }
+cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="cf48897be5cbe147d051ebbbe1eaf5fd8fb6bbc9", optional = true, features=["pulse-dlopen"] }
+cubeb-sys = { version = "0.10.3", optional = true, features=["gecko-in-tree"] }
+audioipc2-client = { git = "https://github.com/mozilla/audioipc", rev = "0b51291d2483a17dce3e300c7784b369e02bee73", optional = true }
+audioipc2-server = { git = "https://github.com/mozilla/audioipc", rev = "0b51291d2483a17dce3e300c7784b369e02bee73", optional = true }
+encoding_glue = { path = "../../../../intl/encoding_glue" }
+authrs_bridge = { path = "../../../../dom/webauthn/authrs_bridge" }
+gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
+gecko_logger = { path = "../../../../xpcom/rust/gecko_logger" }
+rsdparsa_capi = { path = "../../../../dom/media/webrtc/sdp/rsdparsa_capi" }
+# We have these to enforce common feature sets for said crates.
+log = {version = "0.4", features = ["release_max_level_info"]}
+cose-c = { version = "0.1.5" }
+jsrust_shared = { path = "../../../../js/src/rust/shared" }
+cascade_bloom_filter = { path = "../../../components/cascade_bloom_filter" }
+cert_storage = { path = "../../../../security/manager/ssl/cert_storage" }
+crypto_hash = { path = "../../../../security/manager/ssl/crypto_hash" }
+bitsdownload = { path = "../../../components/bitsdownload", optional = true }
+storage = { path = "../../../../storage/rust" }
+bookmark_sync = { path = "../../../components/places/bookmark_sync", optional = true }
+chardetng_c = "0.1.1"
+audio_thread_priority = { version = "0.26.1", default_features = false, features = ["winapi"] }
+mdns_service = { path="../../../../dom/media/webrtc/transport/mdns_service", optional = true }
+neqo_glue = { path = "../../../../netwerk/socket/neqo_glue" }
+wgpu_bindings = { path = "../../../../gfx/wgpu_bindings" }
+mapped_hyph = { git = "https://github.com/jfkthame/mapped_hyph.git", rev = "c7651a0cffff41996ad13c44f689bd9cd2192c01" }
+fog_control = { path = "../../../components/glean" }
+app_services_logger = { path = "../../../../services/common/app_services_logger" }
+http_sfv = { path = "../../../../netwerk/base/http-sfv" }
+unic-langid = { version = "0.9", features = ["likelysubtags"] }
+unic-langid-ffi = { path = "../../../../intl/locale/rust/unic-langid-ffi" }
+fluent-langneg = { version = "0.13", features = ["cldr"] }
+fluent-langneg-ffi = { path = "../../../../intl/locale/rust/fluent-langneg-ffi" }
+oxilangtag = "0.1.3"
+oxilangtag-ffi = { path = "../../../../intl/locale/rust/oxilangtag-ffi" }
+rure = "0.2.2"
+rust_minidump_writer_linux = { path = "../../../crashreporter/rust_minidump_writer_linux", optional = true }
+gecko-profiler = { path = "../../../../tools/profiler/rust-api"}
+midir_impl = { path = "../../../../dom/midi/midir_impl", optional = true }
+dom = { path = "../../../../dom/base/rust" }
+origin-trials-ffi = { path = "../../../../dom/origin-trials/ffi" }
+jog = { path = "../../../components/glean/bindings/jog" }
+dap_ffi = { path = "../../../components/telemetry/dap/ffi" }
+data-encoding-ffi = { path = "../../../../dom/fs/parent/rust/data-encoding-ffi" }
+uniffi-example-arithmetic = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de", optional = true }
+uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de", optional = true }
+uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de", optional = true }
+uniffi-example-sprites = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de", optional = true }
+uniffi-example-todolist = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de", optional = true }
+uniffi-example-custom-types = { path = "../../../components/uniffi-example-custom-types/", optional = true }
+uniffi-fixture-callbacks = { path = "../../../components/uniffi-fixture-callbacks/", optional = true }
+uniffi-fixture-external-types = { path = "../../../components/uniffi-fixture-external-types/", optional = true }
+binary_http = { path = "../../../../netwerk/protocol/http/binary_http" }
+oblivious_http = { path = "../../../../netwerk/protocol/http/oblivious_http" }
+mime-guess-ffi = { path = "../../../../dom/fs/parent/rust/mime-guess-ffi" }
+
+# Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
+# version less than or equal to what we link to. This isn't a problem because we
+# tend to keep this up to date, but it needs to be taken into consideration when
+# changing this version.
+rusqlite = { version = "0.28.0", features = ["modern_sqlite", "in_gecko"] }
+
+fluent = { version = "0.16.0", features = ["fluent-pseudo"] }
+fluent-ffi = { path = "../../../../intl/l10n/rust/fluent-ffi" }
+l10nregistry-ffi = { path = "../../../../intl/l10n/rust/l10nregistry-ffi" }
+l10nregistry = { path = "../../../../intl/l10n/rust/l10nregistry-rs" }
+fluent-fallback = "0.7.0"
+localization-ffi = { path = "../../../../intl/l10n/rust/localization-ffi" }
+
+processtools = { path = "../../../components/processtools" }
+qcms = { path = "../../../../gfx/qcms", features = ["c_bindings", "neon"], default-features = false }
+
+wpf-gpu-raster = { git = "https://github.com/FirefoxGraphics/wpf-gpu-raster", rev = "5ab6fe33d00021325ee920b3c10526dc8301cf46" }
+aa-stroke = { git = "https://github.com/FirefoxGraphics/aa-stroke", rev = "07d3c25322518f294300e96246e09b95e118555d" }
+
+# Force url to stay at 2.1.0. See bug 1734538.
+url = "=2.1.0"
+
+# Force mio to stay at 0.8.0 to avoid windows-sys dependencies.
+mio = "=0.8.0"
+
+# Since we're building with at least rustc 1.63, enable rust 1.57 features (use of try_reserve methods).
+fallible_collections = { version = "0.4", features = ["rust_1_57"] }
+
+[target.'cfg(not(target_os = "android"))'.dependencies]
+viaduct = "0.1"
+webext_storage_bridge = { path = "../../../components/extensions/storage/webext_storage_bridge" }
+tabs = { version = "0.1" }
+
+[target.'cfg(target_os = "windows")'.dependencies]
+detect_win32k_conflicts = { path = "../../../xre/detect_win32k_conflicts" }
+
+[features]
+default = []
+moz_memory = ["mozglue-static/moz_memory"]
+cubeb-remoting = ["cubeb-sys", "audioipc2-client", "audioipc2-server"]
+cubeb_coreaudio_rust = ["cubeb-sys", "cubeb-coreaudio"]
+cubeb_pulse_rust = ["cubeb-sys", "cubeb-pulse"]
+gecko_debug = ["geckoservo/gecko_debug", "nsstring/gecko_debug"]
+gecko_refcount_logging = ["geckoservo/gecko_refcount_logging", "xpcom/gecko_refcount_logging"]
+simd-accel = ["encoding_glue/simd-accel", "jsrust_shared/simd-accel"]
+moz_places = ["bookmark_sync"]
+spidermonkey_rust = []
+smoosh = ["jsrust_shared/smoosh"]
+gecko_profiler = ["gecko-profiler/enabled", "profiler_helper"]
+gecko_profiler_parse_elf = ["profiler_helper/parse_elf"]
+libfuzzer = []
+webrtc = ["mdns_service"]
+glean_disable_upload = ["fog_control/disable_upload"]
+glean_million_queue = ["fog_control/million_queue"]
+glean_with_gecko = ["fog_control/with_gecko", "jog/with_gecko"]
+oxidized_breakpad = ["rust_minidump_writer_linux"]
+with_dbus = ["audio_thread_priority/with_dbus"]
+thread_sanitizer = ["xpcom/thread_sanitizer"]
+uniffi_fixtures = [
+ "uniffi-example-arithmetic", "uniffi-example-geometry", "uniffi-example-rondpoint", "uniffi-example-sprites",
+ "uniffi-example-todolist", "uniffi-example-custom-types", "uniffi-fixture-callbacks",
+ "uniffi-fixture-external-types",
+]
+webmidi_midir_impl = ["midir_impl"]
+
+[lib]
+path = "lib.rs"
+test = false
+doctest = false
+bench = false
+doc = false
+plugin = false
+harness = false
+
+[package.metadata.cargo-udeps.ignore]
+normal = ["moz_asserts"]
diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs
new file mode 100644
index 0000000000..6ab7e5a0bb
--- /dev/null
+++ b/toolkit/library/rust/shared/lib.rs
@@ -0,0 +1,159 @@
+// 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/.
+
+extern crate geckoservo;
+
+extern crate app_services_logger;
+#[cfg(feature = "cubeb-remoting")]
+extern crate audioipc2_client;
+#[cfg(feature = "cubeb-remoting")]
+extern crate audioipc2_server;
+extern crate authrs_bridge;
+#[cfg(feature = "bitsdownload")]
+extern crate bitsdownload;
+#[cfg(feature = "moz_places")]
+extern crate bookmark_sync;
+extern crate cascade_bloom_filter;
+extern crate cert_storage;
+extern crate crypto_hash;
+extern crate chardetng_c;
+extern crate cosec;
+#[cfg(feature = "cubeb_coreaudio_rust")]
+extern crate cubeb_coreaudio;
+#[cfg(feature = "cubeb_pulse_rust")]
+extern crate cubeb_pulse;
+extern crate encoding_glue;
+extern crate fog_control;
+extern crate gecko_profiler;
+extern crate gkrust_utils;
+extern crate http_sfv;
+extern crate jog;
+extern crate jsrust_shared;
+extern crate kvstore;
+extern crate mapped_hyph;
+extern crate mozurl;
+extern crate mp4parse_capi;
+extern crate netwerk_helper;
+extern crate nserror;
+extern crate nsstring;
+extern crate prefs_parser;
+extern crate processtools;
+#[cfg(feature = "gecko_profiler")]
+extern crate profiler_helper;
+extern crate rsdparsa_capi;
+extern crate static_prefs;
+extern crate storage;
+extern crate webrender_bindings;
+extern crate xpcom;
+
+extern crate audio_thread_priority;
+
+#[cfg(not(target_os = "android"))]
+extern crate webext_storage_bridge;
+
+#[cfg(not(target_os = "android"))]
+extern crate tabs;
+
+#[cfg(not(target_os = "android"))]
+mod reexport_tabs {
+ tabs::uniffi_reexport_scaffolding!();
+}
+
+#[cfg(feature = "webrtc")]
+extern crate mdns_service;
+extern crate neqo_glue;
+extern crate wgpu_bindings;
+
+extern crate aa_stroke;
+extern crate qcms;
+extern crate wpf_gpu_raster;
+
+extern crate unic_langid;
+extern crate unic_langid_ffi;
+
+extern crate fluent_langneg;
+extern crate fluent_langneg_ffi;
+
+extern crate fluent;
+extern crate fluent_ffi;
+
+extern crate oxilangtag_ffi;
+
+extern crate rure;
+
+extern crate fluent_fallback;
+extern crate l10nregistry_ffi;
+extern crate localization_ffi;
+
+#[cfg(not(target_os = "android"))]
+extern crate viaduct;
+
+extern crate gecko_logger;
+
+#[cfg(feature = "oxidized_breakpad")]
+extern crate rust_minidump_writer_linux;
+
+#[cfg(feature = "webmidi_midir_impl")]
+extern crate midir_impl;
+
+#[cfg(target_os = "windows")]
+extern crate detect_win32k_conflicts;
+
+extern crate origin_trials_ffi;
+
+extern crate dap_ffi;
+
+extern crate data_encoding_ffi;
+
+extern crate binary_http;
+extern crate oblivious_http;
+
+extern crate mime_guess_ffi;
+
+#[cfg(feature = "uniffi_fixtures")]
+mod uniffi_fixtures {
+ extern crate arithmetical;
+ extern crate uniffi_geometry;
+ extern crate uniffi_rondpoint;
+ extern crate uniffi_sprites;
+ extern crate uniffi_todolist;
+
+ arithmetical::uniffi_reexport_scaffolding!();
+ uniffi_fixture_callbacks::uniffi_reexport_scaffolding!();
+ uniffi_custom_types::uniffi_reexport_scaffolding!();
+ uniffi_fixture_external_types::uniffi_reexport_scaffolding!();
+ uniffi_geometry::uniffi_reexport_scaffolding!();
+ uniffi_rondpoint::uniffi_reexport_scaffolding!();
+ uniffi_sprites::uniffi_reexport_scaffolding!();
+ uniffi_todolist::uniffi_reexport_scaffolding!();
+}
+
+extern crate log;
+use log::info;
+
+use std::{ffi::CStr, os::raw::c_char};
+
+use gecko_logger::GeckoLogger;
+
+#[no_mangle]
+pub extern "C" fn GkRust_Init() {
+ // Initialize logging.
+ let _ = GeckoLogger::init();
+}
+
+#[no_mangle]
+pub extern "C" fn GkRust_Shutdown() {}
+
+/// Used to implement `nsIDebug2::RustPanic` for testing purposes.
+#[no_mangle]
+pub unsafe extern "C" fn intentional_panic(message: *const c_char) {
+ panic!("{}", CStr::from_ptr(message).to_string_lossy());
+}
+
+/// Used to implement `nsIDebug2::rustLog` for testing purposes.
+#[no_mangle]
+pub unsafe extern "C" fn debug_log(target: *const c_char, message: *const c_char) {
+ // NOTE: The `info!` log macro is used here because we have the `release_max_level_info` feature set.
+ info!(target: CStr::from_ptr(target).to_str().unwrap(), "{}", CStr::from_ptr(message).to_str().unwrap());
+}
diff --git a/toolkit/library/symverscript.in b/toolkit/library/symverscript.in
new file mode 100644
index 0000000000..ef70826ad4
--- /dev/null
+++ b/toolkit/library/symverscript.in
@@ -0,0 +1,4 @@
+#filter substitution
+@VERSION@ {
+ global: *;
+};
diff --git a/toolkit/library/xulrunner.rc b/toolkit/library/xulrunner.rc
new file mode 100644
index 0000000000..0158f6cbfc
--- /dev/null
+++ b/toolkit/library/xulrunner.rc
@@ -0,0 +1,6 @@
+/* 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 "mozilla-config.h"
+#include "widget.rc"