1 Introduction and purpose
You will not write any C code in this project. Instead you will just write a makefile to compile some code that you are
being given. This is a small project, which has only public tests and will not be graded for style. So there is just a short
time to do it, in order to leave more time for other projects that are larger and more difficult.
We are supplying you with some small C functions in several source files (with associated header files), along with
three different programs that use the functions. The programs call the functions and just print some integers based on
the values in some arrays. What you have to do is to look at the source files for the three programs and figure out the
commands that would be needed to compile them to produce object files and to link the resulting object files to create
the three executables from them, figure out which files each compiler–generated file depends on, and write a makefile
that will do the compilation and linking.
Before starting to write anything, study your lecture notes about make and makefiles, and study the small lecture
example makefiles. If you aren’t sure about anything that they’re doing, ask in the TAs’ office hours in advance.
2 Supplied code
The project tarfile project04.tgz contains the following files:
array-print.c, array-sum.c, range-fill.c, row-compare.c, and row-sum.c: These source files contain simple
utility functions that perform some operations on two–dimensional arrays of integers.
array-print.h, array-sum.h, range-fill.h, row-compare.h, and row-sum.h: These are header files with the prototypes for the functions that are defined in the source files above.
main.c, program1.c, and tester.c: These are the main programs that call the functions defined in the files mentioned
above (the programs call different functions).
All this code does exactly what we want. Do not change it in the slightest. Look at it only to figure out how to
compile and link it to create the three executable programs. You really don’t even need to understand what the code is
doing other than beyond figuring out how to compile and link it.
3 Makefile to be written
• In the project04 directory you must write a makefile, named Makefile (its name must begin with an uppercase
‘M’), which will build three programs main.x, program1.x, and tester.x (so it must have these three targets)
from the three files main.c, program1.c, and tester.c and the other source files. You can tell which object files
have to be linked together to form each executable by looking at what functions the main programs are calling.
And you should be able to see what files have to depend on what other files in by looking at the source files.
• Your Makefile must also have a target all, which will build all three executable programs main.x, program1.x,
and tester.x. It should be the first target, so either running just make, or make all, will build all three programs.
Note that an example makefile from lecture illustrated the correct way that an all target should be written.
• Your Makefile must use the five gcc compilation options we are using this semester (which are -ansi,
-pedantic-errors, -Wall, -fstack-protector-all, and lastly -Werror), which were mentioned in the first
project, to build object files. (But it should not use these options when linking object files to form executable
Your Makefile should not explicitly repeat all five options in every invocation of gcc; they should be added to
compilation commands via the makefile macro CFLAGS, as long as the macro is added to every command that is
compiling a source file. (When you compile code on Grace by typing gcc in a shell, these options are enforced
via an alias for gcc that is added as a result of the account setup steps you made early in the semester. However,
a makefile does not recognize shell aliases. This is why the options must be explicitly used in a makefile.) Your
makefile should also use the macro CC for the name of the compiler to use.
© 2023 L. Herman; all rights reserved 1
• Your makefile must use separate compilation– for each of the three executable programs, each source file (e.g.,
array-print.c) needed to form that program must be separately compiled, then the resulting object files must
be linked together to form the executable. (So your Makefile must also have additional targets for all object files.
Note that there are eight source files, so eight object files should be created by your makefile.)
• Your Makefile should not explicitly compile header files (i.e., do not pass them as arguments to gcc).
• Your Makefile must also have a target named clean that will not create any files but will instead delete all the
compiler–generated (object and executable) files that are created by the compilation commands in your makefile.
• Your makefile should have all needed dependencies, otherwise programs may not get built correctly. (if some
dependencies are missing make would not perform some necessary compilations.) But it should not have any
unnecessary dependencies, because that would lead to make performing compilations that are not needed.
• Your makefile can only use features that were covered in class this semester.
A Development procedure review
A.1 Obtaining the project files, compiling, checking your results, and submitting
Log into the Grace machines and use commands similar to those from before:
tar -zxvf ~/216public/project04/project04.tgz
This will create a directory project04 that contains the necessary files for the project. You must have your coursework in your course disk space for this class. Your Makefile must be in the project04 directory.
There are eleven public tests for this project, and no secret tests. These tests are written in languages most students
don’t know, and you don’t need to understand the code for these tests in order to write your Makefile. So in order to
avoid confusion, we haven’t given you the test programs, so you cannot run the tests yourself on Grace. (There are also
no output files for the tests.) But instead we explain here what the tests are testing, and the next section explains how to
test (before submitting) whether your Makefile passes the tests.
1. The first test tests whether your Makefile correctly builds main.x.
2. The second test tests whether your Makefile correctly builds program1.x.
3. The third test tests whether your Makefile correctly builds tester.x.
4. The fourth test tests whether your Makefile’s all target works, is written correctly, and is in the correct place in
5. The fifth test tests whether your Makefile is using separate compilation everywhere.
6. The sixth test tests whether your Makefile is explicitly compiling header files, which should not be done.
7. The seventh test tests whether your Makefile’s clean target removes all compiler-generated (executable and
8. The eighth test tests whether your Makefile is using the macros CC and CFLAGS, instead of repeating the compiler
name and the compilation options in every rule, and whether it is using the exact names CC and CFLAGS. (This test
also expects that you are using the correct compilation options.)
9. The ninth test tests whether your Makefile has any missing dependencies.
10. The tenth test tests whether your Makefile has any extra unnecessary dependencies.
11. The eleventh test tests whether your Makefile is using the required compilation options for creating all object
The tests do not test for some “stylistic” properties of makefiles. In later projects where you will also have to write
makefiles, these stylistic properties may be checked manually. (If you have questions about whether your makefile is
stylistically correct you can ask in the TAs’ office hours.) Note that even if your makefile correctly builds the three
programs, it might still fail tests other than the first three on the submit server. Even if your makefile is missing some
rules entirely it could pass the first three tests but still fail later ones.
© 2023 L. Herman; all rights reserved 2
A.2 Testing your Makefile, and submitting
Before you submit you must test your Makefile yourself. (If your Makefile doesn’t compile the programs on Grace
it definitely won’t compile them on the submit server.)
• The first thing to test is whether the three separate commands make main.x, make program1.x, and make
tester.x create the three programs. Besides seeing the three programs in the directory, you should also see eight
object files, one created for each source file.
• The next thing to check is that your clean target removes all executable and object files, but nothing else. First
make a copy of your entire project04 directory using cp -r (for example, if you are in the main ~/216
directory, you can use cp -r project04 project04-copy or a similar command), then run make clean in
the project04 directory. You should still see all eight source and all five header files– none should have been
removed– but you should not see any object or executable files. (The purpose of making a copy of the directory
first is so you will have a backup in case anything is incorrectly removed by your clean target.)
• After running make clean, run the three commands make main.x, make program1.x, and make tester.x
again, to ensure that your makefile will build the programs correctly when there are no executable or object files
already in the directory. This is the situation in which your makefile has to work on the submit server– being able
to build the programs when there are no executable or object files in the directory– so you should ensure it works
right in the same circumstances. (If there are already some executable or object files in the directory when you
try to build the programs your makefile may seem to be working correctly, even if it is missing dependencies or
has other problems.)
• Then run make clean again and then make all and ensure that everything is also built correctly in that case as
well. Then run make clean and make and you should get the exact same results.
Running submit from the project04 will submit your makefile. After submitting you must then log into the
submit server and verify your makefile worked correctly there. If your makefile fails some tests on the submit server,
carefully identify what commands you would have to use to manually compile each source file to an object file, and to
link the necessary object files to form each executable. Then run make clean, and run make -n on each target (object
and executable file) in your makefile one at a time, and see if the commands that are printed are the ones that would be
correct for creating that target.
If you are failing either the ninth or tenth test (missing dependencies or extra unnecessary dependencies) then for
each source and header file: (a) carefully determine which object and executable files would have to be recreated if that
file was changed; (b) then create all of the executable and object files so they’re up to date; (c) then use touch on that
source or header file to simulate it changing; (d) then run make -n to see whether your makefile will cause make to
perform the right commands to create the object and executable files that you determined should be recreated when that
file changes. You can ask for help in the TAs’ office hours if needed, after you have already tried doing this yourself
and can show the TAs your results. The TAs will not help you unless you have first at least tried testing your Makefile
yourself. (How to do this is described above.)
If you fail other tests on the submit server and you’re sure your makefile is correctly building the three executable
programs, other things to check for are that your makefile has the right name (it must be named Makefile), that it
is using the required gcc compilation options, that it is using separate compilation, that it is not explicitly compiling
header files, and that its clean target is removing all object and executable files.
A.3 Grading criteria
Your grade for this project will be based on:
public tests 100 points
Since your Makefile is not being graded for style, and it is not C code, you are not required to write comments in
it. However, it is recommended that you comment it. You will have to write makefiles for other future projects as well,
so documenting how your makefile does things will just help you remember how your makefile for this project works
when you have to write other makefiles later.
© 2023 L. Herman; all rights reserved 3
B Project–specific requirements, suggestions, and other notes
• Check the spelling carefully of filenames and commands (including command arguments) in your Makefile.
Even one mistyped character can cause your Makefile to not work right. (Of course if you test your Makefile
as described in Section A.2 you should find problems if there are any.)
• Do not change any of the source or header files supplied in the project tarfile, or add any source or header files.
Your Makefile will be tested on the submit server using our versions of these files.
• There are many features of make that were not explained in class, because they are difficult for a beginner to use
correctly. Your Makefile is only allowed to use the features of make that were covered in class. If you use
features not explained in class: (a) your submission may not compile on the submit server for technical reasons
not worth explaining here, (b) the TAs will not be able to help you fix your makefile in office hours, and (c) you
will lose significant credit.
• For this project you will lose one point from your final project score for every submission that you make in
excess of ten submissions. (Since you are not writing any C code there won’t be any such thing as a noncompiling
C Academic integrity
Please carefully read the academic honesty section of the syllabus. Any evidence of impermissible cooperation on
projects, use of disallowed materials or resources, publicly providing others access to your project code online, or
unauthorized use of computer accounts, will be submitted to the Office of Student Conduct, which could result in an
XF for the course, or suspension or expulsion from the University. Be sure you understand what you are and what you
are not permitted to do in regards to academic integrity when it comes to projects. These policies apply to all students,
and the Student Honor Council does not consider lack of knowledge of the policies to be a defense for violating them.
More information is in the course syllabus – please review it now.
The academic integrity requirements also apply to any test data for projects, which must be your own original
work. Exchanging test data or working together to write test cases is also prohibited.
© 2023 L. Herman; all rights reserved 4