2. Software Prerequisites

In this course, we will be using OCaml as a main programming language. We will be working with multi-file projects, which will make use of various external libraries, and involve automated testing and graphics. Because of this, you will have to install a number of software utilities, which you did not need in the Intro to Computer Science class. This document provides detailed instructions on how to do so depending on the operating system you use.

If you don’t have a working OCaml framework, allocate at least 3 hours for going through this setup document, as some of the software packages listed required for our class will take quite a while to install.

Please, make sure check the intructions below on installing LLVM and Clang on your operating system.

2.1. Updating your OCaml

First, we need to install all the software necessary for fully fledged OCaml development. If you have taken YSC2229: Introductory Data Structures and Algorithms in 2019/20 AY or later, you should already have this set up, so you are almost good to go.

Assuming you already have some version of opam installed in your system, but your OCaml version is older than 4.09.1 (you can check it by executing ocamlc --version), please, update your set up and install the necessary packages as follows:

opam update; opam upgrade
opam switch create 4.09.1
eval $(opam env)
opam install -y dune core batteries utop num menhir tuareg user-setup merlin
opam user-setup install

Alternatively, if you don’t have a working opam and OCaml, please, follow the instructions below.

2.2. Installing OCaml from Scratch on MS Windows 10

Unfortunately, the OCaml infrastructure is not supported well on Windows (natively), therefore developing large multi-file projects in it is problematic. To circumvent this issue, we will be running OCaml and the related software using Windows Subsystem for Linux, a utility that allows to run a distribution of Linux within your Windows 10 system. This setup takes a large number of steps, but once you’re done with it, you’ll have a premium support for OCaml, and also a fully functional Linux distribution installed on your machine.

  1. First, let us enable WSL and install a Linux distribution. The detailed steps are given in this online tutorial. Don’t forget the password for the Linux account you’ve just created: you will need it to install some software. At the end of this step, you should be able to run a “bare-bone” Ubuntu Linux terminal as an application within your Windows system. In my case, it looks as follows.
_images/ubuntu.png
  1. You can access your Windows home folder from WSL Linux via tha path /mnt/c/Users/YOURNAME/ where YOURNAME is your Windows user name. It is convenient to make a symbolic link for it, so you could access it quickly, for instance, calling it home. This is how you create such a link:

    cd ~
    ln -s /mnt/c/Users/YOURNAME/ home
    

    Now you can navigate to you Windows home folder via cd ~/home and to your Linux home folder via cd ~.

  1. Next, we need to install a graphical shell for the Linux distribution running in WSL. This article provides detailed instructions on how to do so. Here are some comments:

    • You don’t have to install Firefox in WSL Linux, as you can use your Windows browser instead.
    • The required graphical XServer shell (run separately from Windows) can be downloaded from this resource.
    • To run Linux with the graphical mode, you will always have to first run the XServer, and then the Ubuntu shell, in which you will have to type xfce4-session. The Ubuntu window will have to stay running as long as you use Linux.
  2. If the Linux image appears to be somewhat “blurred”, here’s how to fix it:

    • First, add the following lines at the end of the file ~/.bashrc in your Linux home folder:

      export GDK_SCALE=0.5
      export GDK_DPI_SCALE=2
      

      This can be done using the nano editor, similarly to how it is done in this tutorial.

    • Next, close any running instance of that X server (VcxSrv). Open the folder where you have installed it (e.g., C:\Program Files\VcXsrv), right click on vcxsrv.exe. Choose Properties > Compatibility tab > Change high DPI settings > Enable Override high DPI scaling and change it to Application option. Here is the screenshot looks like after changing the settings:

_images/blur.png
  1. Once you have done all of this, you can run Linux terminal within the graphical XFCE shell and execute all commands from it, rather than from a Windows-started Ubuntu terminal. In my case, it looks as follows:
_images/xfce.png
  1. Next, we will install Emacs. It is fairly straightforward and can be done using the instructions given in this article.

    To use Emacs comfortably with Windows-like shortcuts, you will need to enable the Cua mode for it. To enable Cua mode, create the file .emacs in you Linux home folder (i.e., it should be located under ~/.emacs) and add the following lines to it (or just append them to the file if it already exists):

    (cua-mode t)
    (setq cua-auto-tabify-rectangles nil) ;; Don't tabify after rectangle commands
    (transient-mark-mode 1) ;; No region when it is not highlighted
    (setq cua-keep-region-after-copy t) ;; Standard Windows behaviour
    
  2. So far so good, now we have a running Linux and Emacs in it, so it’s time to install OCaml libraries. First, we need to install a number of Linux packages that OCaml needs. Run the following lines from Linux terminal (it can be done both from within graphical shell, or from within a separate Ubuntu terminal run as a Windows applications):

    sudo apt install make m4 gcc pkg-config libx11-dev
    

    Don’t forget to enter the password you’ve created for your Linux account, it might be different from your Windows one. Be patient: installing those packages will take quite some time.

  3. Next, we will install the opam package manager for working with different OCaml libraries. Execute the following lines from Linux terminal:

    sudo add-apt-repository ppa:avsm/ppa
    sudo apt install opam
    opam init -y --compiler=4.09.1 --disable-sandboxing
    eval $(opam env)
    opam install -y dune core batteries utop num menhir
    

    Once done, add the following line to your ~/.bashrc file:

    eval $(opam env)
    

    After that, close your terminal window and start a new one.

    To check that your OCaml is correctly installed, run ocamlc --version from the terminal. You should get the output 4.09.1, which is the version of the OCaml compiler we have just installed.

  4. We’re nearly there. Now we need to install the OCaml support for Emacs. Execute the following from terminal:

    opam install -y tuareg user-setup merlin
    opam user-setup install
    

    The last touch is to add the code completion feature to Emacs. Open Emacs and execute Alt-X package-list-packages. From the list choose company -> Install -> Yes:

_images/company.png
  1. Add the following lines to your ~/.emacs configuration:

    ; Make company aware of merlin
    (with-eval-after-load 'company
    (add-to-list 'company-backends 'merlin-company-backend))
    ; Enable company on merlin managed buffers
    (add-hook 'merlin-mode-hook 'company-mode)
    

    Some additional information about this Emacs mode can be found here.

  2. You’re good to go. To check your setup, create an OCaml file in Emacs (e.g., a.ml) and try to play with some definitions. The editor should highlight OCaml syntax, compile-time errors, and will suggest options for name auto-completion:

_images/tuareg.png

2.3. Installing OCaml from Scratch on Linux

If you’re using Linux, the setup is similar to the one for Windows 10 WSL described previously. Just follow the points above starting from the step 5. If you’re using a distribution different from Ubuntu, make sure to use the corresponding package manager (instead of apt) to get the system packages in the step 6.

2.4. Installing OCaml from Scratch on Mac OS X

OCaml is well supported in Mac OS X, so the installation process is fairly straightforward.

  1. I suggest to use Aquamacs as an Emacs-like editor for work with OCaml. Please, download and install it.

  2. Install the Homebrew package manager for Mac OS X.

  3. Install the following system packages using Homebrew:

    brew install make m4 gcc pkg-config
    
  4. Next, we will install the opam package manager for installing and maintaining different OCaml libraries. Execute the following lines from the terminal:

    brew install opam
    opam init -y --compiler=4.09.1
    eval $(opam env)
    opam install -y dune core batteries utop num menhir
    

    After that, close your terminal window and start a new one.

    To check that your OCaml is correctly installed, run ocamlc --version from the terminal. You should get the output 4.09.1, which is the version of the OCaml compiler we have just installed.

  5. We’re nearly there. Now we need to install the OCaml support for Emacs. Execute the following from terminal:

    opam install -y tuareg user-setup merlin
    opam user-setup install
    

    The last touch is to add the code completion feature to Aquamacs. First, add these lines to your ~/.emacs file (create it if it doesn’t exist):

    ;; Melpa
    (require 'package)
    (add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
    (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
                         ("marmalade" . "http://marmalade-repo.org/packages")
                         ("melpa" . "http://melpa.milkbox.net/packages/")))
    (package-initialize)
    

    Restart Aquamacs. Once it’s reopened, execute company-mode for completion Alt-X package-list-packages. From the list choose company -> Install -> Yes:

_images/mac-company.png
  1. Add the following lines to your ~/.emacs configuration:

    ; Make company aware of merlin
    (with-eval-after-load 'company
    (add-to-list 'company-backends 'merlin-company-backend))
    ; Enable company on merlin managed buffers
    (add-hook 'merlin-mode-hook 'company-mode)
    

    Some additional information about this Emacs mode can be found here.

  2. You’re good to go. To check your setup, create an OCaml file in Emacs (e.g., a.ml) and try to play with some definitions. The editor should highlight OCaml syntax, compile-time errors, and will suggest options for name auto-completion:

_images/mac-tuareg.png

2.5. Installing LLVM and Clang

For some projects, we will be using the LLVM framework, which you can install as follows:

  • Ubuntu or MS Windows 10 with WSL: run sudo apt-get update && apt-get install clang
  • Mac OS X: Install XCode (via the AppStore), run it, go to Preferences, and install the command line tools.
  • Mac OS X (alternative): If you use Homebrew, run brew install llvm.

2.6. Checking your Setup

In order to check your set up, please, make sure to email your GitHub name to the instructor—this is necessary to grant you GitHub access for course-related repositories.

Once you are done installing/updating OCaml and LLVM, please clone this project from GitHub—it is private, but you should have access to it if you have provided your GitHub name.

Once cloned, run make from the project root. You should see the output, meaning that your configuration is complete for the class:

DEFINING O0
DEFINING O1
DEFINING O2
DEFINING O3
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O0 -emit-llvm -S -o factorial-O0.ll factorial.c
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O0 -S -o factorial-O0.s factorial-O0.ll
clang -c -o factorial-O0.o factorial-O0.s
clang -o factorial-O0 factorial-O0.o
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O1 -emit-llvm -S -o factorial-O1.ll factorial.c
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O1 -S -o factorial-O1.s factorial-O1.ll
clang -c -o factorial-O1.o factorial-O1.s
clang -o factorial-O1 factorial-O1.o
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O2 -emit-llvm -S -o factorial-O2.ll factorial.c
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O2 -S -o factorial-O2.s factorial-O2.ll
clang -c -o factorial-O2.o factorial-O2.s
clang -o factorial-O2 factorial-O2.o
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O3 -emit-llvm -S -o factorial-O3.ll factorial.c
clang -fno-stack-protector -fno-asynchronous-unwind-tables  -O3 -S -o factorial-O3.s factorial-O3.ll
clang -c -o factorial-O3.o factorial-O3.s
clang -o factorial-O3 factorial-O3.o
dune build --profile release @install
factorial(10) = 3628800