This lab is designed to help you feel comfortable using GNU Make, one of the oldest and still most-common build tools; as well as with many-file C projects.

Your task:

We would recommend working with a partner, but it is also fine if you do this alone.

  1. Download make-lab.tar (you can do this using the link on this page, or from a command line via wget https://www.cs.virginia.edu/~cr4bd/3130/F2024/files/make-lab.tar)

  2. Expand it using tar xvf make-lab.tar

  3. Read enough of the files to get an idea what they do. Then build them with clang *.c and run ./a.out to verify your understanding. Ask a TA for help if you are not sure you fully understand.

  4. Add a Makefile in the resulting make-lab directory, which

    • has rules for the following
      • building each .c file into a .o file
      • combining cheer.o and grunt.o into a library (either libsay.a or libsay.so)
      • combining the library and guesser.o into program guesser
    • has CC, CFLAGS, and LDFLAGS we can edit
    • make all creates guesser and its dependencies
    • make clean deletes all files that make can recreate

    Your Makefile must have correct dependencies for all rules, so for example,

    • running make twice in a row without editing anything does not cause anything to rebuilt the second time
    • editing say.h and running make should cause all files to be rebuilt
    • editing any .c file and running make causes its .o file to be rebuilt, along with the library and/or program if they depend on the .c file
      • Note: if you chose library format libsay.a, then guesser should be rebuilt if libsay.a changes; but if you chose library format libsay.so, then guesser should not be rebuilt if libsay.so changes, only if say.h or guesser.c change.
    • editing cheer.c or grunt.c should cause libsay and possibly guesser to be rebuilt, but should not cause guesser.o to be rebuilt

    Also, your Makefile should not rely on built-in rules1; you can test this using make --no-builtin-rules ... instead of make ....

  5. Either:

    • Place a comment (line starting with #) at the top of your Makefile indicating who you worked with and submit your Makefile to the submission site. (If working with a partner, both must submit.) and/or
    • Show a TA your Makefile. They may ask you to show it working, or to look at its contents, or both.

Refer to the complation and libraries and makefiles reading and/or the corresponding C material for information on how to achieve these goals. We recommend you read it in full, discussing it with a partner and asking clarifying questions of TAs as you go, then return to the tasks above.


  1. make has some default rules, for example for building .o files from .c files, intended to allow Makefiles to avoid boilerplate for common tasks. For this lab, we want to write all the needed make rules explicitly.↩︎