atomicules

Mostly walking the dogs

Notes On Building Hammerdb On Netbsd Part 2

Was going to edit the original post, but was easier to do a new one.

Went back to this again recently to make some better changes (did not mean to take two months… sigh) and it wouldn’t build! I’d either completely forgotten some of the steps I took last time or the build has changed a bit? Note that even though my changes are still on HammerDB 5.0 that doesn’t mean there haven’t been upstream changes - The HammerDB source code you obtain from Github is more like a “build system” as opposed to the actual source you are compiling. When you build from source you are actually running Tcl scripts that download source code from the TPC/HammerDB website and then it builds that.

Anyway, further to last time ended up doing this:

  1. Turns out I did need to do this bit:

     sudo ln -s /usr/pkg/bin/python3.12-config /usr/pkg/bin/python3-config
    
  2. Running a ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt update would fail because the Makefiles wanted to use -ldl which isn’t applicable for (Net)BSD. So instead I stepped through the process manually:
    1. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt extract.
    2. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt configure.
    3. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt compile.
    4. Which would then fail, but I could edit the relevant Makefile and remove the -ldl and re-run the compile and repeat this until all components had built.
    5. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt distribute.
    6. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt finalize. Weirdly, even though I’m sure these are the same steps update does, this didn’t copy all the required libraries into the distributions so I had one final step of:
    7. ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt update.
  3. That got me working Dev builds again. I also had a play about withstrace/dtrace/ktrace on the Prod builds and figured out they were actually fine, it was just looking for the libraries in an odd place; Say I had extracted at /home/me/temp/HammerDB-5.0, well, it was looking for /home/me/temp/lib. So I just copied the lib folder from a Dev build to that location and then the Prod builds would run fine; I started with strace just for ease of use, but the version on NetBSD is old and doesn’t print full filepaths which makes it useless. ktrace and kdump are pretty easy to use as well, but only if you know what you are looking for upfront and I didn’t, whereas dtrace is more complex, but I could get it to put all filepaths for HammerDB and eyeball a non-existent one:

     syscall::stat:entry, syscall::lstat:entry, syscall::access:entry
     /execname == "hammerdb"/
     {
         self->path = copyinstr(arg0);
         self->probe = probefunc;
     }
     syscall::stat:return, syscall::lstat:return, syscall::access:return
     /execname == "hammerdb" && self->path != NULL/
     {
         printf("%d %s %s errno=%d\n", pid, self->probe, self->path, errno);
         self->path = 0;
     }
    

Next for me on this: Figuring out a better Makefile fix so that’s less tedious to do. And it might not be impossible to do a Pkgsrc package for this since the separate steps (extract, configure, etc) would align with Pkgsrc.

Your Eyeball Is Not A Well Defined Statistical Procedure

"Your eyeball is not a well defined statistical procedure"

In a past-life I ended up doing quite a bit of statistics. There is some evidence on this blog and I even linked to this website before it was the website it is now and before it was a physical book. Bought the physical book recently and have been reading (re-reading?) it due to a change of role where I’m hopeful I can make use of some statistics again (I have already managed a bit of R ♡).

LINK: Claude Container

There are many different blog posts and repos out there for running Claude in a container, but this was one of the first I found and I liked its simplicity (over options like this).

Made some tweaks to this so I could use it at work with our evil MITM TLS.

Seems pretty good. Limitations so far:

  • Can’t run pre-commit (I could try to support this in the container, but not that bothered as I can run myself)
  • Can only commit with --no-verify (linked to above and also can’t sign my commits since I’m using 1Password for my ssh keys and it can’t trigger that from the container)

But… I feel far more comfortable running it this way and I don’t have to babysit it.

Notes On Building Hammerdb On Netbsd

Some initial rough notes on building HammerDB on NetBSD. It has quite a unique build system - I don’t know if it’ll be possible to make a Pkgsrc package of this. For now I just wanted to see if I could get it to build at all.

  1. See github changes
  2. Need to install 7-zip: sudo pkgin install 7-zip
  3. Need to install tcl 9 (just for the header file; Since HammerDB is actually building tcl this step feels superfluous, maybe the header is available locally when building and I just haven’t found it yet?): sudo pkgin install tcl90
  4. To build the pgtcl package need:

     export PG_CONFIG=/usr/pkg/bin
    
  5. I had to set this to get it to find my include files:

     export C_INCLUDE_PATH=/usr/pkg/include/python3.12/:/usr/pkg/tcl/9.0/include/:/usr/include/
    

    The last /usr/include/ isn’t actually required, but I chucked it on there for good measure

  6. And for the pty.h requirement somewhere along the way, we actually need util.h so I had to symlink:

     sudo ln -s /usr/include/util.h /usr/include/pty.h
    
  7. To actually build:

     cd /home/simon/Code/github/TPC-Council/HammerDB/Build/Bawt-2.1.0
     ./Build-Linux.sh x64 Setup/HammerDB-Linux.bawt update
    

    For now I’m just stealing/tweaking the Linux files instead of adding BSD ones.


At some point whilst trying to get things to build I did this:

    sudo ln -s /usr/pkg/bin/python3.12-config /usr/pkg/bin/python3-config

But on a recent rebuild to check through this post this step wasn’t required (I deleted the symlink before rebuilding) and I can’t recall why I did this in the first place. But leaving this as a note just in case


Running the builds

Basically you need to copy and extract the build somewhere:

cd ../BawtBuild/Linux/x64/Release/Distribution
cp HammerDB-5.0-Dev-Linux.tar.gz /to/somewhere/else
cd /to/somewhere/else
tar xvzf HammerDB-5.0-Dev-Linux.tar.gz
cd HammerDB-5.0-Dev-Linux
./hammerdb

I haven’t been able to get the prod one to work yet - for sure it’s got to be linked to “linking” and something has been stripped that shouldn’t have. Not too bothered about figuring this out yet because the Dev build does run!

HammerDB running on NetBSD

For the cli the (default) tcl one works, but the Python one (./hammerdbcli py) doesn’t - I’ve done some initial debugging (editing and putting print statements in; another benefit of the Dev build is you can just edit the “built”scripts) and it’s something to do with not being able to find tclpys even though it is there.


Before going down the building route I did have a brief play with the pre-built binaries and NetBSD’s Linux emulation, but:

/home/simo...-ubuntu-22  $ ./hammerdbcli
./hammerdbcli: /lib64/libc.so.6: version `GLIBC_2.33' not found (required by ./hammerdbcli)
./hammerdbcli: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by ./hammerdbcli)
./hammerdbcli: /lib64/libm.so.6: version `GLIBC_2.35' not found (required by ./hammerdbcli)

I.e. I didn’t have a modern enough glibc available, I only had 2.15 from the Suse Linux Compatibility package. I could, in theory, have tried tracking down a more modern one (because that’s how it works), but it felt easier to try to get the build working.


[EDIT: 2026-08-27] Part 2 of this as a separate post as it was easier than trying to edit this one - had to make some changes to get this building again due to it wanting to use -ldl.

Exploring Syncing Notes With Fossil

For a long time I’ve toyed with the idea of replacing Simplenote with a Fossil repo of text files, more from an “owning your own data” point of view than anything else, but more “recently” since I stopped using Vim and switched to Helix. It’s probably not happening any time soon as Simplenote is still too convienent on mobile, but I thought I’d have a little play just because Fossil’s auto-sync is really neat.

  1. Created a repo on my (this) server, but a private one for now, not public
  2. Cloned that via ssh to my local machine: fossil clone ssh://me@linode/Code/fossil/repos/notes.fossil
  3. Then added a little “hook” to Helix via my mksh config like so:

     function hx {
       /usr/pkg/bin/hx $@
       if [[ $(pwd) == '/home/simon/Code/fossil/checkouts/notes' ]]
       then
         if [[ $(fossil extras) != "" ]]
         then
           fossil add $(fossil extras)
         fi
         fossil commit -m 'Auto-sync notes'
       fi
     }
    

    The idea being that if I am editing a note and then exit and save, Fossil will then automatically sync changes, including adding it if it’s a new note. The only downside to this is that if I suspend Helix (Ctrl+z) then that also triggers this and if I resume (fg) and then quit it won’t automatically sync.

  4. So I’ve also added a keybinding of fs to Helix to manually trigger a sync:

    [keys.normal.f]
    s = [":write", ':sh if [ "$(fossil extras)" != "" ]; then fossil add $(fossil extras); fi; fossil commit -m "Auto-sync notes"']
    

    (Slightly different syntax as it’s sh as opposed to mksh)

I can’t see me fully switching from Simplenote yet as I don’t have a good mobile solution (apart from using a sftp client on Android… hmmm… maybe), but it’s interesting to play about.

Patching the Synaptics driver on NetBSD to disable tap-to-click

This has bugged me since I got a ThinkPad X270, so much so that I actually found/made time for Frustration Driven Development, figured out a patch for the source code, built the kernel and tested it out. This has MASSIVELY IMPROVED my laptop experience. Honestly, not overstating that. Due to the Synaptics driver doing tap-to-click by default I would frequently make mis-clicks with my palm, etc when typing and would often mis-click and accidentally drag tabs, etc in Firefox. I was coming very close to disabling the trackpad altogether and using the pointer instead, but then “solved” half the problem by disabling mouse mode in Helix - although it was still annoying me elsewhere.

I patched it so tap to click is the default behaviour and I can just easily disable via sudo sysctl -w hw.synaptics.tap_to_click=0:

--- /usr/src/sys/dev/pckbport/synaptics.c.orig	2024-06-22 11:02:05.000000000 +0100
+++ /usr/src/sys/dev/pckbport/synaptics.c	2026-04-22 17:21:33.087414774 +0100
@@ -118,6 +118,7 @@
 static int synaptics_button_boundary = SYNAPTICS_EDGE_BOTTOM;
 static int synaptics_button2;
 static int synaptics_button3;
+static int synaptics_tap_to_click = 1;
 static int synaptics_two_fingers_emul = 0;
 static int synaptics_scale_x = 8;
 static int synaptics_scale_y = 8;
@@ -155,6 +156,7 @@
 static int synaptics_edge_motion_delta_nodenum;
 static int synaptics_finger_high_nodenum;
 static int synaptics_finger_low_nodenum;
+static int synaptics_tap_to_click_nodenum;
 static int synaptics_two_fingers_emul_nodenum;
 static int synaptics_scale_x_nodenum;
 static int synaptics_scale_y_nodenum;
@@ -865,6 +867,18 @@
 
 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+	    CTLTYPE_INT, "tap_to_click",
+	    SYSCTL_DESCR("Enable tap to click"),
+	    pms_sysctl_synaptics_verify, 0,
+	    &synaptics_tap_to_click,
+	    0, CTL_HW, root_num, CTL_CREATE,
+	    CTL_EOL)) != 0)
+		goto err;
+
+	synaptics_tap_to_click_nodenum = node->sysctl_num;
+
+	if ((rc = sysctl_createv(clog, 0, NULL, &node,
+	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
 	    CTLTYPE_INT, "two_fingers_emulation",
 	    SYSCTL_DESCR("Map two fingers to middle button"),
 	    pms_sysctl_synaptics_verify, 0,
@@ -1101,6 +1115,10 @@
 		if (t < 0 || t > 3)
 			return (EINVAL);
 	} else
+	if (node.sysctl_num == synaptics_tap_to_click_nodenum) {
+		if (t < 0 || t > 1)
+			return (EINVAL);
+	} else
 	if (node.sysctl_num == synaptics_two_fingers_emul_nodenum) {
 		if (t < 0 || t > 2)
 			return (EINVAL);
@@ -2293,7 +2311,7 @@
 	/*
 	 * Do gesture processing only if we didn't detect a palm.
 	 */
-	if (palm == 0)
+	if (palm == 0 && synaptics_tap_to_click)
 		synaptics_gesture_detect(sc, sp, fingers);
 	else
 		sc->gesture_type = sc->gesture_buttons = 0;

I haven’t noticed any downsides to this at all yet. I have physical buttons that I can use for clicking anyway PLUS it turns out if I press hard enough (I’d never done this because of tap-to-click) on the trackpad it actually physically clicks (and that still registers as a click with this patch).

I must be some kind of freak for hating tap to click (I hate it on macOS as well) since no one has bothered to change this over the years. Or even moaned that much about it.

I couldn’t recall trackpad usage on my previous NetBSD laptop being this bad, but then I looked up that hardware and realised it didn’t have a trackpad.


[EDIT: 2026-05-04] It got committed. Whoop!

Where am I running AI in Tmux?

Since using lots of Vim sessions in a terminal I had a brief dalliance with Nova (I did/do like it, but it’s not cross-platform) and then ended up with Helix. At work I tend to use Helix in the same way I was using Vim but instead of Terminal.app it’s Alacritty with one huuuuge Tmux session with multiple windows (“tabs”) per each Git repository I’m working on. I haven’t bothered figuring out renaming the tmux windows automatically and just rename them manually - it tends to be a very long running Tmux session that I also save and restore so renaming manually is a one-time thing. It is easy to find whichever repo I want (across 70+ windows) by using CTRL, b, w to bring up Tmux’s window search and then using / to search for the name I want.

Since starting to play about with AI clis, I’ll split the Tmux window so I have a pane for running the cli in and a pane for Helix. But I won’t be running an AI cli in all of these windows which has lead me to wonder, “How do I find where I’m running AI clis?”.

What I’ve done is add a simple wrapper to the AI cli command to set and unset Tmux window titles on launch and quit of the AI cli:

function ai {
	# Let me know where I'm running an AI cli session
	
	# Find tmux window this command was called from
	# This way can target window. 
	# And avoid racey style stuff where wrong "current window" gets renamed
	twin=$(tmux list-panes -a | grep "$TMUX_PANE " | cut -d : -f 2 | cut -d . -f 1)
	twse=$(tmux list-panes -a | grep "$TMUX_PANE " | cut -d : -f 1)
	# I don't think I'd ever use an asterisk as a window name, but this would fallover if I did
	twnm=$(tmux list-windows -a | grep "$twse:$twin:" | cut -d : -f 3 | cut -d ' ' -f 2 | cut -d '*' -f 1)
	tmux rename-window -t $twin "$twnm + ai"
	/path/to/ai/cli
	tmux rename-window -t $twin $twnm
}

And now I can easily search through my Tmux windows.

LINK: Using Gemini Cli For Software Development

Meant to link to this at the time, but I meant to write my own blog post (see yesterday) before that, but it’s taken me until now to do either; AI certainly isn’t freeing up any spare time in my life.

Playing About With Ai Clis On Netbsd

NetBSD themselves have a no AI policy (fair; at some point lawyers are going to make a mint), but I just wanted to have a play about and since I run NetBSD, perhaps for too long, I just assumed I was out of luck with most AI tooling (most things do just target macOS, Windows and Linux). But it turns out things are mostly ok thanks to all the CLI tooling being node/npm:

  • Gemini just works* (and requires nothing more than a Google account; Which I have again since switching to Android)
  • Codex throws an unsupported platform (I wonder if this could be worked around?)
  • Claude runs (but there is no free tier)
  • Qwen code works (requires a free account; Looks like a Gemini clone)

(Don’t use global installs)

I started with Gemini - I thought I’d jump in the deep end and ask it to do something useful and something fairly complex so I asked it to build me a Chrome Cast receiver in python - I’d love to be able to cast from my Pixel to my NetBSD laptop. It “worked” in that it built something that looked sensible and did run although didn’t actually work when it came to being a Chrome Cast receiver. So then I thought I’d step back a bit and ask it to migrate simplenote.py (long neglected by me) from Travis to Github Actions; Because this is the kind of thing I’ve been meaning to do for a few years and just haven’t found the time for; I.e. this seems like the kind of “chore” task we should be using AI for instead of all the terrible things we are using AI for.

Comparing Gemini with Qwen

For both I gave a prompt like this (apart from the branch name being different):

Create a branch of this repository called gemini-github-actions and migrate the Travis CI setup to Github Actions

And then also gave both permissions for whatever it asked for for the session.

Both gave me additional instructions. Gemini:

To verify the migration, you should push this branch and ensure the GitHub Actions runner can successfully execute the tests and build the package. If you want to proceed with a commit, please let me know.

Qwen:

Next steps:

  1. Add PyPI credentials to GitHub repository secrets (PYPI_USERNAME and PYPI_PASSWORD)
  2. The deploy job triggers on release publication (modern approach vs. Travis’s tag-based deployment)

Personally I find it dumb that neither of them committed automatically (why would I be telling you to create a branch?) so I told both:

Please commit your changes including the summary of the changes you’ve just provided in the commit message.

Qwen had just created the .github/workflows/ci.yml file whereas Gemini also removed the .travis.yml and updated the README badges (nice); However, I LOVE that Qwen co-authored the commit by default.

I told Qwen:

Please also delete the .travis.yml and update the README badges to suit Github Actions ​

to get it in the same state.

(Interesting aside… I had to update my PAT to allow creation and updates of workflows before I could push)

Here’s the final results (final at the time of publishing is one commit on the gemini branch and two on the qwen one):

  1. Gemini
  2. Qwen

There are some subtle differences. Gemini includes many more python versions, Qwen just two, matching exactly what I had for Travis.

Of these two, only the Gemini branch automatically triggered a Github Actions run because it sensibly included its own branch - it failed though on every single job. Don’t actually know why. Github just tells me all the jobs exceeded the maximum execution times whilst waiting for runners.

In an effort to actually publish this post this year I am going to leave the AI efforts there for now - I might continue with both branches and get Gemini and Qwen to make further tweaks or I might continue by hand, but that could take me days, or weeks. Or months. So this will do for now. There’s no conclusions to this post, just observations - literally just me documenting my playing about.

This post has taken me months to write. I’m just too busy. I’ve been wanting to play with AI CLI tooling because up until just the last day or so I’ve not been allowed to use any such tooling at work (believe it or not). At least my tinkering on NetBSD did give me a little bit of a headstart and familiarisation.


* - Worked until this change since that it now gives env: unknown option -- S on NetBSD. Reverting that makes it work again. For me that was these files:

  • /home/me/node_modules/.bin/gemini
  • /home/me/node_modules/@google/gemini-cli/dist/index.d.ts

[EDIT: 2026-08-14] Qwen still installs and runs fine, but the free plan ended on 2026-04-15, Claude still installs via npm, but doesn’t run (not tried to work around the platform detection). Gemini switched to antigravity which doesn’t work under Linux emulation as needs GLIB_2.25 which is way more modern than I have from the Suse compat stuff. Oh well, that was a short lived adventure on NetBSD - perhaps for the best

[EDIT:2026-08-19] Actually, can still use the Qwen cli with Openrouter and whatever free models they have on offer. Right now Cohere’s North Mini Code seems pretty good (for free)

[EDIT:2026-08-25] pi.dev works a treat on NetBSD via npm. Can use that with Openrouter or many others. It did moan about fd not being available, so I installed it via Pkgsrc: pkgin install fd-find

Making Use Of Having Netbsd Hardware Again

It took me a bit to get up and running after getting the laptop, but did want to point out that I am actually making use of it now:

  • I make use of the excellent pdh on my NetBSD server so it means I can somewhat have an unofficial PagerDuty client on my phone (for “reasons” I can’t use the official one). But it bugged me that plain output was broken and that I couldn’t snooze alerts. So I fixed them both; Technically I didn’t need local NetBSD hardware for this since I only run pdh on my server, but just having a portable computer which is mine doesn’t half make it easier to do this.
    • I spent quite a bit of time looking at pre-commit and ruff-pre-commit as part of this. In the end I’ve not pushed anything, but I patched pre-commit locally so it works after I install pysqlite3, but then still ran into issues building ruff-pre-commit on NetBSD and I couldn’t find a work-around even though I could install ruff itself fine.
      diff --git a/pre_commit/store.py b/pre_commit/store.py
      index 1235942..ba2469a 100644
      --- a/pre_commit/store.py
      +++ b/pre_commit/store.py
      @@ -3,7 +3,11 @@ from __future__ import annotations
       import contextlib
       import logging
       import os.path
      -import sqlite3
      +try:
      +    # Primarily for BSDs that don't have built-in
      +    import pysqlite3
      +except ImportError:
      +    import sqlite3
       import tempfile
       from collections.abc import Generator
       from collections.abc import Sequence
    
  • One of the first things I did on this machine was build helix. It built fine outside of Pkgsrc, but I wanted to update the Pkgsrc package and having local NetBSD hardware meant I could finally do it. Now I just need someone to merge it.
  • Similarly with spotifyd, especially since I’m the supposed maintainer of the Pkgsrc package. That really can only be tested on local hardware.
  • And libvips too.
  • I had some thoughts about trying to setup my own taskwarrior sync server and put together a Pkgsrc WIP package for taskchampion-sync-server, but I don’t think I’m going to pursue this as using the mobile app requires running CCsync as well which just seems silly. Maybe I’ll re-visit this at some point. Maybe I’ll go back to TeuxDeux.

These are the ten most recent posts, for older posts see the Archive.