Harmonia Build Instructions for Linux/Solaris


  1. Tools: GCC 3.4.x or 4.x, GNU make, GNU ar, BASH shell, Perl (all of these come standard with most Linux distributions)
  2. Required Libraries:
    1. Expat
    2. Zlib (standard with most Linux distributions)
    3. GC v6.6 (Boehm-Weiser Garbage Collector) + LD_PRELOAD patch (for use with Java)
  3. Optional Applications
    1. XEmacs 21.4.x or 21.5.x (if you get this from a package, make sure that the header files for dynamically loadable module support are included)
    2. Java SDK (1.4.2 or 5)
    3. Tcl/Tk (any reasonably recent version)


  1. If you with to use Harmonia with Java, you will need to patch the garbage collector so that it can dynamically detect new threads created by the JVM.
    1. Apply patch in unix/gc6.6.patch using the patch command to the garbage collector source code
      cd /path/to/garbage/collector
      cd ..
      patch < /path/to/harmonia/src/unix/gc6.6.patch
    2. Configure, build, and install the garbage collector
      ./configure --prefix=/path/to/install/dir
      make install
  2. Run the Harmonia configure script. This script generates a hostname.mk file in the make/ directory which is included in the Harmonia makefiles to set locations for standard libraries and applications required by the build.
    You will likely need to pass in options specifying where expat is and where the garbage collector is before configure will succeed. The optional libraries and applications will cause configure warnings if they are missing, but will not break the build. Here are a list of important flags:
    1. --with-expat-includes=/path/to/expat/headers --with-expat-libs=/path/to/expat/sharedlibrary
    2. --with-gc-includes=/path/to/gc/headers --with-gc-libs=/path/to/gc/sharedlibrary
    3. --with-tcl-config=/path/to/tclConfig.sh
    4. --with-tk-config=/path/to/tkConfig.sh
  3. If you wish, create a .harmonia.mk file in the top-leve directory of the source tree. In this file, you can override any defaults assumed by the Harmonia build system. Useful lines are the following:
    1. BuildLog := true (records the build commands into a file in the lib/ directory.)
    2. Lang2Modules := java c (a space-delimited list of language modules you want to build; the options are all the languages listed in the langs2/ directory.)
    3. OptimizeLangs := true (often optimizing the languages using gcc uses too much RAM, so we turn it off by default, even if you're optimizing the rest of Harmonia)
    4. UseScratch := true
      BUILD_SCRATCH := /path/to/scratch/dir
      (use this when you want your generated code, your object files, and your libraries and binaries to be stored into a different place than your source tree. Symlinks will be made from the source tree to the appropriate scratch directory (a subdirectory of /path/to/scratch/dir) during the build to appear as if the build targets were in the source build tree. Use this with PerHostGenDir and PerHostDepDir (described below) to use the same source tree to build different targets.)
    5. PerHostGenDir := true (use this when you want the generated code to be put into a directory suffixed by your computer's hostname.)
    6. PerHostDepDir := true (use this when you want dependency files to be put into a directory suffixed by your computer's hostname.)


  1. Run make from the top-level source directory.
  2. You can also add GNU make options. For example, to optimize the code, type make Optimize=3. This passes -O3 to gcc whenever appropriate. There are several other make flags that can be used:
    1. Optimize=3 (turns on an optimized build of Harmonia. Passes -O3 to gcc. Turns off Debug and Trace options. Trace can be forced on by passing ForceTrace=true. It may seem like you can pass other numbers here, but don't. Some parts of the build system have been rigged to expect this value to be 0 or 3.)
    2. Debug=true (forces debugging code to be turned on. Also builds all .o files with debug symbols. Often used as an option to Harmonia applications (e.g. cppexample -debug F turns on debug option F which outputs dot format graphs of parsers and parse trees through time.) Debug options are specified in common/debug.h.)
    3. NoDebugSymbols=true (even if Debug is turned on, turns off debugging symbols)
    4. Trace=true (turns on optional tracing in the code. Often used as an option to Harmonia applications (e.g. cppexample -trace LP turns on trace options L and P at runtime which show human readable traces of the lexer and parser.) Trace options are specified in common/trace.h.)
    5. Profile=true (turns on optional profiling in the code (home-grown profiling, not gprof-style). Often used as an option to Harmonia applications (e.g. cppexample -profile a times all program analyses). Profile options are described in common/profile.h.)
    6. Backtrace=true (turns on optional stack dumps in the code. Often used as an option to Harmonia applications (e.g. cppexample -backtrace A turns on backtrace option A at runtime.) Backtrace options are specified in common/backtrace.h.)
    7. PreprocOnly=true (directs the compiler to preprocess the input files instead of compiling them. The output still goes to the same place as without this flag (so the output files are named *.o, not *.i). This flag is useful when there's a file that is compiling incorrectly and you want to know why.)
    8. TimeCompile=true (times every execution of gcc so you can see how long your build really takes.)
    9. GCCTime=true (directs gcc to print out a report of internal timing information. It passes -ftime-report to all invocations of gcc).
    10. MakeSilent= (yes, that's right, there's nothing after the equals sign. This turns on the verbose build so you can see every command executed by the build system).
  3. The default options can be found in make/definitions.mk. By default, we turn on Debug=true Trace=true Profile=true Backtrace=true Optimize=0.
  4. If you have a multi-processor computer, do not use make -j2 (or any other number). Our makefiles don't seem to work properly when builds run in parallel. If anyone fixes this, please let us know.


  1. Harmonia is distributed with nine sample applications described below. Most are made up of only one file, so they should be simplistic enough to figure out what's going on and how to use this in your own code.
    1. C++ Examples
      1. cppexample - This is our prototypical C++ use of Harmonia as a library. It loads in a sample input file, lexes, parses and semantically analyzes it.
      2. profapp - This is a variant of cppexample that has some options for processing the input file one character or word at a time. We use it to profile the incremental parsing algorithm.
      3. homophone - This application tests the homophone library. It looks up words in a homophone dictionary and returns the homophones. Also includes a Perl script for screen-scraping homophones from a homophone database web site.
      4. phylum-graph - This application loads an input file, parses it, and prints out the syntax tree in dot output format.
    2. Tcl Examples
      1. bfe - Batch Front End. This is a prototypical Tcl use of Harmonia as a library. It loads in a sample input file, lexes, parses and semantically analyzes it. It also reports errors and is able to automatically determine which language module to load based on the input file's extension.
    3. XEmacs Examples
      1. harmonia-mode - This is our flagship application, an XEmacs plugin to provide Harmonia services to the XEmacs editor. Some of its dependent code is in glue/xemacs.
      2. homophone - This application also has an XEmacs plugin module to make it accessible from XEmacs.
    4. Java Examples
      1. ASTBrowser - This is a Java application that loads an input file and lets you browse the resulting parse tree attributes. Each window shows the attributes for a node. Buttons in the window allow you to open windows for neighboring nodes in the parse tree. ASTBrowser always opens up the UltraRoot first.
      2. ASTViewer - This Java application loads an input file and lets your browse the resulting parse tree in a Java Swing Tree widget.
      3. profapp-java - A Java version of the C++ profapp application.
  2. All applications are executed using generated scripts (of the same name as the application) that can be found in the bin/ directory. These scripts set up several important shell variables needed to run Harmonia. Options to the application go right after the application name. Options to the script itself can be passed after preceding them all with a double-dash (--). For example, to run XEmacs from the Optimize=3 build of Harmonia, run bin/run-xemacs.sh /path/to/myfile.java -- -opt3. The following is the list of all the generic script options (more options may be available in each application's script):
    1. -opt3 (used for invoking the Optimize=3 build of Harmonia)
    2. -ndbg (used for invoking the Debug=false build of Harmonia)
    3. -ntr (used for invoking the Trace=false build of Harmonia)
    4. -tr (used for invoking the Trace=true build of Harmonia)
    5. -nprof (used for invoking the Profile=false build of Harmonia)
    6. -verbose (makes the script print out all the environment variables it is defining as well as the command line to run the application)
    7. -gdb (pauses script execution so the user can attach gdb to the process. Tells you the process id).
  3. Other applications have their own script options:
    1. run-gdb.sh - spawns gdb ready to start a Harmonia application (all shell variables are set properly, which would not be the case if you started gdb by hand.)
      1. No options
    2. run-sh.sh - spawns a shell (defined by $SHELL) ready to start a Harmonia application by invoking the binary directly (all shell variables are set properly, which would not be the case from a regular shell).
      1. No options
    3. run-tclsh.sh - Executes a Tcl Harmonia application.
      1. -scriptname (specifies the name of the Tcl script to execute).
    4. run-java.sh - Executes a Java Harmonia application.
      1. -classpath (appends the argument to the classpath used to the run the application)
      2. -mainclass (specifies the main class to execute)
      3. -jar (specifies a Jar file to execute)
    5. run-xemacs.sh - Starts up XEmacs with the Harmonia plugin
      1. -load (loads the specified lisp file into XEmacs with the -load argument)
      2. -eval (executes the specified lisp code into XEmacs with the -eval argument)
      3. -batch (executes a headless XEmacs session. Useful for compiling XEmacs files).
      4. -debug-init (turns Lisp variable debug-on-error on so errors will crash into the XEmacs debugger)
      5. -gdb (when XEmacs starts up, pause to let the user attach gdb to the process. Use this with -coredump to turn off Harmonia segfault and assertion recovery).
      6. -t (turns on trace options in Harmonia: usage -tLP (turns on trace options L and P))
      7. -d (turns on debug options in Harmonia: usage -dLP (turns on debug options L and P))
      8. -b (turns on backtrace options in Harmonia: usage -bLP (turns on backtrace options L and P))
      9. -p (turns on profile options in Harmonia: usage -pLP (turns on profile options L and P))
      10. -coredump (prevents Harmonia from catching segfaults and trying to recover from them. This option is used with -gdb to debug a Harmonia session.


  1. To get help, try reading Marat Boshernitsan's Master's report about the Harmonia architecture.
  2. Then try the harmonia-dev@sequoia.cs.berkeley.edu mailing list and its archives.
  3. Finally, just read through the source code. There are lots of useful comments there. When in doubt, copy and paste from something that already exists.