Every now and then I end up with an AUR package which won’t compile and when checking the respective AUR page applying a patch is recommended.
Up to now I never bothered applying patches but rather waited until the package itself got updated.
Today I ran into such a case again with ungoogled-chromium and I decided I now want to understand how patching works.
I did read up on it to some extend but must admit I am lost.
The patch is mentioned here: https://aur.archlinux.org/packages/ungoogled-chromium/
The post from user neeks shows the content of the patch and a URL.
First question is, am I supposed to copy the patch content into a file and apply it manually to the source file with the patch command or should I rather use the URL in some way?
I tried the file route
- manually create file ~/p.txt
- cd to folder with source file
- patch js-number-format.cc < ~/p.txt
but I can hardly believe this is the appropriate way, didn’t work anyway
I also read that one should modify the PKGBUILD file to apply the patch during the build process. But here again, I don’t really know what to do.
And once I managed to apply the patch I assume I either have to create the package manually or tell yay to not download/overwrite the patched file again?
Like I said, I could wait for this to resolve itself, but I’d like to understand how this works, hence it would be great if you someone could help me over the initial hurdles.
Like everything else, there is probably no single correct answer here but this is what I would do.
Before getting into specific issues with ungoogled-chromium, here is my general approach. What I would do with the patch for a package is:
Add it to the source array in the PKGBUILD
If there is a place the patch can be downloaded from, add the URL
If there isn’t, manually create the file and place it in the directory with the PKGBUILD
Add it’s checksum to the PKGBUILD
Apply the patch to the appropriate place in the PKGBUILD using patch filename < patchfile
In this specific case, there are some complications:
The patch is in code block on the internet and you need to copy/paste it. Make sure you are getting a clean paste, otherwise the patch won’t work
Even if you do get a good copy/paste, this may cause whitespace errors in the patch. Use patch -l, or the equivalent patch --ignore-whitespace, when that happens.
Since ungoogled-chromium is already a bunch of patches that get applied to the source, you need to know when to apply that patch. In this case, it is intended to be applied first, before all the other patches are applied.
If you would like, I can share what the modified PKGBUILD could look like for ungoogled-chromium.
15 minutes?!! It took hours on my side with a i5 3317U CPU. it compiled every time there was an update, horrible! I just quit using it and installed the googled one:)
I have a prior generation threadripper. I forgot that I limited my build cores so it wouldn’t make my machine unusable during a build. It is about 75% done but since it is taking longer than expected and it successfully patched, this should work:
PKGBUILD
# Maintainer: Seppia <seppia@seppio.fish>
# Contributors: Eloston
# Derived from official Chromium and Inox PKGBUILDS and ungoogled-chromium buildkit
pkgname=ungoogled-chromium
pkgver=81.0.4044.129
_rev=1
_archver=54bc225e3a263be9a6b7dc5a33c5d713d9c42716
pkgrel=${_rev}
_launcher_ver=6
pkgdesc="A lightweight approach to removing Google web service dependency"
arch=('x86_64')
url="https://github.com/Eloston/ungoogled-chromium"
license=('BSD')
depends=('gtk3' 'nss' 'alsa-lib' 'xdg-utils' 'libxss' 'libcups' 'libgcrypt'
'ttf-font' 'systemd' 'dbus' 'libpulse' 'pciutils' 'json-glib' 'libva'
'desktop-file-utils' 'hicolor-icon-theme' 'jsoncpp' 'openjpeg2')
makedepends=('python' 'python2' 'gperf' 'yasm' 'mesa' 'ninja' 'nodejs' 'git'
'clang' 'lld' 'gn' 'llvm' 'quilt')
optdepends=('pepper-flash: support for Flash content'
'kdialog: needed for file dialogs in KDE'
'gnome-keyring: for storing passwords in GNOME keyring'
'kwallet: for storing passwords in KWallet'
'libva-intel-driver: for hardware video acceleration with Intel GPUs'
'libva-mesa-driver: for hardware video acceleration with AMD/ATI GPUs'
'libva-vdpau-driver: for hardware video acceleration with NVIDIA GPUs')
provides=('chromium')
conflicts=('chromium')
source=(https://commondatastorage.googleapis.com/chromium-browser-official/chromium-$pkgver.tar.xz
chromium-launcher-$_launcher_ver.tar.gz::https://github.com/foutrelis/chromium-launcher/archive/v$_launcher_ver.tar.gz
https://github.com/Eloston/ungoogled-chromium/archive/$pkgver-$pkgrel.tar.gz
https://github.com/ungoogled-software/ungoogled-chromium-archlinux/archive/${_archver}.tar.gz
mypatch2)
sha256sums=('ff74592f83ed91c082f746c6b0a3acf384bad91f170bd24548971c17f43046d3'
'04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1'
'fda467f6f8046fc9d0f7426cf9543fcaed7da51beb367bd41f7e0407db799965'
'8d173853f02a2349cea0ef3c5a929958034b35b3e1da5dc88ea494fe482380ae'
'54f4ac909260cbef974d95a60c682328d678ab7ec2fceb40abcc97249f226c2e')
# Possible replacements are listed in build/linux/unbundle/replace_gn_files.py
# Keys are the names in the above script; values are the dependencies in Arch
declare -gA _system_libs=(
[ffmpeg]=ffmpeg
[flac]=flac
[fontconfig]=fontconfig
[freetype]=freetype2
[harfbuzz-ng]=harfbuzz
[icu]=icu
[libdrm]=
[libevent]=libevent
[libjpeg]=libjpeg
#[libpng]=libpng # https://crbug.com/752403#c10
[libvpx]=libvpx
[libwebp]=libwebp
[libxml]=libxml2
[libxslt]=libxslt
[opus]=opus
[re2]=re2
[snappy]=snappy
[yasm]=
[zlib]=minizip
)
_unwanted_bundled_libs=(
${!_system_libs[@]}
${_system_libs[libjpeg]+libjpeg_turbo}
)
depends+=(${_system_libs[@]})
prepare() {
_ungoogled_archlinux_repo="$srcdir/$pkgname-archlinux-${_archver}"
_ungoogled_repo="$srcdir/$pkgname-$pkgver-$pkgrel"
_utils="${_ungoogled_repo}/utils"
# apply our patch
patch -l $srcdir/chromium-$pkgver/v8/src/objects/js-number-format.cc < $srcdir/mypatch2
cd "$srcdir/chromium-$pkgver"
msg2 'Pruning binaries'
python "$_utils/prune_binaries.py" ./ "$_ungoogled_repo/pruning.list"
msg2 'Applying patches'
python "$_utils/patches.py" apply ./ "$_ungoogled_repo/patches" "$_ungoogled_archlinux_repo/patches"
msg2 'Applying domain substitution'
python "$_utils/domain_substitution.py" apply -r "$_ungoogled_repo/domain_regex.list" -f "$_ungoogled_repo/domain_substitution.list" -c domainsubcache.tar.gz ./
# Force script incompatible with Python 3 to use /usr/bin/python2
sed -i '1s|python$|&2|' third_party/dom_distiller_js/protoc_plugins/*.py
mkdir -p third_party/node/linux/node-linux-x64/bin
ln -s /usr/bin/node third_party/node/linux/node-linux-x64/bin/
# Remove bundled libraries for which we will use the system copies; this
# *should* do what the remove_bundled_libraries.py script does, with the
# added benefit of not having to list all the remaining libraries
local _lib
for _lib in ${_unwanted_bundled_libs[@]}; do
find -type f -path "*third_party/$_lib/*" \
\! -path "*third_party/$_lib/chromium/*" \
\! -path "*third_party/$_lib/google/*" \
\! -path './base/third_party/icu/*' \
\! -path './third_party/crashpad/crashpad/third_party/zlib/zlib_crashpad.h' \
\! -path './third_party/pdfium/third_party/freetype/include/pstables.h' \
\! -path './third_party/yasm/run_yasm.py' \
\! -regex '.*\.\(gn\|gni\|isolate\)' \
-delete
done
python2 build/linux/unbundle/replace_gn_files.py \
--system-libraries "${!_system_libs[@]}"
}
build() {
_ungoogled_archlinux_repo="$srcdir/$pkgname-archlinux-${_archver}"
_ungoogled_repo="$srcdir/$pkgname-$pkgver-$pkgrel"
make -C chromium-launcher-$_launcher_ver
cd "$srcdir/chromium-$pkgver"
if check_buildoption ccache y; then
# Avoid falling back to preprocessor mode when sources contain time macros
export CCACHE_SLOPPINESS=time_macros
fi
export CC=clang
export CXX=clang++
export AR=llvm-ar
export NM=llvm-nm
mkdir -p out/Default
# Assemble GN flags
cp "$_ungoogled_repo/flags.gn" "out/Default/args.gn"
printf '\n' >> "out/Default/args.gn"
cat "$_ungoogled_archlinux_repo/flags.archlinux.gn" >> "out/Default/args.gn"
sed -i '/use_system_libopenjpeg2=true/d' "out/Default/args.gn"
# Facilitate deterministic builds (taken from build/config/compiler/BUILD.gn)
CFLAGS+=' -Wno-builtin-macro-redefined'
CXXFLAGS+=' -Wno-builtin-macro-redefined'
CPPFLAGS+=' -D__DATE__= -D__TIME__= -D__TIMESTAMP__='
# Do not warn about unknown warning options
CFLAGS+=' -Wno-unknown-warning-option'
CXXFLAGS+=' -Wno-unknown-warning-option'
msg2 'Configuring Chromium'
gn gen out/Default --script-executable=/usr/bin/python2 --fail-on-unused-args
msg2 'Building Chromium'
ninja -C out/Default chrome chrome_sandbox chromedriver
}
package() {
cd chromium-launcher-$_launcher_ver
make PREFIX=/usr DESTDIR="$pkgdir" install
install -Dm644 LICENSE \
"$pkgdir/usr/share/licenses/chromium/LICENSE.launcher"
cd "$srcdir/chromium-$pkgver"
install -D out/Default/chrome "$pkgdir/usr/lib/chromium/chromium"
install -Dm4755 out/Default/chrome_sandbox "$pkgdir/usr/lib/chromium/chrome-sandbox"
ln -s /usr/lib/${pkgname#ungoogled-}/chromedriver "$pkgdir/usr/bin/chromedriver"
install -Dm644 chrome/installer/linux/common/desktop.template \
"$pkgdir/usr/share/applications/chromium.desktop"
install -Dm644 chrome/app/resources/manpage.1.in \
"$pkgdir/usr/share/man/man1/chromium.1"
sed -i \
-e "s/@@MENUNAME@@/Chromium/g" \
-e "s/@@PACKAGE@@/chromium/g" \
-e "s/@@USR_BIN_SYMLINK_NAME@@/chromium/g" \
"$pkgdir/usr/share/applications/chromium.desktop" \
"$pkgdir/usr/share/man/man1/chromium.1"
cp \
out/Default/{chrome_{100,200}_percent,resources}.pak \
out/Default/{*.bin,chromedriver} \
"$pkgdir/usr/lib/chromium/"
install -Dm644 -t "$pkgdir/usr/lib/chromium/locales" out/Default/locales/*.pak
if [[ -z ${_system_libs[icu]+set} ]]; then
cp out/Default/icudtl.dat "$pkgdir/usr/lib/chromium/"
fi
for size in 24 48 64 128 256; do
install -Dm644 "chrome/app/theme/chromium/product_logo_$size.png" \
"$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/chromium.png"
done
for size in 16 32; do
install -Dm644 "chrome/app/theme/default_100_percent/chromium/product_logo_$size.png" \
"$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/chromium.png"
done
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/chromium/LICENSE"
}
# vim:set ts=2 sw=2 et:
A couple of notes:
The patch is called mypatch2 but you can call it whatever you want.
Since the patch is copy/pasted, your checksum is probably going to be different than mine, you can generate a new sum with sha256sum patchfilename
If it doesn’t work, please share your error and we can figure it out. The patch happens as soon as it finishes unpacking so it will fail right away if there is a problem.
I tried with and without, didn’t change the error.
If your compiler is at 75% you probably haven’t hit file #38148 yet, let’s see if works at your end…
Also, if you look at the very beginning of the output, you should see what the patch did.
It should be right after prepare:
==> Starting prepare()...
patching file /home/dalto/garbage/src/chromium-81.0.4044.129/v8/src/objects/js-number-format.cc
patch unexpectedly ends in middle of line
Hunk #6 succeeded at 1423 with fuzz 2.
Took me a while to respond…tried all possible errors in the meantime
First I had a typo in my PKGBUILD, then I missed that the patch file needs to be added in 2 positions and finally it turned out that my PKGBUILD file got overwriten half way through
Running out of time now but will get back to it asap.
By the way, this is a really good exercise, you learn the most when things don’t work.
What did you diff that against? I didn’t look carefully, but isn’t that commit, against a later version of js-number-format.cc?
I think you could take the final version of that, diff it against what exists in src/chromium-81.0.4044.129/v8/src/objects/js-number-format.cc and then cherry pick the parts that relate to ICU.
I did remove everything in ~/.cache/yay/ungoogled-chromium, so unless this process stores data outside of that folder I think I am doing a clean build.
This is what I did:
used yay to download and extract the package again
stopped yay when it was showing the patches as it was of course not picking up the patch
modified PKGBUILD and copied my patch file to the PAKGBUILD folder
ran makepkg
got the error
My PKPGBUILD looks like below:
source=(https://commondatastorage.googleapis.com/chromium-browser-official/chromium-$pkgver.tar.xz
chromium-launcher-$_launcher_ver.tar.gz::https://github.com/foutrelis/chromium-launcher/archive/v$_launcher_ver.tar.gz
https://github.com/Eloston/ungoogled-chromium/archive/$pkgver-$pkgrel.tar.gz
https://github.com/ungoogled-software/ungoogled-chromium-archlinux/archive/${_archver}.tar.gz
p.txt)
sha256sums=('ff74592f83ed91c082f746c6b0a3acf384bad91f170bd24548971c17f43046d3'
'04917e3cd4307d8e31bfb0027a5dce6d086edb10ff8a716024fbb8bb0c7dccf1'
'fda467f6f8046fc9d0f7426cf9543fcaed7da51beb367bd41f7e0407db799965'
'8d173853f02a2349cea0ef3c5a929958034b35b3e1da5dc88ea494fe482380ae'
'56baa3f64d7cb49d90d2850d7d1ba1e5e69c1dbd8f10b1aae3d50fa1b88ac27e')
# Possible replacements are listed in build/linux/unbundle/replace_gn_files.py
# Keys are the names in the above script; values are the dependencies in Arch
declare -gA _system_libs=(
[ffmpeg]=ffmpeg
[flac]=flac
[fontconfig]=fontconfig
[freetype]=freetype2
[harfbuzz-ng]=harfbuzz
[icu]=icu
[libdrm]=
[libevent]=libevent
[libjpeg]=libjpeg
#[libpng]=libpng # https://crbug.com/752403#c10
[libvpx]=libvpx
[libwebp]=libwebp
[libxml]=libxml2
[libxslt]=libxslt
[opus]=opus
[re2]=re2
[snappy]=snappy
[yasm]=
[zlib]=minizip
)
_unwanted_bundled_libs=(
${!_system_libs[@]}
${_system_libs[libjpeg]+libjpeg_turbo}
)
depends+=(${_system_libs[@]})
prepare() {
_ungoogled_archlinux_repo="$srcdir/$pkgname-archlinux-${_archver}"
_ungoogled_repo="$srcdir/$pkgname-$pkgver-$pkgrel"
_utils="${_ungoogled_repo}/utils"
# apply our patch
patch -l $srcdir/chromium-$pkgver/v8/src/objects/js-number-format.cc < $srcdir/p.txt
cd "$srcdir/chromium-$pkgver"
msg2 'Pruning binaries'
python "$_utils/prune_binaries.py" ./ "$_ungoogled_repo/pruning.list"
msg2 'Applying patches'
python "$_utils/patches.py" apply ./ "$_ungoogled_repo/patches" "$_ungoogled_archlinux_repo/patches"
msg2 'Applying domain substitution'
python "$_utils/domain_substitution.py" apply -r "$_ungoogled_repo/domain_regex.list" -f "$_ungoogled_repo/domain_substitution.list" -c domainsubcache.tar.gz ./
# Force script incompatible with Python 3 to use /usr/bin/python2
sed -i '1s|python$|&2|' third_party/dom_distiller_js/protoc_plugins/*.py
mkdir -p third_party/node/linux/node-linux-x64/bin
ln -s /usr/bin/node third_party/node/linux/node-linux-x64/bin/
# Remove bundled libraries for which we will use the system copies; this
# *should* do what the remove_bundled_libraries.py script does, with the
# added benefit of not having to list all the remaining libraries
local _lib
for _lib in ${_unwanted_bundled_libs[@]}; do
find -type f -path "*third_party/$_lib/*" \
\! -path "*third_party/$_lib/chromium/*" \
\! -path "*third_party/$_lib/google/*" \
\! -path './base/third_party/icu/*' \
\! -path './third_party/crashpad/crashpad/third_party/zlib/zlib_crashpad.h' \
\! -path './third_party/pdfium/third_party/freetype/include/pstables.h' \
\! -path './third_party/yasm/run_yasm.py' \
\! -regex '.*\.\(gn\|gni\|isolate\)' \
-delete
done
python2 build/linux/unbundle/replace_gn_files.py \
--system-libraries "${!_system_libs[@]}"
}
build() {
_ungoogled_archlinux_repo="$srcdir/$pkgname-archlinux-${_archver}"
_ungoogled_repo="$srcdir/$pkgname-$pkgver-$pkgrel"
make -C chromium-launcher-$_launcher_ver
cd "$srcdir/chromium-$pkgver"
if check_buildoption ccache y; then
# Avoid falling back to preprocessor mode when sources contain time macros
export CCACHE_SLOPPINESS=time_macros
fi
export CC=clang
export CXX=clang++
export AR=llvm-ar
export NM=llvm-nm
mkdir -p out/Default
# Assemble GN flags
cp "$_ungoogled_repo/flags.gn" "out/Default/args.gn"
printf '\n' >> "out/Default/args.gn"
cat "$_ungoogled_archlinux_repo/flags.archlinux.gn" >> "out/Default/args.gn"
sed -i '/use_system_libopenjpeg2=true/d' "out/Default/args.gn"
# Facilitate deterministic builds (taken from build/config/compiler/BUILD.gn)
CFLAGS+=' -Wno-builtin-macro-redefined'
CXXFLAGS+=' -Wno-builtin-macro-redefined'
CPPFLAGS+=' -D__DATE__= -D__TIME__= -D__TIMESTAMP__='
# Do not warn about unknown warning options
CFLAGS+=' -Wno-unknown-warning-option'
CXXFLAGS+=' -Wno-unknown-warning-option'
msg2 'Configuring Chromium'
gn gen out/Default --script-executable=/usr/bin/python2 --fail-on-unused-args
msg2 'Building Chromium'
ninja -C out/Default chrome chrome_sandbox chromedriver
}
package() {
cd chromium-launcher-$_launcher_ver
make PREFIX=/usr DESTDIR="$pkgdir" install
install -Dm644 LICENSE \
"$pkgdir/usr/share/licenses/chromium/LICENSE.launcher"
cd "$srcdir/chromium-$pkgver"
install -D out/Default/chrome "$pkgdir/usr/lib/chromium/chromium"
install -Dm4755 out/Default/chrome_sandbox "$pkgdir/usr/lib/chromium/chrome-sandbox"
ln -s /usr/lib/${pkgname#ungoogled-}/chromedriver "$pkgdir/usr/bin/chromedriver"
install -Dm644 chrome/installer/linux/common/desktop.template \
"$pkgdir/usr/share/applications/chromium.desktop"
install -Dm644 chrome/app/resources/manpage.1.in \
"$pkgdir/usr/share/man/man1/chromium.1"
sed -i \
-e "s/@@MENUNAME@@/Chromium/g" \
-e "s/@@PACKAGE@@/chromium/g" \
-e "s/@@USR_BIN_SYMLINK_NAME@@/chromium/g" \
"$pkgdir/usr/share/applications/chromium.desktop" \
"$pkgdir/usr/share/man/man1/chromium.1"
cp \
out/Default/{chrome_{100,200}_percent,resources}.pak \
out/Default/{*.bin,chromedriver} \
"$pkgdir/usr/lib/chromium/"
install -Dm644 -t "$pkgdir/usr/lib/chromium/locales" out/Default/locales/*.pak
if [[ -z ${_system_libs[icu]+set} ]]; then
cp out/Default/icudtl.dat "$pkgdir/usr/lib/chromium/"
fi
for size in 24 48 64 128 256; do
install -Dm644 "chrome/app/theme/chromium/product_logo_$size.png" \
"$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/chromium.png"
done
for size in 16 32; do
install -Dm644 "chrome/app/theme/default_100_percent/chromium/product_logo_$size.png" \
"$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/chromium.png"
done
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/chromium/LICENSE"
}
# vim:set ts=2 sw=2 et:
At this point, some of the files were already patched. I am not sure that running makepkg again would clean them up so it probably tried to patch them again.
The simplest way is simply to take the PKGBUILD and the patch, put them in folder together and then run makepkg -i. yay is only adding complexity in this situation.
Excellent, that did the trick! Patch was picked up and it’s now compiling. I’ll report back once it’s done.
And again a few new jigsaw pieces put in place…thanks for your patience @dalto!
Edit: Spoke too quick, compilation ran extreemly fast and things got stuck again here:
Are the compiled object files stored in a tmp folder outside of .cache? This went too quick compared to the usual time.
‘sudo find / -name js-number-format.o’ didn’t return anything though.