Drinking The Koolixir – Part 2
To get a better handle on Erlang’s behavior, I decided to install a popular set of tools for debugging and performance profiling: EPER. I think it stands for “Erlang PERformance tools”, but it could also mean “Everything Proves Erlang Rules” or “Egrets Prefer to Eat Robots” or really anything for that matter. One thing is for certain, however: getting these tools built and running on Mac OS X was fraught with danger and build errors.
Running the Test Suite
Before I got down to the business of trying to make
and make install
EPER, it made sense to run make test
to ensure everything was in working order. Why start there? You know because tests. Seemed like a decent way to figure out how the system ticks, and learn a little more about how the pieces of the Erlang environment fit together.
Problems Arise
EPMD
Right off the bat, I ran into issues with eunit
tests not passing. Specifically, the first run of make test
yielded the following:
=INFO REPORT==== 4-Mar-2015::19:05:02 === Protocol: "inet_tcp": register/listen error: econnrefused prfDog: t0_test (module 'prfDog')...*failed* in function prfHost:assert_proxy/1 (src/prfHost.erl, line 67) in call from prfHost:start/4 (src/prfHost.erl, line 26) in call from prfDog:t0_test/0 (src/prfDog.erl, line 178) **exit:{no_proxy,nonode@nohost}
The solution? Start epmd
in “daemon” mode:
epmd -daemon
That solved the issue, but does raise some more questions. Like: What the heck is epmd
? How do I manage this service on a Mac? Is it lunchy
compatible? launchd
? initctl
? I will definitely be digging deeper into epmd
in a future post. For now, we march onward through Error Canyon.
GTKNode
The installation process next failed because gperfGtk
claims it is missing some dependencies:
src/gperfGtk.erl:386: Warning: gperfGtk:g/1 calls undefined function gtknode:cmd/2 (Xref) src/gperfGtk.erl:37: Warning: gperfGtk:init/0 calls undefined function gtknode:start/1 (Xref) src/sherk.erl:567: Warning: sherk:g/1 calls undefined function gtknode:cmd/2 (Xref) src/sherk.erl:56: Warning: sherk:init/0 calls undefined function gtknode:start/1 (Xref) ERROR: xref failed while processing /Users/BTidwellGrio/Code/elx_workspace/eper: rebar_abort make: *** [xref] Error 1
A little Googling turned up the fact that gtknode
is an OSS Erlang library for mapping to the popular UI library, GTK. I pulled down the repo, and after a little more digging, found the command for building and installing it:
aclocal ; autoconf ; automake ; ./configure --prefix=/your/cool/prefix ; make ; make install
For the prefix here, I personally like to keep all of my shell/library Erlang in a .erllib
folder in my home directory. I track a couple of helper files in the same folder in a dotfiles repo, and ignore the build output of all the remaining libraries.
The first run of the gtknode
build exited with:
Checking for GTK... no
configure: error: Package requirements (gmodule-2.0 libglade-2.0 gtk+-2.0,
gdk-pixbuf-2.0) were not met:
Package 'libxml-2.0', required by 'libglade-2.0', not found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
This story checks out; it seems pretty obvious that something named gtknode would be dependent upon GTK
. The README
for gtknode
encourages the use of Homebrew to install glade
(amongst a myriad other things). This first required adding the X11 homebrew tap. Additionally, a couple more runs of the build script revealed a dependency on XQuartz, which is easily managed using Homebrew Cask. As I had never used Cask up to this point, I have included it in the installation steps below:
brew tap homebrew/x11
brew install glade fontconfig freetype libpng
brew install caskroom/cask/brew-cask
brew cask doctor # This triggers a sudo prompt to configure needed directories
brew cask install xquartz
Since we installed glade
and some of the other libraries using Homebrew, running another build will result in"Package 'xcb-shm', required by 'cairo', not found"
(or any number of other "[Package] not found"
errors). I am not completely familiar with pkg-config
, but it seems the gist of the problem is that Homebrew installs binaries and libraries in non-default locations (at least from a Linux perspective). This can be fixed by exporting the pkgconfig
environment variable*:
PKG_CONFIG_PATH=/usr/local/opt/libxml2/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig
*This lovely bit of minutiae comes courtesy of a completely unrelated page in the node-canvas Wiki.
With all this in place, gtknode
should compile, and make test
from the eper
project root should pass. Then, the EPER project can be built using the same tune as gtknode
:
aclocal ; autoconf ; automake ; ./configure --prefix=/your/cool/prefix ; make ; make install
Using EPER in Your Environment
Now that these libraries are compiled and installed using the prefix we provided earlier, we can add them to the Erlang shell using the ERL_LIBS
environment variable. If you used the same convention stated here (i.e. .erllib
in the home directory), then this variable should look like the following:
export ERL_LIBS="$HOME/.erllib/lib/erlang/lib"
On startup, the Erlang shell will load any source code in the ebin
directory of any libraries contained under the ERL_LIBS
directory. If you refresh this environment variable and then run erl
from the command-line, you should be able to sanity-check installation of EPER by running redbug:help().
inside the Erlang shell. This should output a list of methods supported by Redbug.
These tools are helpful not only for general debugging tasks, but also for learning Erlang in a much more disciplined way. Now, when something goes wrong deep in the depths of some function, it is simple enough to dig deeper using redbug
instead of relying on guesswork. This may deserve a dedicated post on redbug or just be interwoven with future blog posts, but either way you can expect to see more about proper redbug
usage in this series.