Alien Pastures

My thoughts on Slackware, life and everything

How Chromium is built (for now)

A short history of providing Chromium on Slackware.
I have scripted the compilation process in such a way that you can compile the Chromium sources into both chromium and chromium-ungoogled packages for Slackware using the same chromium.SlackBuild script. I compile the packages on Slackware 15.0 and use the same resulting package for both Slackware 15.0 and -current. This is a simple matter of economics – it takes half a day to compile a single package and when I can only validate and run in the evenings, every compilation effectively takes one full day.

The Google developers themselves compile these same Chromium sources into the official Chrome browser binaries using modified, customized versions of the Clang and Rust compiler toolchains to do so. They ship 64bit binaries of both those toolchains inside the Chromium source code tarballs, for both X86 and ARM architectures. No 32bit binaries have been included for a long time now. All of these binaries have been built on a somewhat older Debian release so that they are compatible with modern distros and just work.

As a Chromium packager, I can use these embedded binaries to ensure that I won’t run into source code incompatibilities, but then that only works for 64bit packages. For the 32bit packages I have always been relying on Slackware’s own 32bit versions of Clang and Rust as shipped with Slackware itself. Pat has been so kind to provide recent versions of llvm, rust and rust-bindgen for Slackware 15.0 in its ./extra and ./testing subdirectories, and he keeps doing that until today. Probably because he needs these to compile Mozilla Firefox 🙂 But hey, I profit.
Compiling Chromium using the Slackware native compilers has its own challenges but I have always found ways to deal with that.

Until now.

To compile the Chromium source code, Google has introduced a new tool, crubit, which aims to integrate the C++ and Rust ecosystems. It is a bidirectional bindings generator for C++ and Rust. In the Chromium 152 source code, only the “cc_bindings_from_rs” tool of crubit is being used, but in future also the reverse bindings counterpart “rs_bindings_from_cc” will be added.
The problem I have with this, is that Google compiled this “cc_bindings_from_rs” tool on a modern (Debian?) distro and thereby introduced a dependency on glibc 2.34. Slackware 15.0 contains glibc 2.33 and there you have it. The “cc_bindings_from_rs” program refuses to run on Slackware 15.0.
I have spent considerable time trying to compile crubit on Slackware 15.0 using either the Slackware native compilers or even Google’s own embedded compilers inside the Chromium source code, and have failed to produce a binary that works on Slackware 15.0.

Other measures were required.
The challenge I faced is two-fold:

  1. I cannot use the embedded “cc_bindings_from_rs” on Slackware 15.0
  2. I cannot compile a native Slackware version of it either

And these have multiple consequences. I can try to find a way to make that program run on Slackware 15.0 but it’s still a 64bit binary so I cannot solve the problem for the 32bit Chromium anyway if I cannot compile a native 32bit binary for “rs_bindings_from_rs“.
The way I tackled this is as follows. First I extracted a Slackware-current 64bit “aaa_glibc-solibs” package into the filesystem of my Slackware 15..0 compile box:

mkdir -p /opt/glibc-current/lib64
tar -C /opt/glibc-current/ -xf aaa_glibc-solibs-2.42-x86_64-2.txz
cd /opt/glibc-current/
rm -r install sbin usr
mv -i lib64/incoming/* lib64/
rmdir lib64/incoming

This is a one-time action. These files will remain there for future compilations. And now I have all of the newer glibc libraries (libc.so.6 and others) and the loader (ld-linux) that I need for Chromium, conveniently out of the way so that they do not affect the Slackware 15.0 system.
Then I need to convince the “rs_bindings_from_rs” tool to look at “/opt/glibc-current/lib64/” when  it wants to load glibc libraries. For this purpose, I added the following block inside the chromium.SlackBuild script.

# ---
GLIBC_COMPAT=${GLIBC_COMPAT:-/opt/glibc-current/lib64}
RUSTTC="$TMP/tmp-$PRGNAM/${SRCNAM}-${VERSION}/third_party/rust-toolchain"
CBFR="${RUSTTC}/bin/cc_bindings_from_rs"
if [ -x "$CBFR" ] && ! "$CBFR" --help >/dev/null 2>&1 ; then
  echo "-- Wrapping cc_bindings_from_rs to use $GLIBC_COMPAT."
  mv "$CBFR" "$CBFR.real"
  cat > "$CBFR" <<EOF
#!/bin/bash
exec $GLIBC_COMPAT/ld-linux-x86-64.so.2 \\
--library-path $GLIBC_COMPAT:$RUSTTC/lib \\
"$CBFR.real" "\$@"
EOF
  chmod +x "$CBFR"
  "$CBFR" --help >/dev/null 2>&1 && echo "-- cc_bindings_from_rs OK." \
  || { echo "-- ERROR: cc_bindings_from_rs still not runnable." ; exit 1 ; }
fi
# ---

What this does, is check whether the “cc_bindings_from_rs” tool actually runs (on Slackware-current it will run without issue) and if it fails because of the missing glibc symbols, create a wrapper script which ensures that the newer glibc libraries take precedence over Slackware’s own glibc, only for this particular binary. If “cc_bindings_from_rs” still fails to run, the script will abort.

This solves issue number 1.  But for a package build on 32bit Slackware 15.0 I would still need to be able to compile a native 32bit “cc_bindings_from_rs” and that’s simply not possible right now.
The solution here, is to use the 64bit toolchain embedded in the Chromium source, just like I did for the 64bit Slackware package, but then using cross-compilation on a 64bit multilib Slackware 15.0 host with 32bit as the target architecture.
Guess what… the chromium.SlackBuild is already fully prepared to perform a cross-compilation. All it needs is that you set the variable CROSS32 to the value “YES”. The Clang and Rust toolchains that are embedded in the Chromium source code are fully capable of cross-compiling. You do need to turn your 64bit Slackware host into a full multilib system following the instructions.

The command-line that compiles a 32bit chromium-ungoogled package then becomes:

CROSS32=YES BUILD_CLANG=1 USE_UNGOOGLED=1 ./chromium.SlackBuild

Hope this helps if you want to try this yourself and have been struggling with the new requirements.

Cheers, Eric

Chromium 152 – a pain to compile, so have patience (similar for LibreOffice)

Chromium 152 sources contain another major step for Google to unify their build infrastructure. Great for Google but for me it sucks.

Because unfortunately for me (and for you, the Chromium browser user) Google introduces new tools as part of their custom Rust toolchain that I am unable to compile locally as Slackware-native binaries. The “cc_bindings_from_rs” tool biting me in particular, part of the “crubit” project, also from Google.
Which means that (for now) I have to use the pre-built LLVM and Rust toolchain binaries that are embedded in the Chromium source tarball.
There’s a big ‘gotcha‘ to that now, something that was never an issue before. They have built “cc_bindings_from_rs”  on a system that is more modern than Slackware 15.0, so that this binary (and also several others as I found out) fail to run on Slackware 15.0, complaining “version `GLIBC_2.34′ not found“. As a result, the chromium.SlackBuild script fails to produce a package.

For the time being, I refuse to ditch support for Slackware 15.0 and I will keep trying to find a way to compile Chromium 152. This is galling, because I would like to spend my precious time on actually useful stuff instead of fighting Google at their own game. Still, the amount of CVE’s that is addressed by Chromium 152 is huge and I cannot ignore that.

Then LibreOffice is adding insult to injury. You might have seen in my repository’s ChangeLog.txt that I only released LibreOffice 26.8.0 as 64bit Slackware packages (15.0 and -current). I can not make the 32bit compile work here. An issue (looks like a compiler trap) which is unrelated to the Chromium problem, but it shows a troubling trend: the disregard that developers have for users of older 32bit hardware and older Operating Systems. The build of this new release simply was never properly quality-tested on 32bit.

To be continued.

Update 20260830:
For 32bit Chromium I found a solution which I documented in a separate blog article.
For 32bit LibreOffice I also found a fix, which boils down to “make sure that clang does not run out of address space on a 32bit host”. I disabled debug symbols, reduced code compilation optimizations, cranked up the stack limit and reduced the parallelism from “use all your cores” to “just four, no more”. All of this combined has indeed helped clang avoid traps and segfaults. Takes a lot longer to complete but that’s the compromise.

Slackware Forge is being abused by Chinese computer infrastructure

Unfortunately the Forge web site forge.slackware.nl is super slow today. The reason: an onslaught from many many IP addresses belonging to Chinese infrastructure. It almost feels like a DDoS attack. Every repository, every commit, every ‘blame’ page seems to be requested and the requestors are hiding that they are bots. A UserAgent containing “Edg/145.0.0.0” i.e. with a missing “e” tells it all.

I will look into installing Anubis on this server. Apologies for the degradation of the service.

Update 20260729:
I have installed Anubis to guard the gate of Forge and discourage the AI scraping bots.
It looks like the site has its responsiveness back, but I want to hear if anything in your git and CICD workflows has perhaps broken as a result. It should all still work because only the HTML page requests are being fed into Anubis. Still…

I had to fix the Slackware 15.0 git repository

Recently, and unexpectedly, I noticed a lot of errors in the output of the script which populates the git repository for Slackware. Specifically, when it updated the “15.0” branch which tracks the updates in Slackware 15.0.

I did an evening of troubleshooting and fixing. Somehow, the root user had dumped a copy of Slackware-current in the checked-out directory containing the Slackware 15.0 branch of the git repository. The script errors were caused by the inability of the non-root user running the script, to delete all the root-owned files that were suddenly there.

I was out traveling (to the ISC’26) with my team and did not have the time to fix this earlier.

Now I have fixed https://git.slackware.nl/current/log/?h=15.0 which I mirror as https://forge.slackware.nl/slackware/distrodevelopment/src/branch/15.0 by deleting the faulty commit (which contained all of Slackware-current), replaying the three good commits that came after and then salvaging the actual update from the faulty commit.
It means that the 4 new commits (actually the same commits but with a new hash) look a bit weird compared with all the others. They were manually fixed.

What this also means is: I have re-written the git history. If you cloned this repository from either of the above repository URLs (pure ‘clone’, not ‘clone –mirror’) you need to do a hard reset:

$ git fetch origin
$ git reset --hard origin/15.0
$ git fetch --prune --prune-tags origin

If you cloned this repository in the Slackware Forge, it’s considered an independent copy. It will not update of its own. You will have to sync or reset manually.

If you actually are mirroring the repository https://forge.slackware.nl/slackware/distrodevelopment then your next “git remote update” will most likely just bring your mirror back in sync without a need for further interaction.

I have also double-checked that any script that touches this git repository when doing updates is not clashing with another instance.
Sorry for any inconvenience.

Fixing the cgit configuration of git.slackware.nl

In an earlier article here on the blog, I documented how I have setup cgit to create a browseable web interface to my git repositories, most notably git.liveslak.org and git.slackware.nl.

That configuration has worked just fine for years, and you could clone a branch of a repository using the “https://” git URI and that works.

However…
Cgit is a nice graphical shell around git repositories, but it does not serve the actual git protocol.
I found out when I tried to setup a mirror of the “current” repository on the Slackware Forge. For that, I needed to perform a full clone including all branches and tags. That failed mysteriously with the error:

$ git clone https://git.slackware.nl/current
Cloning into 'current'...
error: Unable to find d8220d28e5d53cd896b28d9dea13e2258923f35a under https://git.slackware.nl/current
Cannot obtain needed object d8220d28e5d53cd896b28d9dea13e2258923f35a
while processing commit 897670f2f2e1795652dfa3da21f9879d04a9b8dc.
error: fetch failed.

At first I thought that the remote repository was damaged or corrupted,but that was ruled out by searching for the hash to see if it would actually return something else than an error. From within the bare git repositorty on the server:

# git cat-file -t d8220d28e5d53cd896b28d9dea13e2258923f35a
commit

The hash does exist and it is a commit. That rules out the corruption.
Examining those errors “unable to find under ” and “cannot obtain needed object … while processing commit …” the conclusion is that the webserver only serves the bare repository as static files over plain HTTP, with no git-http-backend smart protocol behind it.
A working “git clone” over https needs the git-http-backend configured alongside the cgit configuration in Apache. Since that backend runs as the webserver user “apache”, and the git repositories are owned by user “git”,  we need to deal with file permissions/ownership and what git considers “safe directories”. Modern git (2.35.2 and later) refuses to operate on a repository owned by a different user than the one running git, and aborts with:
fatal: detected dubious ownership in repository at '/the/path/to/current'

The final configuration that adds the “git-http-backend” protocol to the Apache webserver and also resolves the “dubious ownership” error comes in two parts.

First:
A global git configuration directive which will only be used by the Apache user so that it won’t trip over the “git” user-owned repository files.
Create the file “/etc/httpd/http-git-config” and add these lines to it:

# ---
[safe]
        directory = *
# ---

Second:
Adding a code block to the VHost definition of the git server. In my previous article I described the git.liveslak.org configuration but actually this is identical to that for git.slackware.nl.
Therefore, to the file “/etc/httpd/extra/git.slackware.nl_content.conf” we add the following right before the “SetEnv CGIT_CONFIG” line:

# ---- smart HTTP for git clients (git-http-backend) ----
# Root directory that contains the bare repositories (current.git, etc.).
SetEnv GIT_PROJECT_ROOT /local/path/to/git/repositories

# Apache trips over the git:git ownership of the repositories, so we
# need to tell git that for Apache, all repositories should be considered
# as having safe ownership:
SetEnv GIT_CONFIG_GLOBAL /etc/httpd/http-git-config

# Route ONLY the git protocol paths to git-http-backend. Everything else
# (the cgit pretty URLs) is left untouched and handled by cgit below.
# The character classes accept both SHA-1 (40 hex) and SHA-256 (64 hex)
# object names, so this keeps working When we ever migrate hash formats.
# This MUST appear before the cgit ScriptAlias in the vhost.
ScriptAliasMatch \
  "(?x)^/(.*/(HEAD | \
    info/refs | \
    objects/(info/[^/]+ | \
      [0-9a-f]{2}/[0-9a-f]{38,62} | \
      pack/pack-[0-9a-f]{40,64}\.(pack|idx)) | \
    git-(upload|receive)-pack))$" \
  /usr/libexec/git-core/git-http-backend/$1

<Directory "/usr/libexec/git-core">
    Options +ExecCGI
    Require all granted
</Directory>
# -------------------------------------------------------

Test the Apache configuration for errors after saving your changes:

# apachectl configtest

And reload the webserver gracefully (not aborting current connections):

# apachectl -k graceful

Now, let’s test the server response when we send it a request:

$ curl -sI "https://git.slackware.nl/info/refs?service=git-upload-pack" | grep -Ei 'HTTP/|Content-Type'
HTTP/1.1 200 OK
Content-Type: application/x-git-upload-pack-advertisement

The content-type of “application/x-git-upload-pack-advertisement” instead of something like “text/plain” or “octet-stream” means that we have a properly working HTTP backend for git now. Cloning the repository no longer returns an error:

$ git clone https://git.slackware.nl/current
Cloning into 'current'...
remote: Enumerating objects: 103427, done.
remote: Counting objects: 100% (103427/103427), done.
remote: Compressing objects: 100% (31583/31583), done.
remote: Total 103427 (delta 69643), reused 103103 (delta 69319), pack-reused 0 (from 0)
Receiving objects: 100% (103427/103427), 759.01 MiB | 69.60 MiB/s, done.
Resolving deltas: 100% (69643/69643), done.

This fix allowed me to mirror https://git.slackware.nl/current/ to https://forge.slackware.nl/slackware/distrodevelopment with a sync frequency of 1 hour.

« Older posts

© 2026 Alien Pastures

Theme by Anders NorenUp ↑