- JavaScript 66.1%
- POV-Ray SDL 14.2%
- C++ 9.9%
- CSS 5.3%
- Go 3.5%
- Other 1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| post-compile-patches | ||
| pre-compile-patches | ||
| .gitignore | ||
| conditional.go | ||
| copy.go | ||
| diff.go | ||
| fetch.go | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| marker.go | ||
| new.go | ||
| nuke.go | ||
| pref.go | ||
| README.md | ||
| replace-all.go | ||
| standard.go | ||
Spitfire Patcher
This is a custom patcher for applying modifications to Firefox source code. It processes patch files located in the `./patches` directory and applies them to files in a specified root path.
How to Use
-
Place your patch files in the
./patchesdirectory. Example of patch file:i:/browser/branding/official/configure.sh o:/browser/branding/official/configure.sh -MOZ_APP_DISPLAYNAME=Firefox +MOZ_APP_DISPLAYNAME=Spitfire -
Run the patcher with the
--pathand--patchesflags:./run.sh --path ./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin --patches ./mozilla-central/patcher/post-compile-patches
Flags
--pathPatches will be applied relative to this path.--patchesSpecifies a path to a.patchfile or a folder used by this script.--target-platformTarget OS the build is for (linux,windows...). Defaults to the host OS.--target-archTarget CPU arch (amd64,arm64, ...). Defaults to the host arch.--target-microarchTarget CPU microarch level (v2,v3,v4). Empty means baseline.--host-platformHost OS the build is running on. Defaults to the host OS.--host-archHost CPU arch. Defaults to the host arch.--host-microarchHost CPU microarch level. Empty means baseline.--channelRelease channel the build is for (release,nightly,beta). Defaults tonightly, same as the Builder.--buildComma-separated build options, e.g.pgo. Empty by default.
Platform-conditional patch directories
Any directory whose name starts with os- is only walked when its name matches the target/host.
| Form | Matches when |
|---|---|
os-<target> |
target OS matches (any libc/arch/microarch) |
os-<target>-<libc> |
target OS and libc match |
os-<target>-<libc>-<arch> |
target OS, libc and arch match |
os-<target>-<libc>-<arch>-<microarch> |
target OS, libc, arch and microarch match |
os-<target>-on-<host> |
target OS matches and host OS matches (any arch on either) |
os-<target>-<libc>-<arch>-on-<host>-<libc>-<arch> |
target and host OS+arch+libc match |
Example layout:
patches/
├── shared.patch # always applied
├── os-linux/ # any linux build (glibc or musl)
├── os-linux-glibc/ # only glibc linux builds
├── os-linux-musl-amd64/ # only musl linux x86_64
├── os-linux-amd64-v3/ # any linux x86_64 at microarch v3 (glibc or musl)
├── os-windows-amd64/ # only windows x86_64
└── os-windows-amd64-on-linux-amd64/ # only when cross-compiling windows-amd64 on a linux-amd64 host
Channel-conditional patch directories
Any directory whose name starts with channel- is only walked when its name matches --channel.
| Form | Matches when |
|---|---|
channel-nightly |
nightly builds |
channel-beta |
beta builds |
Example layout:
patches/
├── 00-mozconfig.patch # writes .mozconfig, numbered so it runs before channel-*/ (this is kinad barbaric, but it works)
├── branding-logo-unofficial.patch # release icons, always applied
├── channel-release/
│ └── mozconfig-lto.patch # --enable-lto=cross
├── channel-nightly/ # only nightly builds
│ ├── branding/ # channel-coloured icons
│ ├── branding-icons.patch # copies them over the release ones
│ └── branding-displayname.patch # "Spitfire" -> "Spitfire Nightly"
└── channel-beta/
├── branding/
├── branding-icons.patch
├── branding-displayname.patch
└── mozconfig-lto.patch
Build-option patch directories
Any directory whose name starts with build- is only walked when that option is in --build.
| Form | Matches when |
|---|---|
build-pgo |
--build pgo (the Builder passes it on --pgo) |
Example layout:
patches/
└── build-pgo/ # When --build pgo is passed
├── pgo-1-profileserver-prefs.patch
└── pgo-2-pageset-no-speedometer.patch
Parameters Explained
Here are the details of each parameter used in the patching system:
i: (Input)
-
Specifies the input file to which the patch should be applied.
-
This is the file that will be read and modified based on the patch instructions.
-
Example:
i:/browser/branding/official/configure.sh- This means the input file is located at
/browser/branding/official/configure.sh.
- This means the input file is located at
o: (Output)
-
Specifies the output file where the modified content will be saved.
-
If the input and output paths are the same, the original file will be overwritten.
-
Example:
o:/browser/branding/official/configure.sh- This means the output file is
/browser/branding/official/configure.sh.
- This means the output file is
t: (Type)
- Defines the type of patch being applied. This parameter can be skipped if not applicable.
- Common types:
-
standard: Standard patching type that follows the+(add) and-(remove) syntax.-
Used for general file modifications.
-
Supports multi-line block matching: the entire
-block must be present to be replaced by the+block. -
Example:
i: /browser/branding/official/configure.sh o: /browser/branding/official/configure.sh -MOZ_APP_DISPLAYNAME=Firefox +MOZ_APP_DISPLAYNAME=Spitfire -
Multi-line example:
t: standard i: /toolkit/moz.configure o: /toolkit/moz.configure -project_flag( - env="MOZ_APP_UA_NAME", - default="", - nargs=1, - help="application name in the User Agent string", -) +project_flag( + env="MOZ_APP_UA_NAME", + default="Firefox", + nargs=1, + help="application name in the User Agent string", +)Note: Type will fallback to t:standard when no type is specified.
-
-
pref: Indicates that the patch is modifying preference settings (e.g., Firefoxprefs.js).- When
t:prefis specified, the script will search for existing preferences in the input file and replace them with the new ones provided in the patch. If a preference is not found, it will be added to the end of the file. - Example:
t:pref i:/browser/branding/nightly/pref/firefox-branding.js o:/browser/branding/nightly/pref/firefox-branding.js +pref("extensions.getAddons.showPane", false); // HIDDEN
- When
-
new: Used for creating new files or overwriting existing files with specified content.- Creates a new file at the
o:location. - Example:
t:new o:/browser/branding/official/newfile.txt +This is a new file created by Spitfire Patcher.
- Creates a new file at the
-
copy:: Copies files or directories from the input path to the output path, overwriting if necessary.- Copies the contents of a file or directory from i: to o:.
- Example:
t:copy i:/patcher/pre-compile-patches/branding o:/browser/branding/official
-
marker: Modifies a file relative to a specific marker line.- A line starting with # defines the marker.
- Lines starting with + are inserted immediately after the marker.
- Lines starting with - are removed from the file (after the marker).
- Example:
t:marker i:/browser/locales/en-US/firefox-l10n.js o:/browser/locales/en-US/firefox-l10n.js #static const RedirEntry kRedirMap[] = + {"store", "http://localhost:20351/", + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::URI_MUST_LOAD_IN_CHILD | + nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS}, -
replace-all: Global String Replacer.- This patch type performs literal string replacements across all files under the target path.
- Unlike
standardorpref, this uses=>to define replacements and does not use+or-prefixes. - The patcher will automatically skip modifying itself (its own executable and folder).
t:replace-all i:. o:. string_to_find => string_to_replace_with -
fetch: Downloads a tarball (.tar.gz,.tar.xzor.zip) and places its contents at the output path.- The
i:field holds the tarball URL (http://orhttps://) instead of a local path. - Downloads are cached under
$XDG_CACHE_HOME/spitfire-patcher(or~/.cache/spitfire-patcher), keyed bysha256:when given, otherwise by a URL hash. - Optional modification fields:
sha256:- expected sha256 of the downloaded archive. Strongly recommended! without it the integrity check is skipped.inner:- what to extract from the archive. A/at end selects every file under that path, and copies contents intoo:. Without a/a single file is expected and copied too:.- Each
*ininner:matches one path segment and fills the next*ino:, e.g.inner: translation-abc/*/tor-browser.ftlwitho: /lang/*/toolkit/toolkit/global/tor-browser.ftl.
- Example (extract a subtree from a
.tar.gz):
t: fetch i: https://archive.torproject.org/tor-package-archive/torbrowser/15.0.13/tor-expert-bundle-linux-x86_64-15.0.13.tar.gz o: /TorBrowser/Tor sha256: 4a46209aaf37a55abd88656a3122bb04305f6cc2a0e39acef70db92485c790f9 inner: tor/ - The
-
nuke: Deletes entire function and replaces it with a constant value.- A line starting with
#is the function signature to locate. The patcher finds the first{at or after that signature and its matching}, then replaces everything between the braces. - Lines starting with
+are the replacement body. - Multiple
#blocks may appear in one patch, in any order. Repeated identical signatures map to successive occurrences in the order written. - Example (delete telemetry getter so it always returns success):
t:nuke i:/toolkit/components/telemetry/core/Telemetry.cpp o:/toolkit/components/telemetry/core/Telemetry.cpp #bool TelemetryImpl::CanRecordBase() + return false; #bool TelemetryImpl::CanRecordExtended() + return false; - A line starting with
-
diff: Applies a standard unified diff with the systempatchtool.- For drop-in patches already in
diff -u/git diffformat. Noi:/o:is used - file paths come from the diff headers. - Everything after the header lines is written to a temp file and applied with
patch -p1 --fuzz=3 --forwardrelative to--path(so-p1strips the leadinga/b/component, just like git). - Example:
t:diff --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1,3 +1,3 @@ pref("a", 1); -pref("b", 2); +pref("b", 3); pref("c", 4); - For drop-in patches already in
-
Example Patch Files
t:pref
i:/browser/firefox.js
o:/browser/spitfire.js
+pref("browser.privatebrowsing.autostart", true);
t:standard
i:/browser/app/profile/firefox.js
o:/browser/app/profile/firefox.js
-MOZ_APP_DISPLAYNAME=Firefox
+MOZ_APP_DISPLAYNAME=Spitfire
t:new
o:/browser/branding/official/new-file.txt
+Welcome to Spitfire Browser Branding.
Summary of Parameters
| Parameter | Purpose | Example |
|---|---|---|
i: |
Specifies the input file path. | i:/browser/app/profile/firefox.js |
o: |
Specifies the output file path. | o:/browser/app/profile/firefox.js |
t: |
Defines the type of patch. | t:pref, t:standard, t:new, t:marker, t:fetch, t:nuke, t:diff |
+ |
Adds a line to the output file. | +MOZ_APP_DISPLAYNAME=Spitfire |
- |
Removes a line from the input file. | -MOZ_APP_DISPLAYNAME=Firefox |
# |
Reference line: insertion point formarker, function signature for nuke. |
# 'settings', |
Workflow
- Define Input and Output: Use
i:ando:to specify which files to read and write. - Specify Patch Type: Use
t:for special handling like preference modifications. - Apply Modifications: Use
+to add lines and-to remove lines.