<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>OrangeShark</title><subtitle>Recent Posts</subtitle><updated>2018-04-02T19:46:56-0400</updated><id>http://www.erikedrosa.com/</id><link href="http://www.erikedrosa.com/feed.xml" rel="self" /><link href="http://www.erikedrosa.com" /><entry><title>Setting up a GNU Guile project with Autotools</title><author><name>Erik Edrosa</name><email>erik.edrosa@gmail.com</email></author><updated>2017-10-29T12:00:00-0400</updated><id>http://www.erikedrosa.com/2017/10/29/guile-projects-with-autotools.html</id><link href="/2017/10/29/guile-projects-with-autotools.html" rel="alternate" /><summary type="html">&lt;p&gt;Lisp, specifically Scheme, has captivated me for about three years
now. My Scheme implementation of choice is &lt;a href=&quot;https://www.gnu.org/software/guile/&quot; title=&quot;GNU Ubiquitous Intelligent Language for Extensions&quot;&gt;GNU Guile&lt;/a&gt; because
it is the official extension language of the &lt;a href=&quot;https://www.gnu.org/&quot;&gt;GNU project&lt;/a&gt;. One issue I
faced early with when trying to develop for Guile was how to set up
and organize my project. There doesn&amp;apos;t seem to be a single
recommended way to set up a Guile project but several projects do
follow a similar project structure I will describe below. You can find
a git repository with the example project &lt;a href=&quot;https://gitlab.com/OrangeShark/guile-skeleton&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Simple Project Structure&lt;/h2&gt;&lt;p&gt;The project template I created for new projects is based on several
GNU Guile projects I have examined. These projects follow the
traditional GNU Build System using the familiar commands &lt;code&gt;./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install&lt;/code&gt; for building and installing software. To
help generate these files, we will use the collection of software
known as autotools which include the software &lt;a href=&quot;https://www.gnu.org/software/autoconf/autoconf.html&quot;&gt;Autoconf&lt;/a&gt; and
&lt;a href=&quot;https://www.gnu.org/software/automake/&quot;&gt;Automake&lt;/a&gt;. Unfortunately, autotools can be quite complex
for developers with its esoteric languages like m4 being used to
magically create and configure all the necessary build files for your
project. Good news for us, not much magic is needed for us to conjure
the build files for a simple Guile project.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;.
├── bootstrap
├── configure.ac
├── COPYING
├── COPYING.LESSER
├── guile.am
├── m4
│   └── guile.m4
├── Makefile.am
├── skeleton
│   └── hello.scm
├── pre-inst-env.in
├── README
└── skeleton.scm&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Above is the directory structure of the project. &lt;code&gt;bootstrap&lt;/code&gt; is a
simple shell script which a developer can regenerate all the GNU Build
System files. &lt;code&gt;configure.ac&lt;/code&gt; is a template file which Autoconf uses to
generate the familiar &lt;code&gt;configure&lt;/code&gt; script. &lt;code&gt;m4/guile.m4&lt;/code&gt; is a recent
copy of Guile&amp;apos;s m4 macros, may not be needed if you prefer to use the
macro from your Guile distribution, but it is recommended to keep your
own copy. &lt;code&gt;COPYING&lt;/code&gt; and &lt;code&gt;COPYING.LESSER&lt;/code&gt; are just the GPL and LGPL
licenses. &lt;code&gt;Makefile.am&lt;/code&gt; and &lt;code&gt;guile.am&lt;/code&gt; are Automake files used to
generate the &lt;code&gt;Makefile.in&lt;/code&gt; which &lt;code&gt;configure&lt;/code&gt; will configure.
&lt;code&gt;skeleton.scm&lt;/code&gt; and &lt;code&gt;skeleton/hello.scm&lt;/code&gt; are some initial source code
files, where &lt;code&gt;skeleton.scm&lt;/code&gt; represents the Guile module &lt;code&gt;(skeleton)&lt;/code&gt;
and &lt;code&gt;skeleton/hello.scm&lt;/code&gt; is the &lt;code&gt;(skeleton hello)&lt;/code&gt; module, change
these file and directory names to what you want to name your modules
as. &lt;code&gt;pre-inst-env.in&lt;/code&gt; is a shell script which set up environment
variables to be able to use your code before installing it.&lt;/p&gt;&lt;h2&gt;Bootstrapping the Project&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;#! /bin/sh

autoreconf --verbose --install --force&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is the &lt;code&gt;bootstrap&lt;/code&gt; script, it just calls autoreconf, which uses
Autoconf and Automake, to generate the &lt;code&gt;configure&lt;/code&gt; script from
&lt;code&gt;configure.ac&lt;/code&gt; and &lt;code&gt;Makefile.in&lt;/code&gt; file from &lt;code&gt;Makefile.am&lt;/code&gt;. The
&lt;code&gt;bootstrap&lt;/code&gt; script is sometimes also named &lt;code&gt;autogen.sh&lt;/code&gt; in projects
but seems to no longer be preferred to avoid confusion with the &lt;a href=&quot;https://www.gnu.org/software/autogen/&quot;&gt;GNU
AutoGen project&lt;/a&gt;. The command will also generate a bunch of
other files needed by the build process. This script is only used when
building from a checkout of the project&amp;apos;s repository, because a user
will only need &lt;code&gt;configure&lt;/code&gt; and &lt;code&gt;Makefile.in&lt;/code&gt;. Whenever you might be
having an issue with the configure script or made a change to it,
doing &lt;code&gt;./bootstrap&lt;/code&gt; will regenerate the files for you.&lt;/p&gt;&lt;h2&gt;Generating the Configure Script&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-autoconf&quot;&gt;AC_INIT([guile-skeleton], [0.1])
AC_CONFIG_SRCDIR([skeleton.scm])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

GUILE_PKG([2.2 2.0])
GUILE_PROGS
if test &amp;quot;x$GUILD&amp;quot; = &amp;quot;x&amp;quot;; then
   AC_MSG_ERROR([&amp;apos;guild&amp;apos; binary not found; please check your guile-2.x installation.])
fi

AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env])

AC_OUTPUT&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Above is the &lt;code&gt;configure.ac&lt;/code&gt; file used by &lt;a href=&quot;https://www.gnu.org/software/autoconf/autoconf.html&quot;&gt;GNU Autoconf&lt;/a&gt; to
generate the &lt;code&gt;configure&lt;/code&gt; script. The first line is the &lt;code&gt;AC_INIT&lt;/code&gt; macro,
the first argument is the package name and the second argument is the
version. There is a couple of other optional arguments which you can
learn more about &lt;a href=&quot;https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Initializing-configure.html#Initializing-configure&quot;&gt;here&lt;/a&gt;. The &lt;code&gt;AC_CONFIG_SRCDIR&lt;/code&gt;
macro adds a check to &lt;code&gt;configure&lt;/code&gt; for the existence of a unique file
in the source directory, useful as a safety check to make sure a user
is configuring the correct project. &lt;code&gt;AC_CONFIG_AUX_DIR&lt;/code&gt; macro is where
auxiliary builds tools are found, &lt;code&gt;build-aux&lt;/code&gt; is the the most commonly
used directory, we use this so we don&amp;apos;t litter the source directory
with build tools.  The next macro, &lt;code&gt;AC_CONFIG_MACRO_DIR&lt;/code&gt; is where
additional macros can be found, we add this to include the
&lt;code&gt;m4/guile.m4&lt;/code&gt; file. &lt;a href=&quot;https://www.gnu.org/software/automake/&quot;&gt;GNU Automake&lt;/a&gt; options are part of the
next macro, &lt;code&gt;AM_INIT_AUTOMAKE&lt;/code&gt;, where &lt;code&gt;-Wall&lt;/code&gt; turns all warnings,
&lt;code&gt;-Werror&lt;/code&gt; turns those warnings into errors, and finally &lt;code&gt;foreign&lt;/code&gt; will
turn the strictness to a standard less than the GNU standard. More
automake options can be found &lt;a href=&quot;https://www.gnu.org/software/automake/manual/html_node/List-of-Automake-options.html#List-of-Automake-options&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;GUILE_PKG&lt;/code&gt; and &lt;code&gt;GUILE_PROGS&lt;/code&gt; macro is part of the &lt;code&gt;m4/guile.m4&lt;/code&gt;
file. This macro will substitute various variables that will be used
in the Makefile. The &lt;code&gt;GUILE_PKG&lt;/code&gt; macro will use the pkg-config program
to find the development files for Guile and substitute the
&lt;code&gt;GUILE_EFFECTIVE_VERSION&lt;/code&gt; variable in the Makefile. The &lt;code&gt;GUILE_PROGS&lt;/code&gt;
macro finds the various Guile programs we will need to compile our
program. This macro substitutes the variables &lt;code&gt;GUILE&lt;/code&gt; and &lt;code&gt;GUILD&lt;/code&gt; with
the path to the &lt;code&gt;guile&lt;/code&gt; and &lt;code&gt;guild&lt;/code&gt; programs. By default, these
Guile macros will check for the latest version of Guile first, which
is currently 2.2. If you have multiple versions of Guile installed, a
user of the &lt;code&gt;configure&lt;/code&gt; script may override the above Guile
variables. For example if you have Guile 2.2 and 2.0 installed and you
want to install the package for 2.0, you can run &lt;code&gt;./configure GUILE=/path/to/guile2.0&lt;/code&gt;. There is also a check to ensure the &lt;code&gt;GUILD&lt;/code&gt;
variable was set by &lt;code&gt;GUILE_PROGS&lt;/code&gt; and displayed an error if it could
not be found.&lt;/p&gt;&lt;p&gt;The next portion of this file involves the files that will actually be
configured when a user runs the &lt;code&gt;configure&lt;/code&gt; script. The
&lt;code&gt;AC_CONFIG_FILES&lt;/code&gt; macro&amp;apos;s first argument is files that will be
created by substituting the variables found in the file of the same
name with &lt;code&gt;.in&lt;/code&gt; appended to the end. In the first macro, it creates a
&lt;code&gt;Makefile&lt;/code&gt; by substituting the variables in &lt;code&gt;Makefile.in&lt;/code&gt;. The second
argument of this macro will be commands to run after the file is
created, in the second macro, it uses &lt;code&gt;chmod&lt;/code&gt; to make the
&lt;code&gt;pre-inst-env&lt;/code&gt; script executable. The last macro in this script is
&lt;code&gt;AC_OUTPUT&lt;/code&gt; and must be the final macro in &lt;code&gt;configure.ac&lt;/code&gt;. This macro
generates &lt;code&gt;config.status&lt;/code&gt; and then uses it to do all the configuration.&lt;/p&gt;&lt;h2&gt;Generating the Project Makefile&lt;/h2&gt;&lt;p&gt;For this project we use &lt;a href=&quot;https://www.gnu.org/software/automake/&quot;&gt;GNU Automake&lt;/a&gt; to help us generate
the Makefile. When Automake is ran, it will produce a &lt;code&gt;Makefile.in&lt;/code&gt;
file which will then be configured by the configure script. We divide
the Makefile into two files, &lt;code&gt;Makefile.am&lt;/code&gt; and &lt;code&gt;guile.am&lt;/code&gt;. The first
file is where we will put code specific for this project, that
includes source code and any other files to be distributed to
users. &lt;code&gt;guile.am&lt;/code&gt; file is where we have all the code that can be
shared between any other Guile project.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-automake&quot;&gt;include guile.am

SOURCES =               \
  skeleton/hello.scm    \
  skeleton.scm

EXTRA_DIST =            \
  README                \
  bootstrap             \
  pre-inst-env.in&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;code&gt;Makefile.am&lt;/code&gt; file is pretty small for now. The Automake script
first includes the Guile specific automake script &lt;code&gt;guile.am&lt;/code&gt;. The next
part is the variable &lt;code&gt;SOURCES&lt;/code&gt; which is a list of the project&amp;apos;s source
code that will be compiled and installed. The next variable,
&lt;code&gt;EXTRA_DIST&lt;/code&gt; is a list of other files that should be included in the
tarball used to distribute this project.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-automake&quot;&gt;moddir=$(datadir)/guile/site/$(GUILE_EFFECTIVE_VERSION)
godir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache

GOBJECTS = $(SOURCES:%.scm=%.go)

nobase_dist_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
nobase_go_DATA = $(GOBJECTS)

# Make sure source files are installed first, so that the mtime of
# installed compiled files is greater than that of installed source
# files.  See
# &amp;lt;http://lists.gnu.org/archive/html/guile-devel/2010-07/msg00125.html&amp;gt;
# for details.
guile_install_go_files = install-nobase_goDATA
$(guile_install_go_files): install-nobase_dist_modDATA

CLEANFILES = $(GOBJECTS)
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
SUFFIXES = .scm .go
.scm.go:
    $(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILD) compile $(GUILE_WARNINGS) -o &amp;quot;$@&amp;quot; &amp;quot;$&amp;lt;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now for &lt;code&gt;guile.am&lt;/code&gt;, this file has all of the Guile specific code used
in our Automake scripts. The first two variables, &lt;code&gt;moddir&lt;/code&gt; and
&lt;code&gt;godir&lt;/code&gt;, are the paths where we will install our Guile modules and
compiled modules. The next variable is the &lt;code&gt;GOBJECTS&lt;/code&gt; variable which
has some code that creates a list of Guile object files from our
&lt;code&gt;SOURCE&lt;/code&gt; variable. The next two variables declared are special &lt;code&gt;DATA&lt;/code&gt;
variables using some of Automake&amp;apos;s features to indicate which files
should be installed and where. The first portion of the variable,
the &lt;code&gt;nobase_&lt;/code&gt; prefix is used to tell Automake to not strip the path of
these files when installing them. &lt;code&gt;dist_&lt;/code&gt; tells Automake that these
files must be distributed in the tarball. The next part, &lt;code&gt;mod_&lt;/code&gt; or
&lt;code&gt;go_&lt;/code&gt;, tell which directory these files should be installed, they
refer to the above &lt;code&gt;moddir&lt;/code&gt; and &lt;code&gt;godir&lt;/code&gt; variables. The files in
&lt;code&gt;SOURCES&lt;/code&gt; and &lt;code&gt;NOCOMP_SOURCES&lt;/code&gt; are installed in the &lt;code&gt;moddir&lt;/code&gt;, where
&lt;code&gt;SOURCES&lt;/code&gt; are the scheme files that we want to be compiled and the
&lt;code&gt;NOCOMP_SOURCES&lt;/code&gt; are scheme files which should not be compiled. The
compiled Guile source code, &lt;code&gt;GOBJECTS&lt;/code&gt; are installed in the
&lt;code&gt;godir&lt;/code&gt;. The next two lines of code are some special magic to ensure
the files are installed in the right order by Automake.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;CLEANFILES&lt;/code&gt; variable is an Automake variable with files which
should be deleted when a user runs &lt;code&gt;make clean&lt;/code&gt;. The compiled Guile
modules are just the files we need to delete, so we assign
&lt;code&gt;GOBJECTS&lt;/code&gt;. &lt;code&gt;GUILE_WARNINGS&lt;/code&gt; are warnings we want to pass to Guile
when it compiles or executes the code. &lt;code&gt;SUFFIXES&lt;/code&gt; allows us to add
Guile&amp;apos;s &lt;code&gt;.scm&lt;/code&gt; and &lt;code&gt;.go&lt;/code&gt; file extensions to be handled by Automake and
we define a suffix rule on how to compile the source code using
&lt;code&gt;GUILD&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;GNU Guile Project Source Files&lt;/h2&gt;&lt;p&gt;We now get to the actual Guile code for this project. A Guile project
may be divided into several modules and organized in various ways. In
this skeleton project, the main module is the &lt;code&gt;skeleton&lt;/code&gt; module and is
found in &lt;code&gt;skeleton.scm&lt;/code&gt; file. Sub-modules of skeleton are found in the
&lt;code&gt;skeleton/&lt;/code&gt; directory, where we currently have the &lt;code&gt;skeleton hello&lt;/code&gt;
module found in the &lt;code&gt;skeleton/hello.scm&lt;/code&gt; file.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-module (skeleton)
  #:use-module (skeleton hello))

(hello-world)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is the &lt;code&gt;skeleton&lt;/code&gt; module, it defines the module with the
&lt;code&gt;define-module&lt;/code&gt; form. We also import the &lt;code&gt;skeleton hello&lt;/code&gt; module using
the &lt;code&gt;#:use-module&lt;/code&gt; option of &lt;code&gt;define-module&lt;/code&gt;. All this file does is
call &lt;code&gt;hello-world&lt;/code&gt; procedure defined in the &lt;code&gt;skeleton hello&lt;/code&gt; module.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-module (skeleton hello)
  #:export (hello-world))

(define (hello-world)
  (display &amp;quot;Hello, World!&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final module is the &lt;code&gt;skeleton hello&lt;/code&gt; module. This module defines
the &lt;code&gt;hello-world&lt;/code&gt; procedure used in the previous module and then
exports it using the &lt;code&gt;#:exports&lt;/code&gt; option in the &lt;code&gt;define-module&lt;/code&gt; form.&lt;/p&gt;&lt;h2&gt;Putting It All Together&lt;/h2&gt;&lt;p&gt;Now how does this all come together for development? With all these
files in place in the project, executing the command &lt;code&gt;./bootstrap&lt;/code&gt;
will use Autoconf and Automake to generate the &lt;code&gt;configure&lt;/code&gt;,
&lt;code&gt;Makefile.in&lt;/code&gt;, and some other files. Then executing &lt;code&gt;./configure&lt;/code&gt; will
configure &lt;code&gt;Makefile.in&lt;/code&gt;, &lt;code&gt;pre-inst-env.in&lt;/code&gt;. Running the program make
should now compile your source code.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;#!/bin/sh

abs_top_srcdir=&amp;quot;`cd &amp;quot;@abs_top_srcdir@&amp;quot; &amp;gt; /dev/null; pwd`&amp;quot;
abs_top_builddir=&amp;quot;`cd &amp;quot;@abs_top_builddir@&amp;quot; &amp;gt; /dev/null; pwd`&amp;quot;

GUILE_LOAD_COMPILED_PATH=&amp;quot;$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH&amp;quot;
GUILE_LOAD_PATH=&amp;quot;$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH&amp;quot;
export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH

PATH=&amp;quot;$abs_top_builddir:$PATH&amp;quot;
export PATH

exec &amp;quot;$@&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Above is the &lt;code&gt;pre-inst-env.in&lt;/code&gt; file which is configured by the
configure script. The variables between &amp;apos;@&amp;apos; characters are variables
that will be replaced by the configure script. &lt;code&gt;abs_top_srcdir&lt;/code&gt; and
&lt;code&gt;abs_top_builddir&lt;/code&gt; are Autoconf variables which gives the absolute
source directory and build directory. Then we add these directories to
Guile&amp;apos;s &lt;code&gt;GUILE_LOAD_COMPILED_PATH&lt;/code&gt; and &lt;code&gt;GUILE_LOAD_PATH&lt;/code&gt;.
&lt;code&gt;GUILE_LOAD_COMPILED_PATH&lt;/code&gt; is an environment variable that has the
search path for compiled Guile code which have the &lt;code&gt;.go&lt;/code&gt; extension.
&lt;code&gt;GUILE_LOAD_PATH&lt;/code&gt; is the search path for Guile source code files. When
the configure script configures this file, it then allows you to run
Guile and use the modules of the project before installing them. This
can be done with this command &lt;code&gt;./pre-inst-env guile&lt;/code&gt;. The script also
does the same for the &lt;code&gt;PATH&lt;/code&gt; variable, to allow you to execute any
scripts in the project&amp;apos;s directory. Finally, the script executes the
rest of the command passed into this script.&lt;/p&gt;&lt;h2&gt;Distributing the Project&lt;/h2&gt;&lt;p&gt;So the project is now complete and you want to distribute it to other
people so they can build and install it. One of the great features of
autotools is it generates everything you need to distribute your
project. From the Makefile that is generated by GNU Automake, you run
&lt;code&gt;make dist&lt;/code&gt; and it will generate a tar.gz file of your project. This
will be the file you will then give to your users and they will just
extract the contents and run &lt;code&gt;./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install&lt;/code&gt; to build and
install your project. The files that are included in the distribution
are figured out by Automake and can be added to in your &lt;code&gt;Makefile.am&lt;/code&gt;
script file using the &lt;code&gt;EXTRA_DIST&lt;/code&gt; variable. One other helpful feature
that GNU Automake will generate is the command &lt;code&gt;make distcheck&lt;/code&gt;. This
command will check to ensure the distribution actually works, it will
first create a distribution and then proceed to open the distribution, build
the project, run tests, install the project, and uninstall the project
all in a temporary directory. You can learn more about GNU Automake
distribution in the &lt;a href=&quot;https://www.gnu.org/software/automake/manual/automake.html#Dist&quot;&gt;manual&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;One more note about installing your GNU Guile project. By default, the
GNU Build System installs your project in the &lt;code&gt;/usr/local&lt;/code&gt;
directory. GNU Guile installations generally do not have this
directory on their load path. There are several options on how to
resolve this issue. You can add
&lt;code&gt;/usr/local/share/guile/site/$(GUILE_EFFECTIVE_VERSION)&lt;/code&gt; to the
&lt;code&gt;GUILE_LOAD_PATH&lt;/code&gt; variable as well as
&lt;code&gt;/usr/local/lib/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache&lt;/code&gt; to the
&lt;code&gt;GUILE_COMPILED_LOAD_PATH&lt;/code&gt; variable, where
&lt;code&gt;$(GUILE_EFFECTIVE_VERSION)&lt;/code&gt; is the GNU Guile version you are using,
like 2.0 or 2.2. You can add these variables to your &lt;code&gt;.profile&lt;/code&gt; or
&lt;code&gt;.bash_profile&lt;/code&gt; in your home directory like so:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export GUILE_LOAD_PATH=&amp;quot;/usr/local/share/guile/site/2.2${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH&amp;quot;
export GUILE_LOAD_COMPILED_PATH=&amp;quot;/usr/local/lib/guile/2.2/site-ccache${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_COMPILED_LOAD_PATH&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The alternative is to install your project in the current load path of
your GNU Guile installation which is often &lt;code&gt;/usr&lt;/code&gt;. You can easily do
this by changing the &lt;code&gt;prefix&lt;/code&gt; variable in the configure script like
&lt;code&gt;./configure --prefix=/usr&lt;/code&gt;. Now when you run &lt;code&gt;make install&lt;/code&gt; it will
install everything in &lt;code&gt;/usr&lt;/code&gt; instead of &lt;code&gt;/usr/local&lt;/code&gt;. With the GNU
Build System, you have full control of where you install your Guile
files so you have the possibility of installing it anywhere you want
like your home directory, just be sure to add that location to your
load paths for Guile. There are several other variables you can modify
to change the installation location of various files, you can learn
more in the &lt;a href=&quot;https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Installation-Directory-Variables.html#Installation-Directory-Variables&quot;&gt;GNU Autoconf manual&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;The GNU Build System provides a common interface for configuring,
building, and installing software. The autotools project, although a
bit complex, helps us achieve this. This should be enough for a basic
GNU Guile library that can be compiled and distributed to users using
the GNU Build System. You can find the example project on GitLab
&lt;a href=&quot;https://gitlab.com/OrangeShark/guile-skeleton&quot;&gt;here&lt;/a&gt;. The project can be extended to include tests
and documentation that I hope to cover in other blog posts.&lt;/p&gt;</summary></entry><entry><title>Algorithms: Insertion Sort</title><author><name>Erik Edrosa</name><email>erik.edrosa@gmail.com</email></author><updated>2015-11-11T12:00:00-0500</updated><id>http://www.erikedrosa.com/2015/11/11/algorithms-insertion-sort.html</id><link href="/2015/11/11/algorithms-insertion-sort.html" rel="alternate" /><summary type="html">&lt;p&gt;I will be writing a series of blog posts about various algorithms. The purpose of these posts
will be to help me further my understanding and ability to explain algorithms. Each post
will cover an algorithm, provide an implementation in a programming language, explain the
algorithm using the implementation, and finally discuss any possible other discoveries I find when
researching the algorithm.&lt;/p&gt;&lt;h2&gt;What are Algorithms?&lt;/h2&gt;&lt;p&gt;Algorithms are a fundamental part of Computer Science, but what exactly are algorithms?
Well according to &lt;a href=&quot;http://www.merriam-webster.com/dictionary/algorithm&quot; title=&quot;Merriam-Webster&amp;apos;s definition for Algorithm&quot;&gt;Merriam-Webster&lt;/a&gt;, they define it as:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;a set of steps that are followed in order to solve a mathematical
problem or to complete a computer process&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In &lt;a href=&quot;http://mitpress.mit.edu/books/introduction-algorithms&quot; title=&quot;MIT Press site&quot;&gt;Introduction to Algorithms&lt;/a&gt;, algorithms are described as &amp;quot;a tool for solving a
well-specified computational problem&amp;quot; and as a technology. Knuth further describes algorithms
as having five important features in his book &lt;a href=&quot;http://www-cs-faculty.stanford.edu/~uno/taocp.html&quot; title=&quot;The Art of Computer Programming site&quot;&gt;The Art of Computer Programming&lt;/a&gt;.
These include:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Finiteness: it must eventually stop (better if it stops in a reasonable amount of time)&lt;/li&gt;&lt;li&gt;Definiteness: each step must be clearly stated&lt;/li&gt;&lt;li&gt;Input: Zero or more inputs to give to an algorithm&lt;/li&gt;&lt;li&gt;Output: One or more outputs the algorithm produces&lt;/li&gt;&lt;li&gt;Effectiveness: operations must be basic and producible&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So why are algorithms important to study? Well just as &lt;a href=&quot;http://mitpress.mit.edu/books/introduction-algorithms&quot; title=&quot;MIT Press site&quot;&gt;Introduction to Algorithms&lt;/a&gt;
describes them as tools, they should be an important tool in any programmer&amp;apos;s tool set to
allow them to go above and beyond to solve problems.&lt;/p&gt;&lt;h2&gt;Insertion Sort&lt;/h2&gt;&lt;p&gt;Sorting algorithms are typically one of the first algorithms introduced to students studying
Computer Science. The problems are usually easy to understand; I have a sequence of objects
and I want to arrange them in some ordered sequence. Numbers are often used as the objects
in examples of these algorithms because ordering numbers in an increasing or decreasing
sequence is simple to understand. Insertion sort is one of those sorting algorithms.&lt;/p&gt;&lt;p&gt;The basic high level idea of the insertion sort algorithm is given an unsorted list, each item
of the list is taken out and then inserted into a list in sorted order. Well according to
the definition of an algorithm, maybe what I just described is more like the strategy to come
up with an algorithm. This basic strategy can thus produce multiple algorithms with different
properties. I will cover two variations of insertion sort and discuss their pros and cons.&lt;/p&gt;&lt;h3&gt;Insertion Sort on Arrays&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;Insertion-Sort(v)
    for i &amp;lt;- 1 to length(v) - 1
        j &amp;lt;- i
        while j &amp;gt; 0 and v[j-1] &amp;gt; v[j]
            swap v[j] and v[j-1]
            j &amp;lt;- j - 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above is the pseudocode for insertion sort taken from &lt;a href=&quot;https://en.wikipedia.org/wiki/Insertion_sort&quot; title=&quot;Wikipedia page on insertion sort&quot;&gt;Wikipedia&lt;/a&gt;. Please note the
&lt;code&gt;&amp;lt;-&lt;/code&gt; operator is the assignment operator, more commonly written as &lt;code&gt;=&lt;/code&gt; in many languages. The
algorithm sorts the list &lt;code&gt;v&lt;/code&gt; in place, meaning it will modify, or mutate, the list given to
the Insertion-Sort function. One will notice that the operation &lt;code&gt;swap&lt;/code&gt; is usually not a basic
operation in most languages so here is the simple pseudocode for &lt;code&gt;swap&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;temp &amp;lt;- v[j]
v[j] &amp;lt;- v[j-1]
v[j-1] &amp;lt;- temp&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the above pseudocode, translating it to your favorite programming language is trivial.
Here it is written in python.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def insertion_sort(v):
    for i in range(1, len(v)):
        j = i
        while j &amp;gt; 0 and v[j-1] &amp;gt; v[j]:
            v[j], v[j-1] = v[j-1], v[j]
            j = j - 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The python code is almost a literal copy and paste of the pseudocode, which shows off the popular
idea on how python is almost like pseudocode. The line &lt;code&gt;v[j], v[j-1] = v[j-1], v[j]&lt;/code&gt; is how you
perform a swap operation in python.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/imgs/insertionsort.gif&quot; alt=&quot;insertion sort&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now to explain the basic idea behind the above insertion sort algorithm. The algorithm treats
the front of the list, that is elements with index less than &lt;code&gt;i&lt;/code&gt;, as a list that is already
sorted and elements that are greater than &lt;code&gt;i&lt;/code&gt; as elements which need to be sorted. This
is why the algorithm starts from 1 because sorting a list of length 1 is trivial, it is already
sorted. So the first loop goes through the unsorted part of the list, &amp;quot;taking out&amp;quot; the element,
and then inserting it into the the sorted part of the list. The insertion part of the algorithm
is the inner while loop, which keeps swapping elements from the tail end of the sorted list until
it reaches the correct spot.&lt;/p&gt;&lt;p&gt;The behavior of this algorithm is also pretty straight forward. In the best case, the list is
already sorted and the algorithm takes linear time or O(n). The algorithm will go through
the list and try to insert the element to only find &lt;code&gt;v[j-1] &amp;gt; v[j]&lt;/code&gt; to be false and thus no need
to swap the element. For the worst case insertion sort takes quadratic time or O(n²),
the worst case being the list is in reverse sorted order. It is the worst case because at each
element in the list, it must swap that element until it reaches the front of the list. For memory,
the algorithm sorts the list in place and thus is constant space or O(1). The insertion sort
algorithm I listed here can actually be improved to make it slightly faster, but I leave that as
an exercise for the reader (Hint: it is mentioned on &lt;a href=&quot;https://en.wikipedia.org/wiki/Insertion_sort&quot; title=&quot;Wikipedia page on insertion sort&quot;&gt;Wikipedia&lt;/a&gt;).&lt;/p&gt;&lt;h3&gt;Insertion Sort on Linked Lists&lt;/h3&gt;&lt;p&gt;The second variation is an algorithm that works on linked lists or sometimes known as cons cells
in other programming languages. This algorithm is written as a recursive function.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Insertion-Sort(l)
    if l is the empty list
        return the empty list
    else
        return Insert(Insertion-Sort(rest of l), head of l)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above pseudocode is an example of the algorithm. There is of course one problem with the above
pseudocode, Insertion-Sort uses the operation of Insert to insert an element into an already sorted
list. Insert isn&amp;apos;t a basic operation so we must provide an Insert algorithm for lists.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Insert(l, n)
    if l is the empty list
        return a list with the element n
    else if n &amp;lt;= the head of l
        return a list with the element n as the new head of list l
    else
        return a list with Insert(rest of l, n))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we should be able to implement the Insertion Sort algorithm in a programming language. I
decided to use the Scheme programming language because of lists being native to the language.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define (insertion-sort l)
  (if (null? l)
      &amp;apos;()
      (insert (insertion-sort (cdr l)) (car l))))

(define (insert l n)
  (cond ((null? l) (list n))
        ((&amp;lt;= n (car l)) (cons n l))
        (else (cons (car l) 
                    (insert (cdr l) n)))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For those unfamiliar with the Lisp family of languages, here is a break down of some of the
operations performed above. &lt;code&gt;null?&lt;/code&gt; is a procedure to check for the empty list, &lt;code&gt;car&lt;/code&gt; is a
procedure to get the first element of a list, &lt;code&gt;cdr&lt;/code&gt; is the procedure to get the list without
the first element, &lt;code&gt;cons&lt;/code&gt; is the procedure to create pairs which form the linked lists of lisp.
So &lt;code&gt;(cons x y)&lt;/code&gt; with &lt;code&gt;y&lt;/code&gt; being a list &lt;code&gt;(a b)&lt;/code&gt; creates a list &lt;code&gt;(x a b)&lt;/code&gt;. &lt;code&gt;cond&lt;/code&gt; is a special
form similar to &lt;code&gt;if&lt;/code&gt; except with multiple clauses in the form &lt;code&gt;(question answer)&lt;/code&gt;, where
if &lt;code&gt;question&lt;/code&gt; evaluates to true, then &lt;code&gt;answer&lt;/code&gt; is evaluated and returned as the result.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(insertion-sort &amp;apos;(3 1 2))
(insert (insertion-sort &amp;apos;(1 2)) 3)
(insert (insert (insertion-sort &amp;apos;(2)) 1) 3)
(insert (insert (insert (insertion-sort &amp;apos;()) 2) 1) 3)
(insert (insert (insert &amp;apos;() 2) 1) 3)
(insert (insert &amp;apos;(2) 1) 3)
(insert &amp;apos;(1 2) 3)
(cons 1 (insert &amp;apos;(2) 3))
(cons 1 (cons 2 (insert &amp;apos;() 3)))
(cons 1 (cons 2 &amp;apos;(3)))
(cons 1 &amp;apos;(2 3))
&amp;apos;(1 2 3)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The idea behind this linked list version of insertion sort is to take each element from the list
and then insert it into the sorted version of the list. So this recursive algorithm has to have
a base case, which is if the list &lt;code&gt;l&lt;/code&gt; is the empty list. Well, how do you sort the empty list?
Of course, it is just the empty list. Now if the list isn&amp;apos;t empty, we need to sort it, so the
recursive step is to sort the rest of &lt;code&gt;l&lt;/code&gt;. With the result of the recursive call, we have a sorted
list without the first element of &lt;code&gt;l&lt;/code&gt;, so we then insert the the first element &lt;code&gt;l&lt;/code&gt; into the sorted
list. The insert algorithm is complex enough to need an explanation as well. The insert algorithm
is also recursive with the same base case of the list &lt;code&gt;l&lt;/code&gt; being empty, so we just return a new list
with the number &lt;code&gt;n&lt;/code&gt;. The next base case is when &lt;code&gt;n&lt;/code&gt; is less than or equal to the head of list &lt;code&gt;l&lt;/code&gt;,
so the proper action is to &lt;code&gt;cons&lt;/code&gt; &lt;code&gt;n&lt;/code&gt; to be the new head of &lt;code&gt;l&lt;/code&gt;. The recursive step is when &lt;code&gt;n&lt;/code&gt;
isn&amp;apos;t in the correct position, so we &lt;code&gt;cons&lt;/code&gt; the current head of &lt;code&gt;l&lt;/code&gt; onto the list with &lt;code&gt;n&lt;/code&gt; inserted
into it.&lt;/p&gt;&lt;p&gt;The behavior of the list insertion sort is similar to the first insertion sort. The best case is
when the list is already sorted which will give you linear time or O(n). What the algorithm does
is it tries to insert the head of &lt;code&gt;l&lt;/code&gt; onto the already sorted list, the head will just be &lt;code&gt;cons&lt;/code&gt;
to the front of it. The worst case is also the same, the list is in reverse sorted list and thus
has quadratic time or O(n²). Memory is a different story, this version of the algorithm
creates a new list instead of sorting in place. The best case, when the list is already sorted, the
algorithm copies the elements to the new list and is just linear space or O(n). The worst case is
the list is in reverse sorted order, the insert algorithm creates a new list each time &lt;code&gt;n&lt;/code&gt; is
inserted into &lt;code&gt;l&lt;/code&gt; which is quadratic space or O(n²). The above algorithm can also be
improved, insertion sort can be made into an iterative process and the insert algorithm can also
insert into the list by mutating it.&lt;/p&gt;</summary></entry><entry><title>Tutorial: Hello, world! Cinnamon desklet</title><author><name>Erik Edrosa</name><email>erik.edrosa@gmail.com</email></author><updated>2014-12-31T12:00:00-0500</updated><id>http://www.erikedrosa.com/2014/12/31/hello-world-desklet-tutorial.html</id><link href="/2014/12/31/hello-world-desklet-tutorial.html" rel="alternate" /><summary type="html">&lt;p&gt;This is the first of hopefully several tutorials on developing desklets for
the Cinnamon desktop environment. In this tutorial, I will cover the basics
of creating a desklet and do my best to link or refer to additional
resources where you might find more information on
the topics. &lt;a href=&quot;https://en.wikipedia.org/wiki/Cinnamon_%28software%29&quot;&gt;Cinnamon&lt;/a&gt;
is a linux desktop environment forked from Gnome Shell by
&lt;a href=&quot;http://linuxmint.com/&quot;&gt;Linux Mint&lt;/a&gt;. A desklet is a small application which
appears on the Cinnamon desktop, Cinnamon ships with three desklets and more
can be found &lt;a href=&quot;http://cinnamon-spices.linuxmint.com/desklets&quot;&gt;here&lt;/a&gt;. Desklets
are written in JavaScript and uses CJS which is based on Gjs.
&lt;a href=&quot;https://wiki.gnome.org/Projects/Gjs&quot;&gt;Gjs&lt;/a&gt; are JavaScript bindings
for GNOME and is based on Mozilla&amp;apos;s JavaScript engine
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey&quot;&gt;Spidermonkey&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;My reason for creating this tutorial came about when I was creating a desklet
for Cinnamon. There were barely any guides or tutorials on creating a desklet
and finding documentation on the libraries available in CJS was difficult. The
only advice I saw was to read other people&amp;apos;s source code and learn from that,
while it is a great way to learn, it does not provide enough information. So
I would like to share what I have learned and where I found it.&lt;/p&gt;&lt;p&gt;Our first desklet will be a simple &amp;quot;Hello, World!&amp;quot; program, a simple program
which displays the text &amp;quot;Hello, World!&amp;quot; on the desktop using GNOME Shell&amp;apos;s
&lt;a href=&quot;https://wiki.gnome.org/Projects/Clutter&quot;&gt;Clutter&lt;/a&gt;-based toolkit called
&lt;a href=&quot;https://developer.gnome.org/st/stable/&quot;&gt;St (Shell Toolkit)&lt;/a&gt;. The St library
provides an easy way to create simple user interfaces.&lt;/p&gt;&lt;h2&gt;Requirements&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Cinnamon (I am running Linux Mint 17.1 with version 2.4.5)&lt;/li&gt;&lt;li&gt;Your favorite text editor&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Set up&lt;/h2&gt;&lt;p&gt;Let&amp;apos;s start by setting up the directory for our desklet. Desklets are stored
in the user&amp;apos;s home directory ~/.local/share/cinnamon/desklets, this is where
we will work on our desklet. First, we need to create the directory of our
desklet with a unique ID or UUID in the following format &amp;quot;desklet-name@name&amp;quot;,
where desklet-name is the desklet&amp;apos;s name, in this case hello-world, and name
is either your name or your domain name. I will use the UUID
&amp;quot;hello-world@orangeshark&amp;quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;mkdir -p ~/.local/share/cinnamon/desklets/hello-world@orangeshark
cd ~/.local/share/cinnamon/desklets/hello-world@orangeshark&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we need to create the structure for our project. A desklet has the
following structure:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;hello-world@orangeshark/
├── desklet.js
└── metadata.json&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The desklet.js file is where the majority of our JavaScript code will be
located. metadata.json contains, of course, the metadata for the desklet,
including the UUID and name of the desklet.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;touch desklet.js metadata.json&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Time to code&lt;/h2&gt;&lt;p&gt;Lets first define the metadata for the desklet, open up metadata.json and add
the following json.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &amp;quot;uuid&amp;quot;: &amp;quot;hello-world@orangeshark&amp;quot;,
    &amp;quot;name&amp;quot;: &amp;quot;Hello, world! desklet&amp;quot;,
    &amp;quot;description&amp;quot;: &amp;quot;Displays Hello, World!&amp;quot;,
    &amp;quot;prevent-decorations&amp;quot;: false
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The metadata contains basic information about your desklet, including the
UUID we discussed earlier. The only special property is &amp;quot;prevent-decorations&amp;quot;
which tells Cinnamon whether to apply your desktop&amp;apos;s theme or prevent it from
inheriting it. For this simple example, we will put the value false so the
desklet looks like the rest of your desktop.&lt;/p&gt;&lt;p&gt;Now for the JavaScript. There are several coding style guides to follow for
JavaScript by the GNOME project, Cinnamon seems to follow
&lt;a href=&quot;https://wiki.gnome.org/Projects/GnomeShell/Gjs_StyleGuide&quot;&gt;this guide&lt;/a&gt;. If
you are used to using JavaScript on the web or in node.js, you might notice
a couple of differences in the language. Several of these features are
from Mozilla&amp;apos;s version of JavaScript with some being defined in future
versions of ECMAScript. I will provide links where you can find additional
information on those features as we encounter them.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const Desklet = imports.ui.desklet;

function HelloDesklet(metadata, desklet_id) {
    this._init(metadata, desklet_id);
}

HelloDesklet.prototype = {
    __proto__: Desklet.Desklet.prototype,

    _init: function(metadata, desklet_id) {
        Desklet.Desklet.prototype._init.call(this, metadata, desklet_id);
    }
}

function main(metadata, desklet_id) {
    return new HelloDesklet(metadata, desklet_id);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above code is all you need to create a minimal desklet. You can use it
as the basic template to start your own desklet. Now for an explanation of
each part! The first line contains const, one of those new features I
mentioned earlier, more info &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const&quot;&gt;here&lt;/a&gt;.
The const declaration creates a constant in the current scope, in this case
the global scope, with a value that cannot be changed through re-assignment.
We use it here to import the desklet module from Cinnamon. The next function
is our Desklet object&amp;apos;s constructor, following GNOME&amp;apos;s style guide for
creating &amp;quot;classes&amp;quot;. Using GNOME&amp;apos;s class pattern, we assign to the
prototype of HelloDesklet an object containing the methods and properties for
our HelloDesklet class. The first property &amp;quot;__proto__&amp;quot; is a special
one, it allows us to modify the prototype chain, allowing us to have a
sort of inheritance of classes. So if a property is not found in the current
instance, it will walk the prototype chain to the next prototype, in this
case Desklet&amp;apos;s prototype, and check if the property is there. So our desklet
must &amp;quot;inherit&amp;quot; from &lt;a href=&quot;https://github.com/linuxmint/Cinnamon/blob/master/js/ui/desklet.js#L35&quot;&gt;Cinnamon&amp;apos;s Desklet class&lt;/a&gt;,
Desklet contains a lot of code required by Cinnamon to set up and destroy a
desklet. The _init function is the actual constructor for our &amp;quot;class&amp;quot; and our
first task is to call the Desklet&amp;apos;s constructor, passing the current instance
using &amp;quot;this&amp;quot;. Finally the main function is the entry point to our desklet and
we just return an instance of our desklet.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const Desklet = imports.ui.desklet;
const St = imports.gi.St;

function HelloDesklet(metadata, desklet_id) {
    this._init(metadata, desklet_id);
}

HelloDesklet.prototype = {
    __proto__: Desklet.Desklet.prototype,

    _init: function(metadata, desklet_id) {
        Desklet.Desklet.prototype._init.call(this, metadata, desklet_id);

        this.setupUI();
    },

    setupUI: function() {
        // main container for the desklet
        this.window = new St.Bin();
        this.text = new St.Label();
        this.text.set_text(&amp;quot;Hello, world!&amp;quot;);
        
        this.window.add_actor(this.text);
        this.setContent(this.window);
    }
}

function main(metadata, desklet_id) {
    return new HelloDesklet(metadata, desklet_id);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We now import a new library, this time St or Shell Toolkit library from GNOME.
I have found &lt;a href=&quot;http://www.roojs.com/seed/gir-1.2-gtk-3.0/seed/St.html&quot;&gt;this&lt;/a&gt;
documentation to be helpful in finding what classes are available in
JavaScript over the GNOME&amp;apos;s official &lt;a href=&quot;https://developer.gnome.org/st/stable/&quot;&gt;C API reference&lt;/a&gt;.
Next, a new method to HelloDesklet has been added which sets up our little
window on the desktop and displays the text &amp;quot;Hello, world!&amp;quot;. We use a
StBin container that can contain a single child, which is a StLabel widget
with the text &amp;quot;Hello, world!&amp;quot;. Finally we add the label to the window with
the add_actor method and then set the desklet content with setContent method
inherited from the Desklet base class. That is it! We have finished the
basis of a simple desklet for Cinnamon. It should look something like what
you see below (the style might be different depending on your Cinnamon theme).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/imgs/helloworlddesklet.png&quot; alt=&quot;Hello, World!&quot; /&gt;&lt;/p&gt;&lt;p&gt;This concludes the tutorial for Cinnamon desklets. I plan on covering more
aspects on creating Cinnamon desklets in the future, so stay tuned!&lt;/p&gt;</summary></entry></feed>