CS 70

Homework 3: Make Your Makefile

Now it’s time to make your own Makefile! The Makefile will contain all the compilation and linking steps to make an executable called our-movie. You and your partner (together or individually) should complete the written questions in Part 1 before working on this part.


In the asciimation directory, you'll find a file called our-movie.cpp, which contains a main function. There are also two pairs of header/implementation files,

  • sprite.cpp and sprite.hpp, which you’ll use to create ASCII-art–based “characters”
  • asciimation.cpp and asciimation.hpp, which you’ll use to coordinate the “characters” on the screen

Reminder: Compiling by Hand

If you compiled this code by hand, you would have to run several complex commands,

clang++ -c -std=c++17 -g -Wall -Wextra -pedantic -isystem /usr/include/opencv4 our-movie.cpp

to build the object file our-movie.o;

clang++ -c -std=c++17 -g -Wall -Wextra -pedantic -isystem /usr/include/opencv4 asciimation.cpp

to build the object file asciimation.o;

clang++ -c -std=c++17 -g -Wall -Wextra -pedantic -isystem /usr/include/opencv4 sprite.cpp

to build the object file sprite.o; and, finally,

clang++ -o our-movie -std=c++17 -g -Wall -Wextra -pedantic our-movie.o asciimation.o sprite.o -lopencv_imgcodecs -lopencv_core -lopencv_imgproc -lopencv_video -lopencv_videoio

to link the object files and various library files into the executable our-movie. (Note: All the OpenCV-related include options are explained in the hints at the bottom of the page.)

Remembering all the different includes and arguments for clang++ is a pain, and you will also have to figure which commands you need to rerun if you make changes to one or more files. A makefile for the project allows you to figure things out once and then let make decide what needs to be rebuilt for later builds.

Task: Create Your Makefile

Create a makefile for your project (which, by convention, is called Makefile when there is just one) in the asciimation directory with all of the commands you’ll need to compile the our-movie executable. You will be graded on how “well” your Makefile performs; for example, compiling only what’s necessary for any given change and doing those compilations correctly.

Include both the all: and clean: targets in your Makefile.

If you're looking for an example you can use as a starting point, the segfault-generator directory contains an example of a very basic Makefile, as did the make exercise that you saw at the start of the written part of this assignment (which also had more advanced examples, with variables).

Note that you do not have to comment your Makefile as we did in our example. We added those comments for your benefit! For basic makefiles like the ones we will use in CS 70, it's probably not necessary to add comments. (Of course you can always include comments if you want.)

Helpful Hints

It's just called Makefile

By default, the make program looks for a file called Makefile. If you wanted to have lots of make files, you could use the extension .mak, but, by default, the name is Makefile with no file extension. And yes, it's a capital M at the front.

Test Your Makefile (Use cs70-make)

Once you write your Makefile, you should be able to successfully run cs70-make or make to generate any of the .o files, and to link the .o files together into the executable our-movie.

  • Duck speaking

    Why would I use cs70-make rather than make?

  • LHS Cow speaking

    The cs70-make program explains everything its doing and why, which can be helpful for checking that your Makefile is working properly.

  • RHS Cow speaking

    It's also often more likely to give an error when you've made a mistake in your Makefile. Sometimes, regular make assumes that you're an expert and you meant to do something weird.

Indent with Tabs (in Makefiles)

The syntax for Makefiles requires that the line below the target and dependencies begins with a literal tab character followed by the command it should run. Check the example Makefile you were given for examples. Note that in the bottom bar in VS Code there is a convenient way to switch between using tabs/spaces for a given file. (If you have the Makefile support that VSCode offers to install, it will automatically set the indentation character to a tab in Makefiles.)

Headers that Include Headers

Remember that a header file can include another header file. If a .cpp file includes a .hpp file that includes another .hpp file, it depends on both of them! That is, if either header file changes, the .cpp file should be recompiled to stay up-to-date.

Fancy Makefile Tricks Are Optional

You don’t have to use the fancy tricks described on the Makefile resource page (or any of the terrifying shortcuts found on the internet)—if your Makefile doesn’t use any tricks fancier than the example provided for segfaultGenerator, that’s fine.

Using the OpenCV Library

Like Homeworks 1 & 2, ASCIImation uses OpenCV, this time to generate a video. So your code that uses OpenCV will need the same -isystem /usr/include/opencv4 option when you compile it and depends on a bunch of libraries added when linking. The video parts of OpenCV need access to even more parts of the library than our previous projects. If you give the name OPENCV_LIBS to all of those libraries at the top of your Makefile,

OPENCV_LIBS=-lopencv_imgcodecs -lopencv_core -lopencv_imgproc -lopencv_video -lopencv_videoio

then you can link in all the extra libraries by including OPENCV_LIBS in your compilation command. For example, if generateSegfault required opencv (it doesn’t, but just as a hypothetical), you’d write the following line to do the linking:

    clang++ -o generateSegfault -g -std=c++11 -pedantic -Wall -Wextra generateSegfault.o helloSayer.o $(OPENCV_LIBS)

To Complete This Part of the Assignment…

You'll know you're done with this part of the assignment when you've done all of the following:

(When logged in, completion status appears here.)