Quick notes on how to build the actor-oriented language Pony on DragonFly.
We need LLVM 10 to build or that’s what I have tested with:
sudo pkg ins llvm10
It won’t build with the stock gcc
due to some issues with C11’s stdatomic
that is used by the Pony runtime. DragonFly does not ship with libatomic
, but
LLVM 10 is clever enough to emit opcodes for cmpxchg
on uint128_t
types
instead of falling back to calls to __atomic_compare_exchange_16
. It still
links to -latomic
so that I had to provide a dummy libatomic.a
in order to
make the linker happy. Note that libatomic
is part of LLVM but it seems to be
disabled by default in the DragonFly port.
Next, what you need is my dragonfly-fix-compile
branch of ponyc:
git clone https://github.com/mneumann/ponyc.git
cd ponyc
git checkout dragonfly-fix-compile
This branch contains a few fixes to the CMakefiles as DragonFly is the only BSD
that has no BSD in it’s uname
. This results in a couple of patches like this:
-elseif(${CMAKE_HOST_SYSTEM_NAME} MATCHES "BSD")
+elseif(${CMAKE_HOST_SYSTEM_NAME} MATCHES "BSD|DragonFly")
Furthermore, the benchmark library gbenchmark
had to be patched as it did not
know anything about DragonFly. I just tricked it so that it now thinks we are
FreeBSD:
--- src/internal_macros.h.orig 2020-04-15 14:43:24 UTC
+++ src/internal_macros.h
@@ -54,6 +54,9 @@
#endif
#elif defined(__FreeBSD__)
#define BENCHMARK_OS_FREEBSD 1
+#elif defined(__DragonFly__)
+ #define BENCHMARK_OS_FREEBSD 1
+ #define BENCHMARK_OS_DRAGONFLY 1
#elif defined(__NetBSD__)
#define BENCHMARK_OS_NETBSD 1
#elif defined(__OpenBSD__)
The patch was trivial to create but telling CMake to apply it automatically
required a tiny bit of research. In the end it was as simple as adding
PATCH_COMMAND
to the ExternalProject_Add
directive:
PATCH_COMMAND patch -p0 < ...patch-file
In the dragonfly-fix-compile
branch I further ship the stdatomic.h
header
file, as it’s not installed by default on DragonFly as mentioned earlier. The
only thing I had to modify was:
-#if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>)
+#if 0
# include_next <stdatomic.h>
I tried to fix the CMakefiles in order to pick the stdatomic.h
header up
automatically from a local directory, but that did not work. Instead, I ended
up with pasting the contents of stdatomic.h directly into the
src/common/pony/detail/atomics.h
file at the right place.
Then I had to tell CMake to pick up my dummy
libatomic.a
:
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../dragonfly/lib
)
To produce the dummy libatomic.a
, I used something like this:
echo "" > atomic.c
gcc -c -o atomic.o atomic.c
ar rcs libatomic.a atomic.o
All these things are contained in my dragonfly-fix-compile
branch. To compile ponyc,
you just have to execute the following from the ponyc directory:
export CC=clang10
export CXX=clang++10
gmake libs && gmake configure && gmake build
Run tests:
gmake test
And to install:
gmake install prefix=$HOME/pony
Let’s try to compile a simple hello world application with the Pony compiler:
mkdir hw && cd hw
cat <<EOF > main.pony
actor Main
new create(env: Env) =>
env.out.print("Hello World")
EOF
$HOME/pony/bin/ponyc .
./hw # => "Hello World"
Works, great!