The pibake script

From Compilers
Jump to navigation Jump to search

Like all our other compilers, the one in Lab 4 is an OCaml program that inputs a text, the source code of a program in picoPascal, and outputs a text – this time, the same program translated into ARM assembly language. Consequently, the compiler itself can run on any machine, including the x86-based machines in the lab, or an ordinary laptop. What's not possible without installing special software is to assemble and link the compiler output, or to run the resulting object code.

Typing make in the lab4 directory will build the compiler as usual, but the command make test that's typically used to run regression tests has been replaced by three commands: make test0 will compile the whole test suite, but only compare the object code with the previous version stored in the test files, and not try to run it. The command make test1 compiles the test cases, then assembles them using a cross-assembler and runs them on an emulator called qemu-arm. The third option, test2, runs the code on a real ARM chip: I've set up an immense server farm of Raspberry Pi's somewhere on the internet to act as a batch service, and make test2 submits the object code for each test case as a batch job and checks the results. Actually, I added a fourth option, make test3, that uses qemu-arm, but remotely on the lab machines via ssh, in case you can't get qemu-arm working on your own machine.

There's a shell script tools/pibake that mediates the process of submitting batch jobs, and is called with the assembly code for each test. It generates a shell script in which the assembly code is embedded, and uses the Secure Shell protocol ssh to submit it to a machine called jaune[1] for execution. It goes like this:

$ make test2-digits
*** Test digits.p
./ppc -O2 test/digits.p >b.s
../tools/pibake b.s >b.test
+ gcc -o b.out /home/guest/lib/pas0.o b.s
+ ./b.out
sed -n -e '1,/^(\*<</d' -e '/^>>\*)/q' -e p test/digits.p | diff - b.test
*** Passed
Our Raspberry Pi based server farm (artist's impression)

Here you can see the picoPascal compiler being run on the source program test/digits.p to produce an assembly language file b.s. Then pibake is invoked to assemble and run it, capturing the output in a file b.test. The next two lines show commands executed on the jaune server: first using gcc to assemble the code and link it with the library pas0.o, a precompiled copy of which is conveniently located on the target machine; then running the object code as a native program on the ARM.[2] Finally, the output of the program is compared (on the host) with the expected output contained in the test file.

The process of authentication with the server named jaune uses a crypto key guest_rsa that is stored in the tools directory. For reasons of security, that key is not provided as part of the Mercurial or Git repository that you clone to begin the lab exercises, but must be installed separately. If you invoke the pibake script on one of the Lab machines, then the script is smart enough to find and install the key for you. Elsewhere, you must obtain the key yourself and put it in the tools directory; you can find the file you need as /users/mike/pi/guest_rsa on the Lab machines – or, in case of need, Mike will e-mail it to you.

I've introduced a rudimentary mechanism that aims to prevent batch jobs from different people from interfering with each other: the batch job works inside a directory named according to your user name on the host machine. That is not enforced, however. There's no provision for avoiding interference between two simultaneous batch jobs from the same person, and in fact there's no mechanism to stop you from using the login token to connect to jaune and do whatever takes your fancy. No mechanism, that is, apart from the forbidding phrase, Tout abus sera puni.

ecsbake: an alternative

As an alternative to pibake, there's a script ecsbake that uses Qemu on the lab machines to run your ARM assembly language programs. Rather than use a shared account, this script uses your own account, and assumes that it can log in by invoking

$ ssh

If logging in requires a password, then you will be prompted for it. The script becomes much less tedious to use if you create your own crypto key with ssh-keygen and install it on, because then the testing process (with make test3) becomes totally automatic, and you won't need to keep typing your password.

The script also assumes that your username on the lab machines is the same as your local username. If that's not the case – for example, if your remote username is u23abc, then you can create a file .ssh/config under your home directory and in it put the following lines:

  User u23abc

(the second line is optionally indented by convention to show it belongs with the line above). This will cause ssh always to try logging you in as u23abc on the lab machines.

  1. because it is housed in a yellow plastic case!
  2. Although we use the gcc program for assembly and linking, that does not mean we are using the Gnu C Compiler. It's just that the gcc command provides a convenient way to invoke the assembler and linker with all the standard libraries.