1
0
Fork 1
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-08 02:38:11 +09:00
nixpkgs/pkgs/applications/networking/browsers/firefox/common.nix

716 lines
22 KiB
Nix

{
pname,
version,
packageVersion ? version,
meta,
updateScript ? null,
binaryName ? "firefox",
application ? "browser",
applicationName ? "Firefox",
branding ? null,
requireSigning ? true,
allowAddonSideload ? false,
src,
unpackPhase ? null,
extraPatches ? [ ],
extraPostPatch ? "",
extraNativeBuildInputs ? [ ],
extraConfigureFlags ? [ ],
extraBuildInputs ? [ ],
extraMakeFlags ? [ ],
extraPassthru ? { },
tests ? { },
}:
let
# Rename the variables to prevent infinite recursion
requireSigningDefault = requireSigning;
allowAddonSideloadDefault = allowAddonSideload;
# Specifying --(dis|en)able-elf-hack on a platform for which it's not implemented will give `--disable-elf-hack is not available in this configuration`
# This is declared here because it's used in the default value of elfhackSupport
isElfhackPlatform =
stdenv:
stdenv.hostPlatform.isElf
&& (
stdenv.hostPlatform.isi686
|| stdenv.hostPlatform.isx86_64
|| stdenv.hostPlatform.isAarch32
|| stdenv.hostPlatform.isAarch64
);
in
{
lib,
pkgs,
stdenv,
patchelf,
# build time
autoconf,
cargo,
dump_syms,
makeWrapper,
mimalloc,
nodejs,
perl,
pkg-config,
pkgsCross, # wasm32 rlbox
python3,
runCommand,
rustc,
rust-cbindgen,
rustPlatform,
unzip,
which,
wrapGAppsHook3,
# runtime
bzip2,
dbus,
dbus-glib,
file,
fontconfig,
freetype,
glib,
gnum4,
gtk3,
icu73,
icu77, # if you fiddle with the icu parameters, please check Thunderbird's overrides
libGL,
libGLU,
libevent,
libffi,
libjpeg,
libpng,
libstartup_notification,
libvpx,
libwebp,
nasm,
nspr,
nss_esr,
nss_latest,
pango,
xorg,
zip,
zlib,
pkgsBuildBuild,
# Darwin
apple-sdk_14,
apple-sdk_15,
cups,
rsync, # used when preparing .app directory
# optionals
## addon signing/sideloading
requireSigning ? requireSigningDefault,
allowAddonSideload ? allowAddonSideloadDefault,
## debugging
debugBuild ? false,
# On 32bit platforms, we disable adding "-g" for easier linking.
enableDebugSymbols ? !stdenv.hostPlatform.is32bit,
## optional libraries
alsaSupport ? stdenv.hostPlatform.isLinux,
alsa-lib,
ffmpegSupport ? true,
gssSupport ? true,
libkrb5,
jackSupport ? stdenv.hostPlatform.isLinux,
libjack2,
jemallocSupport ? !stdenv.hostPlatform.isMusl,
jemalloc,
ltoSupport ? (
stdenv.hostPlatform.isLinux && stdenv.hostPlatform.is64bit && !stdenv.hostPlatform.isRiscV
),
overrideCC,
buildPackages,
pgoSupport ? (stdenv.hostPlatform.isLinux && stdenv.hostPlatform == stdenv.buildPlatform),
xvfb-run,
elfhackSupport ?
isElfhackPlatform stdenv && !(stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isAarch64),
pipewireSupport ? waylandSupport && webrtcSupport,
pulseaudioSupport ? stdenv.hostPlatform.isLinux,
libpulseaudio,
sndioSupport ? stdenv.hostPlatform.isLinux,
sndio,
waylandSupport ? !stdenv.hostPlatform.isDarwin,
libxkbcommon,
libdrm,
## privacy-related options
privacySupport ? false,
# WARNING: NEVER set any of the options below to `true` by default.
# Set to `!privacySupport` or `false`.
crashreporterSupport ?
!privacySupport
&& !stdenv.hostPlatform.isLoongArch64
&& !stdenv.hostPlatform.isRiscV
&& !stdenv.hostPlatform.isMusl,
curl,
geolocationSupport ? !privacySupport,
webrtcSupport ? !privacySupport,
# digital rights managemewnt
# This flag controls whether Firefox will show the nagbar, that allows
# users at runtime the choice to enable Widevine CDM support when a site
# requests it.
# Controlling the nagbar and widevine CDM at runtime is possible by setting
# `browser.eme.ui.enabled` and `media.gmp-widevinecdm.enabled` accordingly
drmSupport ? true,
# As stated by Sylvestre Ledru (@sylvestre) on Nov 22, 2017 at
# https://github.com/NixOS/nixpkgs/issues/31843#issuecomment-346372756 we
# have permission to use the official firefox branding.
#
# For purposes of documentation the statement of @sylvestre:
# > As the person who did part of the work described in the LWN article
# > and release manager working for Mozilla, I can confirm the statement
# > that I made in
# > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815006
# >
# > @garbas shared with me the list of patches applied for the Nix package.
# > As they are just for portability and tiny modifications, they don't
# > alter the experience of the product. In parallel, Rok also shared the
# > build options. They seem good (even if I cannot judge the quality of the
# > packaging of the underlying dependencies like sqlite, png, etc).
# > Therefor, as long as you keep the patch queue sane and you don't alter
# > the experience of Firefox users, you won't have any issues using the
# > official branding.
enableOfficialBranding ? true,
}:
assert stdenv.cc.libc or null != null;
assert
pipewireSupport
-> !waylandSupport || !webrtcSupport
-> throw "${pname}: pipewireSupport requires both wayland and webrtc support.";
assert elfhackSupport -> isElfhackPlatform stdenv;
let
inherit (lib) enableFeature;
# Target the LLVM version that rustc is built with for LTO.
llvmPackages0 = rustc.llvmPackages;
llvmPackagesBuildBuild0 = pkgsBuildBuild.rustc.llvmPackages;
# Force the use of lld and other llvm tools for LTO
llvmPackages = llvmPackages0.override {
bootBintoolsNoLibc = null;
bootBintools = null;
};
llvmPackagesBuildBuild = llvmPackagesBuildBuild0.override {
bootBintoolsNoLibc = null;
bootBintools = null;
};
# LTO requires LLVM bintools including ld.lld and llvm-ar.
buildStdenv = overrideCC llvmPackages.stdenv (
llvmPackages.stdenv.cc.override {
bintools = if ltoSupport then buildPackages.rustc.llvmPackages.bintools else stdenv.cc.bintools;
}
);
# Compile the wasm32 sysroot to build the RLBox Sandbox
# https://hacks.mozilla.org/2021/12/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/
# We only link c++ libs here, our compiler wrapper can find wasi libc and crt itself.
wasiSysRoot = runCommand "wasi-sysroot" { } ''
mkdir -p $out/lib/wasm32-wasi
for lib in ${pkgsCross.wasi32.llvmPackages.libcxx}/lib/*; do
ln -s $lib $out/lib/wasm32-wasi
done
'';
distributionIni =
let
platform = if stdenv.hostPlatform.isDarwin then "Nix on MacOS" else "NixOS";
in
pkgs.writeText "distribution.ini" (
lib.generators.toINI { } {
# Some light branding indicating this build uses our distro preferences
Global = {
id = "nixos";
version = "1.0";
about = "${applicationName} for ${platform}";
};
Preferences = {
# These values are exposed through telemetry
"app.distributor" = "nixos";
"app.distributor.channel" = "nixpkgs";
};
}
);
defaultPrefs =
if geolocationSupport then
{
"geo.provider.network.url" = {
value = "https://api.beacondb.net/v1/geolocate";
reason = "We have no Google API keys and Mozilla Location Services were retired.";
};
}
else
{
"geo.provider.use_geoclue" = {
value = false;
reason = "Geolocation support has been disabled through the `geolocationSupport` package attribute.";
};
};
defaultPrefsFile = pkgs.writeText "nixos-default-prefs.js" (
lib.concatStringsSep "\n" (
lib.mapAttrsToList (key: value: ''
// ${value.reason}
pref("${key}", ${builtins.toJSON value.value});
'') defaultPrefs
)
);
toolkit =
if stdenv.hostPlatform.isDarwin then
"cairo-cocoa"
else
"cairo-gtk3${lib.optionalString waylandSupport "-wayland"}";
in
buildStdenv.mkDerivation {
pname = "${pname}-unwrapped";
version = packageVersion;
inherit src unpackPhase meta;
outputs = [
"out"
] ++ lib.optionals crashreporterSupport [ "symbols" ];
# Add another configure-build-profiling run before the final configure phase if we build with pgo
preConfigurePhases = lib.optionals pgoSupport [
"configurePhase"
"buildPhase"
"profilingPhase"
];
patches =
lib.optionals (lib.versionAtLeast version "111" && lib.versionOlder version "133") [
./env_var_for_system_dir-ff111.patch
]
++ lib.optionals (lib.versionAtLeast version "133") [ ./env_var_for_system_dir-ff133.patch ]
++ lib.optionals (lib.versionAtLeast version "121" && lib.versionOlder version "136") [
./no-buildconfig-ffx121.patch
]
++ lib.optionals (lib.versionAtLeast version "136") [ ./no-buildconfig-ffx136.patch ]
++ lib.optionals (lib.versionAtLeast version "139") [ ./139-relax-apple-sdk.patch ]
++ lib.optionals (lib.versionOlder version "139") [
# Fix for missing vector header on macOS
# https://bugzilla.mozilla.org/show_bug.cgi?id=1959377
# Fixed on Firefox 139
./firefox-mac-missing-vector-header.patch
]
++ lib.optionals (lib.versionOlder version "140") [
# https://bugzilla.mozilla.org/show_bug.cgi?id=1962497
# https://phabricator.services.mozilla.com/D246545
# Fixed on Firefox 140
./build-fix-RELRHACK_LINKER-setting-when-linker-name-i.patch
]
++ extraPatches;
postPatch =
''
rm -rf obj-x86_64-pc-linux-gnu
patchShebangs mach build
''
# https://bugzilla.mozilla.org/show_bug.cgi?id=1927380
+ lib.optionalString (lib.versionAtLeast version "134") ''
sed -i "s/icu-i18n/icu-uc &/" js/moz.configure
''
+ extraPostPatch;
# Ignore trivial whitespace changes in patches, this fixes compatibility of
# ./env_var_for_system_dir-*.patch with Firefox >=65 without having to track
# two patches.
patchFlags = [
"-p1"
"-l"
];
# if not explicitly set, wrong cc from buildStdenv would be used
HOST_CC = "${llvmPackagesBuildBuild.stdenv.cc}/bin/cc";
HOST_CXX = "${llvmPackagesBuildBuild.stdenv.cc}/bin/c++";
nativeBuildInputs =
[
autoconf
cargo
gnum4
llvmPackagesBuildBuild.bintools
makeWrapper
nodejs
perl
python3
rust-cbindgen
rustPlatform.bindgenHook
rustc
unzip
which
wrapGAppsHook3
]
++ lib.optionals (!stdenv.hostPlatform.isDarwin) [ pkg-config ]
++ lib.optionals stdenv.hostPlatform.isDarwin [ rsync ]
++ lib.optionals stdenv.hostPlatform.isx86 [ nasm ]
++ lib.optionals crashreporterSupport [
dump_syms
patchelf
]
++ lib.optionals pgoSupport [ xvfb-run ]
++ extraNativeBuildInputs;
setOutputFlags = false; # `./mach configure` doesn't understand `--*dir=` flags.
preConfigure =
''
# Runs autoconf through ./mach configure in configurePhase
configureScript="$(realpath ./mach) configure"
# Set reproducible build date; https://bugzilla.mozilla.org/show_bug.cgi?id=885777#c21
export MOZ_BUILD_DATE=$(head -n1 sourcestamp.txt)
# Set predictable directories for build and state
export MOZ_OBJDIR=$(pwd)/objdir
export MOZBUILD_STATE_PATH=$TMPDIR/mozbuild
# Don't try to send libnotify notifications during build
export MOZ_NOSPAM=1
# Set consistent remoting name to ensure wmclass matches with desktop file
export MOZ_APP_REMOTINGNAME="${binaryName}"
# AS=as in the environment causes build failure
# https://bugzilla.mozilla.org/show_bug.cgi?id=1497286
unset AS
# Use our own python
export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system
# RBox WASM Sandboxing
export WASM_CC=${pkgsCross.wasi32.stdenv.cc}/bin/${pkgsCross.wasi32.stdenv.cc.targetPrefix}cc
export WASM_CXX=${pkgsCross.wasi32.stdenv.cc}/bin/${pkgsCross.wasi32.stdenv.cc.targetPrefix}c++
''
+ lib.optionalString pgoSupport ''
if [ -e "$TMPDIR/merged.profdata" ]; then
echo "Configuring with profiling data"
for i in "''${!configureFlagsArray[@]}"; do
if [[ ''${configureFlagsArray[i]} = "--enable-profile-generate=cross" ]]; then
unset 'configureFlagsArray[i]'
fi
done
appendToVar configureFlags --enable-profile-use=cross
appendToVar configureFlags --with-pgo-profile-path=$TMPDIR/merged.profdata
appendToVar configureFlags --with-pgo-jarlog=$TMPDIR/jarlog
${lib.optionalString stdenv.hostPlatform.isMusl ''
LDFLAGS="$OLD_LDFLAGS"
unset OLD_LDFLAGS
''}
else
echo "Configuring to generate profiling data"
configureFlagsArray+=(
"--enable-profile-generate=cross"
)
${lib.optionalString stdenv.hostPlatform.isMusl
# Set the rpath appropriately for the profiling run
# During the profiling run, loading libraries from $out would fail,
# since the profiling build has not been installed to $out
''
OLD_LDFLAGS="$LDFLAGS"
LDFLAGS="-Wl,-rpath,$(pwd)/objdir/dist/${binaryName}"
''
}
fi
''
+ lib.optionalString (enableOfficialBranding && !stdenv.hostPlatform.is32bit) ''
export MOZILLA_OFFICIAL=1
''
+ lib.optionalString (!requireSigning) ''
export MOZ_REQUIRE_SIGNING=
''
+ lib.optionalString stdenv.hostPlatform.isMusl ''
# linking firefox hits the vm.max_map_count kernel limit with the default musl allocator
# TODO: Default vm.max_map_count has been increased, retest without this
export LD_PRELOAD=${mimalloc}/lib/libmimalloc.so
'';
# firefox has a different definition of configurePlatforms from nixpkgs, see configureFlags
configurePlatforms = [ ];
configureFlags =
[
"--disable-tests"
"--disable-updater"
"--enable-application=${application}"
"--enable-default-toolkit=${toolkit}"
"--with-app-name=${binaryName}"
"--with-distribution-id=org.nixos"
"--with-libclang-path=${lib.getLib llvmPackagesBuildBuild.libclang}/lib"
"--with-wasi-sysroot=${wasiSysRoot}"
# for firefox, host is buildPlatform, target is hostPlatform
"--host=${buildStdenv.buildPlatform.config}"
"--target=${buildStdenv.hostPlatform.config}"
]
# LTO is done using clang and lld on Linux.
++ lib.optionals ltoSupport [
"--enable-lto=cross,full" # Cross-Language LTO
"--enable-linker=lld"
]
++ lib.optional (isElfhackPlatform stdenv) (enableFeature elfhackSupport "elf-hack")
++ lib.optional (!drmSupport) "--disable-eme"
++ lib.optional allowAddonSideload "--allow-addon-sideload"
++ lib.optionals (!stdenv.hostPlatform.isDarwin) [
# MacOS builds use bundled versions of libraries: https://bugzilla.mozilla.org/show_bug.cgi?id=1776255
"--enable-system-pixman"
"--with-system-ffi"
"--with-system-icu"
"--with-system-jpeg"
"--with-system-libevent"
"--with-system-libvpx"
"--with-system-nspr"
"--with-system-nss"
"--with-system-png" # needs APNG support
"--with-system-webp"
"--with-system-zlib"
# These options are not available on MacOS, even --disable-*
(enableFeature alsaSupport "alsa")
(enableFeature jackSupport "jack")
(enableFeature pulseaudioSupport "pulseaudio")
(enableFeature sndioSupport "sndio")
]
++ [
(enableFeature crashreporterSupport "crashreporter")
(enableFeature ffmpegSupport "ffmpeg")
(enableFeature geolocationSupport "necko-wifi")
(enableFeature gssSupport "negotiateauth")
(enableFeature jemallocSupport "jemalloc")
(enableFeature webrtcSupport "webrtc")
(enableFeature debugBuild "debug")
(if debugBuild then "--enable-profiling" else "--enable-optimize")
# --enable-release adds -ffunction-sections & LTO that require a big amount
# of RAM, and the 32-bit memory space cannot handle that linking
(enableFeature (!debugBuild && !stdenv.hostPlatform.is32bit) "release")
(enableFeature enableDebugSymbols "debug-symbols")
]
++ lib.optionals enableDebugSymbols [
"--disable-strip"
"--disable-install-strip"
]
# As of Firefox 137 (https://bugzilla.mozilla.org/show_bug.cgi?id=1943009),
# the --enable-official-branding flag overrides the --with-branding flag.
++ lib.optional (enableOfficialBranding && branding == null) "--enable-official-branding"
++ lib.optional (branding != null) "--with-branding=${branding}"
++ extraConfigureFlags;
buildInputs =
[
bzip2
file
libGL
libGLU
libstartup_notification
perl
zip
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
(if lib.versionAtLeast version "138" then apple-sdk_15 else apple-sdk_14)
cups
]
++ (lib.optionals (!stdenv.hostPlatform.isDarwin) (
[
dbus
dbus-glib
fontconfig
freetype
glib
gtk3
libffi
libevent
libjpeg
libpng
libvpx
libwebp
nspr
pango
xorg.libX11
xorg.libXcursor
xorg.libXdamage
xorg.libXext
xorg.libXft
xorg.libXi
xorg.libXrender
xorg.libXt
xorg.libXtst
xorg.pixman
xorg.xorgproto
zlib
(
if (lib.versionAtLeast version "129") then nss_latest else nss_esr # 3.90
)
]
++ lib.optional alsaSupport alsa-lib
++ lib.optional jackSupport libjack2
++ lib.optional pulseaudioSupport libpulseaudio # only headers are needed
++ lib.optional sndioSupport sndio
++ lib.optionals waylandSupport [
libxkbcommon
libdrm
]
))
++ [ (if (lib.versionAtLeast version "138") then icu77 else icu73) ]
++ lib.optional gssSupport libkrb5
++ lib.optional jemallocSupport jemalloc
++ extraBuildInputs;
profilingPhase = lib.optionalString pgoSupport ''
# Package up Firefox for profiling
./mach package
# Run profiling
(
export HOME=$TMPDIR
export LLVM_PROFDATA=llvm-profdata
export JARLOG_FILE="$TMPDIR/jarlog"
xvfb-run -w 10 -s "-screen 0 1920x1080x24" \
./mach python ./build/pgo/profileserver.py
)
# Copy profiling data to a place we can easily reference
cp ./merged.profdata $TMPDIR/merged.profdata
# Clean build dir
./mach clobber
'';
preBuild = ''
cd objdir
'';
postBuild = ''
cd ..
'';
makeFlags = extraMakeFlags;
separateDebugInfo = enableDebugSymbols;
enableParallelBuilding = true;
env = lib.optionalAttrs stdenv.hostPlatform.isMusl {
# Firefox relies on nonstandard behavior of the glibc dynamic linker. It re-uses
# previously loaded libraries even though they are not in the rpath of the newly loaded binary.
# On musl we have to explicitly set the rpath to include these libraries.
LDFLAGS = "-Wl,-rpath,${placeholder "out"}/lib/${binaryName}";
};
# tests were disabled in configureFlags
doCheck = false;
# Generate build symbols once after the final build
# https://firefox-source-docs.mozilla.org/crash-reporting/uploading_symbol.html
preInstall =
lib.optionalString crashreporterSupport ''
./mach buildsymbols
mkdir -p $symbols/
cp objdir/dist/*.crashreporter-symbols.zip $symbols/
''
+ ''
cd objdir
'';
# The target will prepare .app bundle
installTargets = lib.optionalString stdenv.hostPlatform.isDarwin "stage-package";
postInstall =
lib.optionalString stdenv.hostPlatform.isDarwin ''
mkdir -p $out/Applications
cp -r dist/${binaryName}/*.app "$out/Applications/${applicationName}.app"
resourceDir="$out/Applications/${applicationName}.app/Contents/Resources"
''
+ lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
# Remove SDK cruft. FIXME: move to a separate output?
rm -rf $out/share/idl $out/include $out/lib/${binaryName}-devel-*
# Needed to find Mozilla runtime
gappsWrapperArgs+=(--argv0 "$out/bin/.${binaryName}-wrapped")
resourceDir=$out/lib/${binaryName}
''
+ ''
# Install distribution customizations
install -Dvm644 ${distributionIni} "$resourceDir/distribution/distribution.ini"
install -Dvm644 ${defaultPrefsFile} "$resourceDir/browser/defaults/preferences/nixos-default-prefs.js"
cd ..
'';
postFixup = lib.optionalString (crashreporterSupport && buildStdenv.hostPlatform.isLinux) ''
patchelf --add-rpath "${lib.makeLibraryPath [ curl ]}" $out/lib/${binaryName}/crashreporter
'';
# Some basic testing
doInstallCheck = true;
installCheckPhase =
lib.optionalString buildStdenv.hostPlatform.isDarwin ''
bindir="$out/Applications/${applicationName}.app/Contents/MacOS"
''
+ lib.optionalString (!buildStdenv.hostPlatform.isDarwin) ''
bindir=$out/bin
''
+ ''
"$bindir/${binaryName}" --version
'';
passthru = {
inherit applicationName;
inherit application extraPatches;
inherit updateScript;
inherit alsaSupport;
inherit binaryName;
inherit requireSigning allowAddonSideload;
inherit jackSupport;
inherit pipewireSupport;
inherit sndioSupport;
inherit nspr;
inherit ffmpegSupport;
inherit gssSupport;
inherit tests;
inherit gtk3;
inherit wasiSysRoot;
version = packageVersion;
} // extraPassthru;
hardeningDisable = [ "format" ]; # -Werror=format-security
# the build system verifies checksums of the bundled rust sources
# ./third_party/rust is be patched by our libtool fixup code in stdenv
# unfortunately we can't just set this to `false` when we do not want it.
# See https://github.com/NixOS/nixpkgs/issues/77289 for more details
# Ideally we would figure out how to tell the build system to not
# care about changed hashes as we are already doing that when we
# fetch the sources. Any further modifications of the source tree
# is on purpose by some of our tool (or by accident and a bug?).
dontFixLibtool = true;
# on aarch64 this is also required
dontUpdateAutotoolsGnuConfigScripts = true;
requiredSystemFeatures = [ "big-parallel" ];
}