This is the code running on the builders and the web server behind http://45.33.8.238/
Every builder runs syncbot.sh
, which in turn runs syncbot.py
in loop.
syncbot.py
is responsible for doing a single build, where a build consists
of pulling the newest version of LLVM, building it, and running tests. If
no new changes are available in LLVM's git repository, the script instead
sleeps for a while and then exits.
syncbot.sh
writes the output of syncbot.py
to a log file, and if work
was done (i.e. syncbot.py
did more than just sleep and exit), it rsync
s
the log file to the buildlog storage server.
The buildlog storage server watches for file creations in the buildlog
directories and runs annotate.py
to convert the buildlog text files to
html files every time a new log file arrives. The watching is done by the
watch.sh
script.
The html files are static files and are served as such by the web server.
The web server and the buildlog storage server happen to be the same machine at the moment.
The buildlog server currently pulls the newest version of annotate.py
before
running it, so landing changes to it takes effect immediately. (watch.sh
doesn't currently re-exec itself when it changes since it's so short. Maybe
it should, see autoupdate.sh
in this repo.)
The builders currently do not pull the newest version of syncbot.sh/py
, so
changes to it need logging in to the builders and doing something.
Each builder needs some amount of one-time manual setup.
-
Check out llvm-project from github to some directory, e.g.
~/src/llvm-project
. -
Check out this repository here to some other directory, e.g.
~/src/hack
. -
cd ~/src/llvm-project
-
Run
llvm/utils/sysroot.py make-fake --out-dir=sysroot
to create a sysroot (on macOS, this requires a full Xcode installation). -
python3 llvm/utils/gn/get.py
to download a gn binary. -
Create
out/gn
as build directory, put this inargs.gn
:llvm_targets_to_build = "all" clang_base_path = getenv("HOME") + "/src/chrome/src/third_party/llvm-build/Release+Asserts" sysroot = "//sysroot"
On Windows, use this for
clang_base_path
instead:clang_base_path = "C:/src/chrome/src/third_party/llvm-build/Release+Asserts"
-
Run
llvm/utils/gn/gn.py gen out/gn
to create the initial build files. -
On Windows, most of the build runs natively, but rsync needs a cygwin-like environment, and since it's needed for that anyways, syncbot.sh runs in it too. It's easiest to use a
git bash
shell. To addrsync
to it, grab rsync off the msys2 repo and put it indirname $(cygpath -w $(which ls))
(justbin/rsync.exe
is enough). -
On non-Windows, run
git config core.trustctime false
in the llvm checkout. The GN build uses hardlinks to copy files, which changes the ctime on the copy source inode. By default,git checkout -f main
will replace files with modified ctime with a new copy of the file, which in turn changes the mtime on the copy inputs -- which makes ninja think copy steps are dirty and need to be rerun on every build. This setting fixes this. More information. -
On macOS, in System Preferences→Energy Saver, make sure "Prevent computer from sleeping automatically when the display is off" is checked.
-
Create
~/.ssh/id_rsa.pub
if necessary by runningssh-keygen -t rsa
, then copy it to the buildlog server withcat ~/.ssh/id_rsa.pub | ssh [email protected] 'cat >> .ssh/authorized_keys'
-
On the linux bot, run
git config user.email [email protected]
andgit config user.name "LLVM GN Syncbot"
in the LLVM checkout used by the bot. -
On the linux bot, generate a second public key with
ssh-keygen -t rsa -f ~/.ssh -f ~/.ssh/llvmgnsyncbot_id_rsa
, and add the.pub
file contents as SSH key on https://github.com/settings/keys for the llvmgnsyncbot github account. Rungit config core.sshCommand "ssh -i ~/.ssh/llvmgnsyncbot_id_rsa"
in the LLVM checkout used by the bot. If the checkout is using https, rungit remote set-url origin [email protected]:llvm/llvm-project.git
to move to SSH. -
In a tmux or screen session, or a CRD window, run
../hack/llvmgnsyncbot/syncbot.sh
while in the LLVM checkout. Then disconnect from the builder. -
To automatically start the sync script after reboots:
On linux, create a file in your home directory containing this script (with paths adjusted), run
chmod +x
on it, and add it tocrontab -e
as described in the script:#!/bin/bash # Put this in your `crontab -e`: # # @reboot /home/botusername/syncbotcron.sh /bin/sleep 4 # Wait a bit for the network to come up. /usr/bin/tmux new-session -d -s gnsyncbot /usr/bin/tmux send-keys -t gnsyncbot "cd /home/botusername" C-m # Get depot_tools on path (for ninja, ...) /usr/bin/tmux send-keys -t gnsyncbot "source ./.bashrc" C-m /usr/bin/tmux send-keys -t gnsyncbot "cd src/llvm-project" C-m /usr/bin/tmux send-keys -t gnsyncbot "../hack/llvmgnsyncbot/syncbot.sh" C-m
On macOS, the default shell is
zsh
andtmux
isn't preinstalled butscreen
is. Use this script instead (with paths adjusted), runchmod +x
on it, and start it via launchd (see below for how):#!/bin/bash # Start via ~/Library/LaunchAgents/start-gnbot.plist, see below. /bin/sleep 4 # Wait a bit for the network to come up. /usr/bin/screen -dmS gnsyncbot /usr/bin/screen -S gnsyncbot -X stuff $'cd /Users/botusername\n' # Get depot_tools on path (for ninja, ...) /usr/bin/screen -S gnsyncbot -X stuff $'source ./.zshrc\n' /usr/bin/screen -S gnsyncbot -X stuff $'cd src/llvm-project\n' /usr/bin/screen -S gnsyncbot -X stuff $'../hack/llvmgnsyncbot/syncbot.sh\n'
Things started with
@reboot
from crontab end up in some scheduling class where they don't get access to performance cores on Apple Silicon, so start it via launchd:% cat ~/Library/LaunchAgents/start-gnbot.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>start-gnbot</string> <key>ProgramArguments</key> <array><string>/Users/thakis/syncbotcron.sh</string></array> <key>RunAtLoad</key> <true/> </dict> </plist>
Open System Preferences→Users & Groups→Login Options and make sure "Automatic login:" is enabled for that user.
Create a user llvm
, and create ~llvm/buildlog
. The builders will rsync build
logs to ~llvm/buildlog/{linux,mac,win}
.
Check out this repository as llvm to ~llvm/hack
.
To run annotate.py
automatically every time a file appears, run
hack/llvmgnsyncbot/watch.sh buildlog html hack > watch.out 2> watch.err < /dev/null &
followed by disown -h
.
annotate.py
then writes static html files to ~llvm/html
.
Create symlinks in /var/www/html
to these two directories.
The webserver runs nginx in the default debian configuration.
/etc/nginx/sites-enabled/default
contains custom bits to serve ~llvm/html
as /
, and currently a fallback to serve ~llvm/buildlog
at /buildlog
:
server {
listen 80 default_server;
listen [::]:80 default_server;
charset: utf-8;
root /var/www/html/html;
index summary.html;
server_name _;
location /buildlog {
root /var/www/html;
autoindex on;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
After changing this config, run nginx -s reload
to make nginx reload its
config.
This setup requires that the user running nginx can access all files and
directories in ~llvm/buildlog
and ~llvm/html
-- directories need to be
+rx
for others, files need to be +r
for others. An easy way to check this
is namei -m ~llvm/buildlog/linux/1.txt
.