#!/bin/bash # $Id: librewolf.SlackBuild,v 1.1 2025/04/27 19:16:19 root Exp root $ # Copyright 2025 Eric Hameleers, Eindhoven, NL # All rights reserved. # # Permission to use, copy, modify, and distribute this software for # any purpose with or without fee is hereby granted, provided that # the above copyright notice and this permission notice appear in all # copies. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ----------------------------------------------------------------------------- # # Slackware SlackBuild script # =========================== # By: Eric Hameleers # For: librewolf # Descr: a custom version of Firefox, focused on privacy, security # URL: https://librewolf.net/ # Build needs: (Slackware 15.0) cbindgen, llvm >= 20, rust >= 1.86 # Needs: # Changelog: # 137.0.2_1-1: 27/apr/2025 by Eric Hameleers # * Initial build. # # Run 'sh librewolf.SlackBuild' to build a Slackware package. # The package (.t?z) and .txt file as well as build logs are created in /tmp . # Install the package using 'installpkg' or 'upgradepkg --install-new'. # # ----------------------------------------------------------------------------- # # This script tries to stay close to the mozilla-firefox.SlackBuild of Slackware # # ----------------------------------------------------------------------------- PRGNAM=librewolf SRCVER=${SRCVER:-137.0.2-1} VERSION=$(echo $SRCVER |tr - _) BUILD=${BUILD:-1} NUMJOBS=${NUMJOBS:-" -j$(nproc) "} TAG=${TAG:-alien} DOCS="AUTHORS LICENSE README*" # Where do we look for sources? SRCDIR=$(cd $(dirname $0); pwd) # Place to build (TMP) package (PKG) and output (OUTPUT) the program: TMP=${TMP:-/tmp/build} PKG=$TMP/package-$PRGNAM OUTPUT=${OUTPUT:-/tmp} SOURCE="$SRCDIR/${PRGNAM}-${SRCVER}.tar.gz" SRCURL="https://gitlab.com/api/v4/projects/32320088/packages/generic/${PRGNAM}-source/${SRCVER}/${PRGNAM}-${SRCVER}.source.tar.gz" # Without LANG=C, building the Python environment may fail with: # "UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 36: ordinal not in range(128)" LANG=C # Add a shell script to start the browser binary with MOZ_ALLOW_DOWNGRADE=1 # to avoid backing up (and disabling) the user profile if a browser downgrade # is detected. We made it fine for years without this feature, and all the # feedback we've seen suggests that it is causing more problems than it # solves. For example, this feature causes a profile reset trying to switch # between a 32-bit and 64-bit browser on installations that share a common # /home directory. If you want to build with the stock default behavior, set # this to something other than "YES": MOZ_ALLOW_DOWNGRADE=${MOZ_ALLOW_DOWNGRADE:-YES} # Firefox has been requiring more and more memory, especially while linking # libxul. If it fails to build natively on x86 32-bit, it can be useful to # attempt the build using an x86_64 kernel and a 32-bit userspace. Detect this # situation and set the ARCH to i686. Later in the script we'll add some # options to the .mozconfig so that the compile will do the right thing. if [ "$(uname -m)" = "x86_64" -a "$(file -L /usr/bin/gcc | grep 386 | grep 32-bit)" != "" ]; then COMPILE_X86_UNDER_X86_64=true ARCH=i686 else COMPILE_X86_UNDER_X86_64=false fi # Choose a compiler (gcc/g++ or clang/clang++): export CC=${CC:-clang} export CXX=${CXX:-clang++} # Set linker to use: if [ "$CC" = "clang" -a "$(which lld 2> /dev/null)" = "/usr/bin/lld" ]; then # Upstream default: LINKER=lld else LINKER=bfd fi # Keep memory usage as low as possible when linking: if [ ! "$LINKER" = "lld" ]; then SLKLDFLAGS=" -Wl,--as-needed -Wl,--no-keep-memory -Wl,--stats -Wl,--reduce-memory-overheads" export LDFLAGS="$SLKLDFLAGS" export MOZ_LINK_FLAGS="$SLKLDFLAGS" fi # Put Rust objects on a diet to keep the linker from running into memory # issues (especially on 32-bit): export RUSTFLAGS="-Cdebuginfo=0" ## ## --- with a little luck, you won't have to edit below this point --- ## ## # Automatically determine the architecture we're building on: if [ -z "$ARCH" ]; then case "$(uname -m)" in i?86) ARCH=i586 ;; arm*) ARCH=arm ;; # Unless $ARCH is already set, use uname -m for all other archs: *) ARCH=$(uname -m) ;; esac export ARCH fi # Set CFLAGS/CXXFLAGS and LIBDIRSUFFIX: case "$ARCH" in i?86) SLKCFLAGS="-g0" SLKLDFLAGS=""; LIBDIRSUFFIX="" ;; x86_64) SLKCFLAGS="-g0 -fPIC" SLKLDFLAGS="-L/usr/lib64"; LIBDIRSUFFIX="64" ;; arm) SLKCFLAGS="-g0 -march=armv4 -mtune=xscale" SLKLDFLAGS=""; LIBDIRSUFFIX="" ;; *) SLKCFLAGS=${SLKCFLAGS:-"-O2"} SLKLDFLAGS=${SLKLDFLAGS:-""}; LIBDIRSUFFIX=${LIBDIRSUFFIX:-""} ;; esac case "$ARCH" in arm*) TARGET=$ARCH-slackware-linux-gnueabi ;; *) TARGET=$ARCH-slackware-linux ;; esac # Exit the script on errors: set -e trap 'echo "$0 FAILED at line ${LINENO}" | tee $OUTPUT/error-${PRGNAM}.log' ERR # Catch unitialized variables: set -u P1=${1:-1} # Save old umask and set to 0022: _UMASK_=$(umask) umask 0022 # Create working directories: mkdir -p $OUTPUT # place for the package to be saved mkdir -p $TMP/tmp-$PRGNAM # location to build the source mkdir -p $PKG # place for the package to be built rm -rf $PKG/* # always erase old package's contents rm -rf $TMP/tmp-$PRGNAM/* # remove the remnants of previous build rm -rf $OUTPUT/{checkout,configure,make,install,error,makepkg,patch}-$PRGNAM.log # remove old log files # Source file availability: if ! [ -f ${SOURCE} ]; then echo "Source '$(basename ${SOURCE})' not available yet..." # Check if the $SRCDIR is writable at all - if not, download to $OUTPUT [ -w "$SRCDIR" ] || SOURCE="$OUTPUT/$(basename $SOURCE)" if [ -f ${SOURCE} ]; then echo "Ah, found it!"; continue; fi if ! [ "x${SRCURL}" == "x" ]; then echo "Will download file to $(dirname $SOURCE)" wget --no-check-certificate -nv -T 20 -O "${SOURCE}" "${SRCURL}" || true if [ $? -ne 0 -o ! -s "${SOURCE}" ]; then echo "Downloading '$(basename ${SOURCE})' failed... aborting the build." mv -f "${SOURCE}" "${SOURCE}".FAIL exit 1 fi else echo "File '$(basename ${SOURCE})' not available... aborting the build." exit 1 fi fi if [ "$P1" == "--download" ]; then echo "Download complete." exit 0 fi # --- PACKAGE BUILDING --- echo "++" echo "|| $PRGNAM-$VERSION" echo "++" cd $TMP/tmp-$PRGNAM echo "Extracting the source archive(s) for $PRGNAM..." tar -xf ${SOURCE} if [ -d source ]; then mv -i source $PRGNAM-$SRCVER ; fi cd $PRGNAM-$SRCVER chown -R root:root . chmod -R u+w,go+r-w,a+rX-st . echo Building ... export LDFLAGS="$SLKLDFLAGS" export CXXFLAGS="$SLKCFLAGS" export CFLAGS="$SLKCFLAGS" # Our building options, in a configure-like display ;) # Note: NSS/NSPR is too old on Slackware 15.0, so we use the internal version. OPTIONS="\ --with-app-name=${PRGNAM} \ --with-branding=browser/branding/${PRGNAM} \ --prefix=/usr \ --libdir=/usr/lib${LIBDIRSUFFIX} \ --with-l10n-base=$TMP/tmp-$PRGNAM/$PRGNAM-$SRCVER/lw/l10n \ --with-system-zlib \ --with-unsigned-addon-scopes=app,system \ --without-system-nss \ --without-system-nspr \ --without-wasm-sandboxed-libraries \ --allow-addon-sideload \ --enable-alsa \ --enable-application=browser \ --enable-linker=$LINKER \ --enable-optimize \ --enable-pulseaudio \ --enable-release \ --disable-bootstrap \ --disable-default-browser-agent \ --disable-strip \ --disable-install-strip \ --disable-tests \ --enable-cpp-rtti \ --enable-accessibility \ --disable-crashreporter \ --disable-debug-symbols \ --disable-debug \ --disable-elf-hack \ --disable-updater" #export MACH_USE_SYSTEM_PYTHON="1" export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=pip export CFLAGS="$SLKCFLAGS" export CXXFLAGS="$SLKCFLAGS -fno-delete-null-pointer-checks -Wno-error=c++11-narrowing-const-reference" export MOZ_MAKE_FLAGS="$NUMJOBS" export MOZBUILD_STATE_PATH="$TMP/tmp-$PRGNAM/$PRGNAM-$SRCVER/.mozbuild" export MOZ_APP_REMOTINGNAME="$PRGNAM" export MOZ_BUILD_DATE="$(date +%Y%m%d)" export MOZ_NOSPAM=1 export MOZ_REQUIRE_SIGNING= # Clear some variables that could break the build unset DBUS_SESSION_BUS_ADDRESS ORBIT_SOCKETDIR SESSION_MANAGER \ XDG_SESSION_COOKIE XAUTHORITY MAKEFLAGS # Assemble our .mozconfig, we use this method for building, seems # needed for PGO. echo ". \$topsrcdir/browser/config/mozconfig" > .mozconfig ## Mozilla devs enforce using an objdir for building ## https://developer.mozilla.org/en/Configuring_Build_Options#Building_with_an_objdir #mkdir obj #echo "mk_add_options MOZ_OBJDIR=$(pwd)/obj" >> .mozconfig # Don't phone home: cat <> .mozconfig mk_add_options MOZ_CRASHREPORTER=0 mk_add_options MOZ_DATA_REPORTING=0 mk_add_options MOZ_SERVICES_HEALTHREPORT=0 mk_add_options MOZ_TELEMETRY_REPORTING=0 EOT # Tell .mozconfig about the selected compiler: echo "export CC=\"${CC}\"" >> .mozconfig echo "export CXX=\"${CXX}\"" >> .mozconfig if [ "$COMPILE_X86_UNDER_X86_64" = "true" ]; then # Compile for i686 under an x86_64 kernel: echo "ac_add_options --host=i686-pc-linux-gnu" >> .mozconfig echo "ac_add_options --target=i686-pc-linux-gnu" >> .mozconfig fi # Add the $OPTIONS above to .mozconfig: for option in $OPTIONS; do echo "ac_add_options $option" >> .mozconfig; done # Move the original mozconfig out of the way or else mach will barf: mv -i mozconfig{,.orig} # Do a normal build (no PGO): ./mach build 2>&1 | tee $OUTPUT/make-${PRGNAM}.log ./mach buildsymbols 2>&1 | tee -a $OUTPUT/make-${PRGNAM}.log DESTDIR=$PKG ./mach install 2>&1 | tee -a $OUTPUT/install-${PRGNAM}.log # If MOZ_ALLOW_DOWNGRADE=YES, replace the /usr/bin/$PRGNAM symlink with a # shell script that sets the MOZ_ALLOW_DOWNGRADE=1 environment variable so # that a detected browser downgrade does not reset the user profile: if [ "$MOZ_ALLOW_DOWNGRADE" = "YES" ]; then rm -f $PKG/usr/bin/$PRGNAM cat << EOF > $PKG/usr/bin/$PRGNAM #!/bin/sh # # Shell script to start $PRGNAM. # # Don't reset the user profile on a detected browser downgrade: export MOZ_ALLOW_DOWNGRADE=1 # Start $PRGNAM: exec /usr/lib${LIBDIRSUFFIX}/$PRGNAM/$PRGNAM "\$@" EOF chown root:root $PKG/usr/bin/$PRGNAM chmod 755 $PKG/usr/bin/$PRGNAM fi # Fix duplicate binary, https://bugzilla.mozilla.org/show_bug.cgi?id=658850 ( cd $PKG/usr/lib$LIBDIRSUFFIX/$PRGNAM if cmp $PRGNAM $PRGNAM-bin ; then ln -sf $PRGNAM-bin $PRGNAM fi ) # Use system certificates, remove potentially embedded library: if [ -e $PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/libnssckbi.so ]; then ln -sf /usr/lib${LIBDIRSUFFIX}/libnssckbi.so \ $PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/libnssckbi.so fi # Allow for plugins: mkdir -p $PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/plugins # Need some default icons in the right place: for i in 16 32 48 64 128; do install -D -m0644 browser/branding/${PRGNAM}/default${i}.png \ $PKG/usr/share/icons/hicolor/${i}x${i}/apps/${PRGNAM}.png done install -D -m0644 ${SRCDIR}/default192x192.png \ $PKG/usr/share/icons/hicolor/192x192/apps/$${PRGNAM}.png install -D -m0644 browser/branding/${PRGNAM}/default16.png \ $PKG/usr/share/icons/hicolor/symbolic/apps/${PRGNAM}-symbolic.png # Install a desktop file (thanks to Arch Linux for the content): install -D -m0644 ${SRCDIR}/${PRGNAM}.desktop \ $PKG/usr/share/applications/${PRGNAM}.desktop # Add definition files: mkdir -p $PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/browser/defaults/preferences cat <$PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/browser/defaults/preferences/vendor.js // Use system-provided dictionaries pref("spellchecker.dictionary_path", "/usr/share/hunspell"); EOT mkdir -p $PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/distribution cat <$PKG/usr/lib${LIBDIRSUFFIX}/$PRGNAM/distribution/distribution.ini [Global] id=Built by alienBOB for Slackware version=1.0 about=LibreWolf [Preferences] app.distributor="Slackware LibreWolf Community" app.distributor.channel=$PRGNAM app.partner.librewolf=$PRGNAM EOT # Do not clobber user-modifyable content and ensure that these files are # placed in /etc/ where they belong: mkdir -p $PKG/etc/librewolf/distribution mv -i $PKG/usr/lib${LIBDIRSUFFIX}/librewolf/librewolf.cfg $PKG/etc/librewolf/librewolf.cfg.new ln -s /etc/librewolf/librewolf.cfg $PKG/usr/lib${LIBDIRSUFFIX}/librewolf/librewolf.cfg mv -i $PKG/usr/lib${LIBDIRSUFFIX}/librewolf/distribution/policies.json $PKG/etc/librewolf/distribution/policies.json.new ln -s /etc/librewolf/distribution/policies.json $PKG/usr/lib${LIBDIRSUFFIX}/librewolf/distribution/policies.json # Add this to the doinst.sh: mkdir -p $PKG/install cat <> $PKG/install/doinst.sh # Handle the incoming configuration files: config() { for infile in \$1; do NEW="\$infile" OLD="\$(dirname \$NEW)/\$(basename \$NEW .new)" # If there's no config file by that name, mv it over: if [ ! -r \$OLD ]; then mv \$NEW \$OLD elif [ "\$(cat \$OLD | md5sum)" = "\$(cat \$NEW | md5sum)" ]; then # toss the redundant copy rm \$NEW fi # Otherwise, we leave the .new copy for the admin to consider... done } preserve_perms() { NEW="\$1" OLD="\$(dirname \$NEW)/\$(basename \$NEW .new)" if [ -e \$OLD ]; then cp -a \$OLD \${NEW}.incoming cat \$NEW > \${NEW}.incoming mv \${NEW}.incoming \$NEW fi config \$NEW } config etc/librewolf/librewolf.cfg.new config etc/librewolf/distribution/policies.json.new # Update the desktop database: if [ -x usr/bin/update-desktop-database ]; then chroot . /usr/bin/update-desktop-database usr/share/applications > /dev/null 2>&1 fi # Update hicolor theme cache: if [ -d usr/share/icons/hicolor ]; then if [ -x /usr/bin/gtk-update-icon-cache ]; then chroot . /usr/bin/gtk-update-icon-cache -f -t usr/share/icons/hicolor 1> /dev/null 2> /dev/null fi fi # Update the mime database: if [ -x usr/bin/update-mime-database ]; then chroot . /usr/bin/update-mime-database usr/share/mime >/dev/null 2>&1 fi EOT # Add documentation: mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION cp -a $DOCS $PKG/usr/doc/$PRGNAM-$VERSION || true cat $SRCDIR/$(basename $0) > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild chown -R root:root $PKG/usr/doc/$PRGNAM-$VERSION find $PKG/usr/doc -type f -exec chmod 644 {} \; # Compress the man page(s): if [ -d $PKG/usr/man ]; then find $PKG/usr/man -type f -name "*.?" -exec gzip -9f {} \; for i in $(find $PKG/usr/man -type l -name "*.?") ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done fi # Strip binaries (if any): find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true # Add a package description: mkdir -p $PKG/install cat $SRCDIR/slack-desc > $PKG/install/slack-desc # Build the package: cd $PKG makepkg --linkadd y --chown n $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.${PKGTYPE:-txz} 2>&1 | tee $OUTPUT/makepkg-${PRGNAM}.log cd $OUTPUT md5sum ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.${PKGTYPE:-txz} > ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.${PKGTYPE:-txz}.md5 cd - cat $PKG/install/slack-desc | grep "^${PRGNAM}" > $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.txt # Restore the original umask: umask ${_UMASK_}