Useful Links

How I will run your code

Save your program in a file called proj.erl in folders called proj1 and proj2 respectively for phases 1 and 2 of your project. You should have a module called proj exporting a 0-arity main function.

I will test your code in the same environment as the lab machines in MI 302, using the commands

  /usr/bin/erlc *.erl
  /usr/bin/erl -noshell -s proj main

Phase 2 Assignment

For phase 2 of your project, you will write a program that imitates some of the features of the popular linux utility make. You should submit your program in a folder called proj2, and be sure that it runs as described above.


Your program will read from a file called spec.txt (like a simplified makefile). This file will consist of a series of rules. Each rule is structured like

target : prereq1 prereq2 ...

You will notice a few components of the rule:

The meaning of the rule is that the target should be re-generated whenever every one of its prerequisites exists, and either (1) the target does not exist, or (2) at least one of the prerequisites is newer (in terms of file modification time) than the target. Re-generation just involves executing each of the commands in sequence.

Your program will read the spec.txt file and then create a new thread for each target. These threads will monitor the prerequisites of that target at some short interval (say every second), and whenever any prerequisite is modified (and the others exist), then the specified commands are executed. You should execute commands using the os:cmd function in the Erlang module os.

The threads should continue to execute, re-checking at 1-second intervals, until the main thread reads a number (any number) from the command line. At this time all the threads should be halted.


I suggest you write your program in the following steps:

  1. Initially, don't allow comments, ignore prerequisites, and just read the file and write out the targets and the command for each target.
  2. Next, make your program read spec.txt once, and generate threads for each target. Each thread should just run the commands (once) to generate that target and then die.
  3. Now have the threads re-make targets every second, until they are told to die. Have the main thread read a single integer from the command line and then kill all the threads.
  4. Have the main thread send the names of prerequisites to the threads, and the targets should only be re-generated when all its prerequisites exist.
  5. Make is so the threads only re-generate targets when all the prerequisites exist and at least one is newer than the target, as specified above.

Style Requirements

For full credit, your program should be well-documented and easy to follow. Specifically, it should be easy for a non-Erlang programmer to understand what is going on. And of course you are not allowed to use the existing make utility!


Suppose we are in a directory that initially only contains the file spec.txt, consisting of:

a :
  echo "this will go into a" > a

b.txt : index.php a
  cp a b.txt
  head index.php >> b.txt

c : c.cpp
  g++ -o c c.cpp

index.php :
  wget ""

Running your program in this directory should first cause the files a and index.php to be generated, since those targets do not exist, but all of their prerequisites do (vacuously, since they have no prerequisites). They are generated, in any order, by running the echo and wget commands as specified.

After this, the b.txt file should be generated, since it does not exist, and now both of its prerequisites do. This will cause the cp and head commands to be run, as specified, and in order.

And then your program should continue waiting for either an input from the keyboard (indicating it should halt), or for one of the prerequisites to be updated. Notice that the target c never gets generated, since its single prerequisite does not exist.