You are suppose to know how to write a Makefile already. If you don't, you should learn it as soon as possible because your Makefile must work in all your programming assignment submissions. There are a few tutorials on make on the web. Here are links to some of them. I have not really read through these pages so I cannot guarantee their correctness. Since I don't track these links, if they have moved, just google "makefile tutorial".

If you just want something simple, please see the simple example below.

Please be aware that if you transfer a Makefile from a Windows environment to a UNIX environment, chances are, it will not work. The reason is that a line in a text file in Windows ends with "\r\n" while a line in a text file in UNIX ends with just "\n". The extra "\r" can confuse make on UNIX machines. But I'm sure you can write a small program to fix that.

Compiling Your Code
If you are writing your program in C or C++, you must use the g++ compiler to compile your code and you must include the following commandline options to compile any part of your code (the last part in the commandline is required for all networking-related assignments):
    -g -Wall -std=c++11 -DLOCALHOST=\"localhost\"
The -g commandline option turns on debugging. The -Wall commandline option turns on all the required g++ warnings (compiling with this option can find many simple mistakes in your programs). The -std=c++11 commandline option makes sure that you are using the 2011 C++ Standard There are also the 2014 and 2017 C++ standards. If you want to use these (and use -std=c++14 or -std=c++17), that would be perfectly fine. But you must not use an earlier or a later C++ standard. The last commandline option says that all instances of LOCALHOST in the source code must be replaced by "localhost" (the double-quotes are required and it must be specified in the above manner, i.e., with a back-slash before a double-quote character). The reason it must be done this way is that "localhost" may not work in certain systems and you must not hard-code "localhost" in your source code. When the grader grades, the grader is not permitted to modify your source code, but the grader can use a different commandline to compile your code without deducting any points.

Finally, if your program needs them, you should also link to multithreading and networking/socket libraries that came with the system. (You are not permitted to include 3rd-party multithreading and networking/socket libraries.)

For all programming assignments, you must use the g++ compiler that came with the 32-bit Ubuntu 16.04 system. Please understand that we will not accept any other compiler to be used to compiler your program for grading. If you code only works when it is compiled with a different version of the g++ compiler, you will not get any credit for it. To see what version of g++ you are running, please run the following command in a Terminal window:

    g++ --version
On a 32-bit Ubuntu 16.04 system, you should see that you are running g++ version 5.4.0. If you have accidentically upgraded your system and end up with a different version of g++, please contact the instructor. Most likely, you will have to delete your 32-bit Ubuntu 16.04 system and reinstall everything to make sure that the grader will be able to compile your code!

If your program cannot be compiled with a required compiler and run on a required system, your program will not be graded (and it will get a grade of zero). Please understand that we are not permitted to write code for you (or fix your code to get it compiled).

Since grading of all programming assignments must be done on a 32-bit Ubuntu 16.04 machine running inside VirtualBox, it's imperative that you make sure that your code can be compiled and run on a 32-bit Ubuntu 16.04 machine running inside VirtualBox. Please understand that even if your code runs perfectly on some other systems, we cannot give you any partial credit for that.

We will evaluate your submission by copying all the files you have submitted into an empty directory on the grader's 32-bit Ubuntu 16.04 machine running inside VirtualBox and then type the make command specified in the "Compiling" section of the respective spec. Minor variation (such as using gmake) is allowed, but you must describe in details how to compile your code near the top of your README file. The grader is not permitted to use a visual tool or an IDE to compile your code. If this does not produce the desired executable(s), you will probably lose a lot of points. You may lose quite a few points if the grader has to debug and modify your Makefile in order to get your code to compile. How many points you will lose depends on how hard it is for the grader to get your Makefile to work. You will receive a score of zero if we cannot find a way to compile your code without modifying your source code.

Here are some additional requirements (sorry about redundancy with the programming assignment specs):

  • When the following command is invoked at the UNIX prompt:
        make clean
    all binary files created during compilation (.o files, .gch files, executable files, etc.) must be removed.

  • To compile your code, you must use g++ (even if your program is completely written in C) and you must use the g++ that came with the 32-bit Ubuntu 16.04 system. No other compilers will be permitted. If your code can only be compiled using another compiler, you will get a score of zero for your assignment. Therefore, when you develop your code, it's imperative that you avoid using something that's not g++ or running it on the wrong platform!

  • You must use "-g -Wall -std=c++11 -DLOCALHOST=\"localhost\"" in your Makefile when you compile with g++ (i.e., the command used to compile your program must start with "g++ -g -Wall -std=c++11 -DLOCALHOST=\"localhost\"") and you should eliminate all compile-time warning messages because they are telling you that something is not just right in your code. The -DLOCALHOST is only required for a networking-related assignment.
By the way, if you think you have a perfectly working Makefile but when you run "make", you get an error message saying it does not know how to make a target, it's probably because you have created or modified your Makefile on a Windows machine and what you have is a DOS/Windows text file, which is not quite compatible with a Unix text file. In this case, you can either use "gmake" or run "dos2unix" to convert a DOS/Windows text file into a Unix text file.

When you compile, if you get warning messages saying that certain .c or .h file has no newline at end of file, then it's cause by the same problem (i.e., you have created these files in Windows). Please run "dos2unix" to convert such a DOS/Windows text file into a Unix text file.

A README file is the documentation of your submission. The filename you must use for a README is "pa#-README.txt" where "#" is the assignment number. You must download a README file template from the respective spec, edit it with a text editor by supplying all the required information, and then include it with your submission. You must not delete any line from the README file template or the grader will have to deduct points.

Such a README file includes the following sections:

  • A section called "BUILD & RUN" - This section contains instructions for creating the executable for your assignment. Since the grader can only grade on a 32-bit Ubuntu 16.04 machine running inside VirtualBox or on viterbi-scf1.usc.edu, you must tell the grader which system to use to grade your submission. You are required to replace the first "(Comments?)" in this section with the environment to grade your submission. The only permitted systems are "VirtualBox with 32-bit Ubuntu 16.04" or "viterbi-scf1.usc.edu".

    You are required to replace the 2nd "(Comments?)" in this section with the command the grader must type to compile your program. This command should be the "make" command mentioned in the spec. You will lose 0.5 point each if a "(Comments?)" in the answer part of this section is not replaced by a proper response. Please understand that the ONLY acceptable compiler is g++. If you ask the grader to use anything else, the grader will not be allowed to comply and you will get a zero for your assignment.

  • A section called "SELF-GRADING" - This section contains your assessment of your submission. Each item in this section corresponds to an item in the grading guidelines. You are expected to run through the grading guidelines and give each item a grade. You must replace every "?" in this section with a numeric value (which should be a number ≥ 0 for anything in the "plus points" section and a number ≤ 0 for anything in the "minus points" section). If you give yourself a score of 0 for an item in the "plus points" section, the grader will give a 0 for that item and will not grade that item. You will lose 0.5 point each if a "?" in this section is not replaced by a proper value or if such a line is omitted.

  • A section called "BUGS / TESTS TO SKIP" - If there is a test that you don't want the grader to run because it may cause you to lose additional points elsewhere, please clearly state it in this section. Please read the instructions there. You are required to replace the "(Comments?)" in this section with either the word "none" or whatever appropriate information you want to provide. You will lose 0.5 point each if the "(Comments?)" in this section is not replaced by a proper response or if such a line is omitted.

  • A section called "ADDITIONAL INFORMATION FOR GRADER (Optional)" - If you have additional information for the grader, you can add them here. If you have no additional information for the grader, you can just leave it blank.

  • A section called "OTHER (Optional) - Not considered for grading" - This is just for you. The grader will not read this section even if you ask the grader to read it. You do not have to replace the "(Comments?)" in this section.
For this class, there is no requirement to use a fancy Makefile. You can just use a simple Makefile that contains 2 lines. The first line is the "target line" and it looks like:
    target: files
where target is the "target" of your "make" command and files is a space-separated list of source files and header files that make up your program.

For example, if you need to type "make foo" to create your executable, then "foo" is the "target". Typically, the "target" is the name of your executable file. If you need "foo.c", "bar.c", and "bar.h" in order to build the foo executable, then the first line of your Makefile can look like:

    foo: foo.c bar.c bar.h
The way you should read the above line is, "The foo target depends on foo.c bar.c bar.h." The idea here is that if any of files the target depends on changes and if you type "make target", the command in the line immediately follow the target line will get executed. There must be no blank character at the beginning of a target line.

The 2nd line is a line of command and it must begin with a <TAB> character and follow by a Unix/Linux command. Our simple Makefile can look like:

    foo: foo.c bar.c bar.h
            g++ -g -Wall -std=c++11 -DLOCALHOST=\"localhost\" -o foo foo.c bar.c
The leading blank space you see in front of the 2nd line must be a <TAB> character or this won't work! Also, there must be no intervening line between the target line and line of command. Using the above Makefile, if you type "make foo" and if foo.c, bar.c, or bar.h has changed, the "make" program will run the "g++ -g -Wall -std=c++11 -DLOCALHOST=\"localhost\" -o foo foo.c bar.c" command. (The command doesn't even need to have anything to do with compiling a program!)

In general, there can be multiple sections in a Makefile and a target can depend on other targets in another section of the Makefile (therefore, we can have a tree of dependencies). Each section starts with a target line and followed by one or more lines of commands. The target line must be have no leading space characters and each line of command must begin with a <TAB> character and you cannot have a blank link within a section. When you type "make target", the "make" program search the Makefile for a section whose target line contains the target of your "make" command, check the dependencies, and execute the corresponding lines of commands. For more details, please check out the recommanded tutorials mentioned at the top of this web page.

All programming assignments also require that when you type "make clean", you must delete all generated binary files when you typed "make target" where "target" is the name of your executable file. In that case, your minimum "Makefile" must also contain a second section whose target is "clean" that depends on nothing and the command to execute should delete all generated binary files. The following is an example of such a file:

    foo: foo.c bar.c bar.h
            g++ -g -Wall -std=c++11 -DLOCALHOST=\"localhost\" -o foo foo.c bar.c

    clean:
            rm -f foo *.o
If you type "make clean", it will delete the file "foo" and all the files with a ".o" filename extension. If you create additional binary files (such as ".gch" files) when you "make", you must change the last line so that they also get deleted when you type "make clean".

How do you make sure that make would work? It's actually very simple.
  • Create a Makefile first time you need to compile your code. Don't wait till the last minute.

  • If you do your development on Windows or Mac OS X and expect your code to just compile and run on a 32-bit Ubuntu 16.04 system, you will soon find out how unrealistic your assumption is. I would leave at least 2 days for porting for small programming assignments and 5 days for porting large programming assignments from Windows/Mac to Ubuntu 16.04.

  • Write a rule in your Makefile to generate a submittable file in the right format (i.e., ".tar.gz"). Do this early! You can also think of this as generating a backup copy of what you have done so far. Copy the backup copy to another place in case you accidentically erase all your files.

  • Testing! Verify your submissions. Create an empty directory on your 32-bit Ubuntu 16.04 system, unpack your test submission, and type make in it! Then run through all the commands in the grading guidelines to make sure that you get a perfect score and check the "minus points" section to make sure that you have no deduction. If something doesn't work, fix it right away.

  • Have a working copy ready for submission. When it's 2 hours away from the deadline and your code is not completing working, you should probably consider doing the following.

    1. Fix your code so that it compiles and runs.

    2. Create a submission from your working code and keep it as a backup in case you can't fix your bugs when deadline comes.

    3. Repeat this as you fix more bugs.