The Fediverse is a wonderful place, and the #FreeBSD community over there is rather active :-).
Justine Smithies is one those people with whom we have had multiple constructive interactions, and she has made lovely contributions to FreeBSD’s community, starting with her enthusiasm!
Recently, she’s been toying around with maomao, a Wayland compositor.
And I promised to create a port if she committed to keeping it up to date (neat trick to get new contributors!)
Let’s document both that process, and how she can keep those patches coming in to the ports tree!
You may want to read my (now outdated) post on
updating a FreeBD port, which goes into detail about the
Source trees, but most technical bits are outdated by now, given that
FreeBSD has moved away from svn
and now uses git
to manage code.
The short version about FreeBSD‘s Source trees (plural!). Without going into much detail: FreeBSD has a base (or src) tree and a ports tree.
The base tree contains the whole Operating System along with any necessary system utilities and they are developed as a unit.
While the ports tree contains a description of how to compile
third-party software under FreeBSD and how to install it manually or
how to build an installable binary package, which can later on be built on
FreeBSD‘s infrastructure and served by official pkg
repositories.
Contrary to popular belief, Wayland is not something that is exclusive to Linux. While it is Linux-centric, it does support FreeBSD, even as a test target on its CI!
Some things that are worth checking on this topic (though some might be outdated, they are still worth it):
There are in fact right now 140 ports with ‘Wayland’ on their description
(source: quick pkg(8)
magic).
As usual with Wayland things, it is written with Linux in mind, but as it often happens, that does not mean the authors are hostile towards supporting FreeBSD, they just might not be aware that the OS can be a target.
In fact, the author recently committed some code that helps mmsg
(a companion tool to maomao) bulid on FreeBSD without patches.
So if we run into issues, we can be reasonably sure that a patch will be welcome.
I have previously created several ports and update some from time to time, so I was able to take shortcuts and creating the ports was relatively quick.
poudriere(8)
With poudriere(8)
, we’ll be able to manage building the ports with jails
and producing a local repository of packages, that we can easily install, as
well as manage the ports tree.
Once poudriere(8)
is installed with pkg install poudriere
, we can check
its configuration under /usr/local/etc/poudriere.conf
.
Here is what I like to adapt from the sample file:
# Use the ZFS dataset zroot/poudriere
ZPOOL=zroot
ZROOTFS=/poudriere
# Which is mounted on /poudriere
BASEFS=/poudriere
# Suggested value
FREEBSD_HOST=https://download.FreeBSD.org
# DNS resolution for jails
RESOLV_CONF=/etc/resolv.conf
# Use tempfs(5) for wrdir and data
USE_TMPFS=yes
# Adapt this to your CPU count, leaving some for your regular use
PARALLEL_JOBS=6
# I have found timestamps to be useful
TIMESTAMP_LOGS=yes
# I like to keep old versions around
KEEP_OLD_PACKAGES=yes
KEEP_OLD_PACKAGES_COUNT=2
# Use the 'latest' ports branch when fetching pre-buit binaries
PACKAGE_FETCH_BRANCH="latest"
This can be done in multiple ways, the most convenient one is getting the
code from the same repository that is used by developers over anonymous git
with poudriere(8)
:
# Fetch the ports tree
> poudriere ports -c -p default
Luckily, this is a fairly standard port, we start by identifying a somewhat
similar port, like
x11-wm/swayfx
,
and using it as a starting point.
Here is roughly what that looks like:
PORTNAME= maomao
DISTVERSION= g20250624
CATEGORIES= x11-wm
MAINTAINER= ports@FreeBSD.org
COMMENT= A streamlined but feature-rich Wayland compositor
WWW= https://github.com/DreamMaoMao/maomaowm
LICENSE= MIT
LICENSE_FILE= ${WRKSRC}/LICENSE
USES= meson pkgconfig desktop-file-utils
OPTIONS_DEFINE= X11
OPTIONS_DEFAULT=X11
X11_MESON_ENABLED= xwayland
USE_GITHUB= yes
GH_ACCOUNT= DreamMaoMao
GH_PROJECT= maomaowm
GH_TAGNAME= e8fe574
.include <bsd.port.mk>
We then check the meson.build
file, which
lists all its dependencies.
And adapt entries acordingly:
BUILD_DEPENDS= wayland-scanner:graphics/wayland \
wayland-protocols>0:graphics/wayland-protocols \
evdev-proto>0:devel/evdev-proto
LIB_DEPENDS= libscenefx-0.4.so:x11-toolkits/scenefx04 \
libwlroots-0.19.so:x11-toolkits/wlroots019
X11_LIB_DEPENDS= libxcb-icccm.so:x11/xcb-util-wm
X11_USE= XORG=xcb,pixman
I also identify that we need the same sample file, version and C flag patches
that x11-wm/swayfx
implements, so I copy and adapt those:
post-patch:
# Extract (snapshot) version from the port instead of meson.build
@${REINPLACE_CMD} -i .nogit -e 's/git.found()/false/' \
-e '/unknown/s/@0@/${DISTVERSIONFULL}/' \
${WRKSRC}/meson.build
# Fix C flags
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=275328
@${REINPLACE_CMD} -e 's/_POSIX_C_SOURCE=200809L/_XOPEN_SOURCE=700/' \
${WRKSRC}/meson.build
# Respect PREFIX for system-wide config
@${REINPLACE_CMD} -e "s,format('/etc'),format('${PREFIX}/etc')," \
${WRKSRC}/meson.build
post-install:
# Install config file as a sample
@${MV} ${STAGEDIR}${ETCDIR}/config.conf \
${STAGEDIR}${ETCDIR}/config.conf.sample
We update / generate the distinfo
file with make makesum
.
Then the pkg-plist
file:
bin/maomao
@sample %%ETCDIR%%/config.conf.sample
share/wayland-sessions/maomao.desktop
And also create the pkg-descr
file:
A streamlined but feature-rich Wayland compositor
1. **Lightweight & Fast Build**
- *Maomao* is as lightweight as *dwl*, and its build can be completed within
few seconds. Despite this, *maomao* does not compromise on functionality.
2. **Feature Highlights**
- In addition to basic WM functionality, Maomao provides:
- Base tag not workspace (supports separate window layouts for each tag)
- Smooth and customizable complete animations (window open/move/close, tag
enter/leave)
- Excellent input method support (text input v2/v3)
- Flexible window layouts with easy switching (scroller, master, monocle,
spiral, etc.)
- Rich window states (swallow, minimize, maximize, unglobal, global,
fakefullscreen, overlay, etc.)
- Simple yet powerful external configuration
- Sway-like scratchpad and named scratchpad
- Minimize window to scratchpad
- Hycov-like overview
- Window effects from scenefx(blur, shadow, corner radius, opacity)
And the pkg-message
file, which gets shown upon install:
[
{ type: install
message: <<EOM
The default configuration works best by installing foot(1) and rofi(1)
alongside maomao.
Also, keep these default shortcuts in mind:
- alt+return: open foot terminal
- alt+q: kill client
- alt+left/right/up/down: focus direction
- super+m: quit maomao
EOM
}
]
We do this with poudriere(8)
, which uses jails and ZFS snapshots.
We first have to create the jail, if we haven’t already:
# Create a builder jail for amd64 based on 14.3-RELEASE
> poudriere jail -c -j 143-amd64 -v 14.3-RELEASE
# We also can keep the jail up to date with:
# poudriere jail -u -j 143-amd64
And we can now instruct poudriere(8)
to use our ports tree with this jail
to build this port:
# Start jail 143-amd64, with the default ports tree, to build maomao
> poudriere bulk -j 143-amd64 -p default x11-wm/maomao
This will fetch all needed packages along with their dependencies, so we only have to build locally the port we need.
Once the port builds (which required a small code patch), we can install it with:
# Install the resulting maomao binary pkg
> pkg add /poudriere/data/packages/143Ramd64-default/All/maomao-g20250624.pkg
And we can then run it as usual.
The recurring work of updating the port lies in updating the Makefile
with
each release.
Usually dependencies are pretty stable, other than that we just have to:
PORTVERSION
to match the latest releasemmsg
, that’d be DISTVERSION
and GH_TAGNAME
, this is
because it does not currently have actual releasesmake makesum
Now that we created two ports: x11-wm/maomao
and deskutils/mmsg
, we can
submit them and hope that they get merged soon.
Since Diane Bruce offered to help commit this, we add her as a reviewer. And since further maintainership is going to Justine, we add her on CC.
You can check the patch and its state [here][pr_maomao].
[pr_maomao]:
Generally speaking, I would advise people who want to get into contributing to the ports tree, to start by updating ports that they use and care about.
Committers and maintainers are usually happy to have a patch to quickly review and test as opposed to having to do the whole work.
In this case, since the port did not exist, it might be easier to nerdsnipe someone into creating the ports, and then helping out with the maintenance ;-) which is always super needed and appreciated!