After interviewing jeremy_list, I wanted to pull functions out of his habitat secure scuttlebutt client (C++), and to embed or interleave portable embeddable common lisp in lieu of nonportable haikuos features. I use openbsd, all else being equal, though I am meant to be trying dragonflybsd one of these days. So this article does that.
Doing that meaning making an openbsd native C++ ecl port for openbsd. Every operating system or linux distribution has their own analogy of doing this. At some point your lisp system needs to interface with the host operating system. Using openbsd ports(7) on openbsd means your software all hooks together properly. Since we are particularly using C++, we would like to be able to get C++ libraries from the package manager, so playing ball properly is doubly necessary.
Anyway, here’s specifically and literally what I did on openbsd. You could adopt openbsd and never look back, or it’s always kind of like this for whatever os (though openbsd/macports/freebsd/netbsd/dragonflybsd and friends particularly).
ecl
is a major ansi CL implementation, so openbsd has a maintained port of 24.5.10
. ECL is fundamentally lisp-as-a-C-or-C+±lib (libecl). The existing port is for C rather than C++. Without further ado, here it is:
COMMENT = embeddable common-lisp
CATEGORIES = lang
V = 24.5.10
DISTNAME = ecl-$V
SHARED_LIBS += ecl 9.0
REVISION = 2
HOMEPAGE = https://common-lisp.net/project/ecl/
MAINTAINER = Timo Myyra <timo.myyra@bittivirhe.fi>
EXTRACT_SUFX = .tgz
# LGPLv2 or later
PERMIT_PACKAGE = Yes
SITES = ${HOMEPAGE}static/files/release/
COMPILER = base-clang ports-gcc
COMPILER_LANGS = c
USE_GMAKE = Yes
CONFIGURE_STYLE = gnu
TEST_TARGET = check
CONFIGURE_ENV += CPPFLAGS=-I${LOCALBASE}/include \
ECLLIB_VERSION=${LIBecl_VERSION} \
ecldir=${LOCALBASE}/lib/ecl \
MAKEINFO=${PREFIX}/bin/gmakeinfo
CONFIGURE_ARGS += --enable-boehm=system \
--enable-libatomic=system \
--enable-gmp=system \
--with-gmp-prefix=${LOCALBASE}
# etags gets picked up if it's installed, and dumps core while
# generating the tags. so override it for now untill etags is fixed.
CONFIGURE_ENV += ETAGS=/usr/bin/true
WANTLIB += atomic_ops c ffi gc gmp m pthread
BUILD_DEPENDS += print/texinfo
LIB_DEPENDS += devel/gmp \
devel/boehm-gc,-main \
devel/boehm-gc,-atomic \
devel/libffi
TEST_DEPENDS = ${BASE_PKGPATH}
TEST_ENV = "ECL=${WRKDIST}/build/bin/ecl" \
"TEST_IMAGE=${WRKDIST}/build/bin/ecl"
.include <bsd.port.mk>
--with-cxx
versionUnified diff:
$ diff -u Makefile.orig Makefile
--- Makefile.orig 2025-08-01 16:33:39.163635975 +1200
+++ Makefile 2025-08-01 16:36:16.523631049 +1200
@@ -18,7 +18,7 @@
SITES = ${HOMEPAGE}static/files/release/
COMPILER = base-clang ports-gcc
-COMPILER_LANGS = c
+COMPILER_LANGS = c c++
USE_GMAKE = Yes
CONFIGURE_STYLE = gnu
TEST_TARGET = check
@@ -29,6 +29,8 @@
CONFIGURE_ARGS += --enable-boehm=system \
--enable-libatomic=system \
+ --with-cxx \
+ --disable-c99complex \
--enable-gmp=system \
--with-gmp-prefix=${LOCALBASE}
It’s a very slight adjustment. Technically I’m meant to have made a cxx
flavor, though there are not flavors of ecl currently so I just left a mail with the maintainer. So our full patch-applied file is:
COMMENT = embeddable common-lisp
CATEGORIES = lang
V = 24.5.10
DISTNAME = ecl-$V
SHARED_LIBS += ecl 9.0
REVISION = 2
HOMEPAGE = https://common-lisp.net/project/ecl/
MAINTAINER = Timo Myyra <timo.myyra@bittivirhe.fi>
EXTRACT_SUFX = .tgz
# LGPLv2 or later
PERMIT_PACKAGE = Yes
SITES = ${HOMEPAGE}static/files/release/
COMPILER = base-clang ports-gcc
COMPILER_LANGS = c c++
USE_GMAKE = Yes
CONFIGURE_STYLE = gnu
TEST_TARGET = check
CONFIGURE_ENV += CPPFLAGS=-I${LOCALBASE}/include \
ECLLIB_VERSION=${LIBecl_VERSION} \
ecldir=${LOCALBASE}/lib/ecl \
MAKEINFO=${PREFIX}/bin/gmakeinfo
CONFIGURE_ARGS += --enable-boehm=system \
--enable-libatomic=system \
--with-cxx \
--disable-c99complex \
--enable-gmp=system \
--with-gmp-prefix=${LOCALBASE}
# etags gets picked up if it's installed, and dumps core while
# generating the tags. so override it for now untill etags is fixed.
CONFIGURE_ENV += ETAGS=/usr/bin/true
WANTLIB += atomic_ops c ffi gc gmp m pthread
BUILD_DEPENDS += print/texinfo
LIB_DEPENDS += devel/gmp \
devel/boehm-gc,-main \
devel/boehm-gc,-atomic \
devel/libffi
TEST_DEPENDS = ${BASE_PKGPATH}
TEST_ENV = "ECL=${WRKDIST}/build/bin/ecl" \
"TEST_IMAGE=${WRKDIST}/build/bin/ecl"
.include <bsd.port.mk>
I asked jackdaniel to clarify my need for --disable-c99complex
- basically the definition of _Complex
is not standardised so it is not always present, as was the case here (and hence the available configure
flag).
Well, my path was
cd /usr/ports/mystuff/lang/ecl++/
i.e. where I had the above patched build.
doas make fake
this install(1)
s dependencies in a fake (as such) environment to build safely in isolation. doas(1)
is a less crazy notion of ‘sudo’. If you don’t have a dependency available because it is installed systemwise, the default is to recursively build ports (which you don’t want to do with texlive…). Followed by
doas make install
which install
s the binary in the expected /usr/local/bin/ecl
and lib in /usr/local/lib/libecl.so
.
I had to nuke my ~/.cache/common-lisp/ecl-24.5.10-unknown-bsd-x64/
after this (since all those were built with C libecl
.
Well, this article ended up being just making a C++ openbsd port of ecl out of the available port until the maintainer adds a flavor or otherwise responds to my mail. I was quite satisfied how easy this was to do with ecl in particular and openbsd in general.
Now I can use embeddable common lisp’s ffi:c-progn
freely with openbsd port C++ libraries and particular project sources like jeremy_list’s habitat.
Our C++ ecl port is also part of my insane fairy godmother idea of turning the ubiquitous C++ programs of modernity into embeddable common lisp swank servers that can be slime-connected to.
As to what we could possibly want from an operating system as lispusers: basically we want to be able to build and drag in prebuilt (carefully signed (signify(1)ed)) ports we are likely to want. Building should be both safe, well-integrated and easy to pick up, all of which openbsd satisfies. We would also like operating-system features like networking and threading to be proactively safe for normal consumption, which is an openbsd hallmark. In particular we have access to openbsd’s nonportable and openbsd-led operating system security tools and libraries.
Hope I helped someone start using C++ embeddable common lisp and working with their OS’s ports. Talk on the Mastodon as always please.
screwlisp proposes kittens