Commit 9b2a2fd0 authored by Marcus M. Darden's avatar Marcus M. Darden
Browse files

Initial commit.

parents
## EECS 281 Advanced Makefile
# How to use this Makefile...
###################
###################
## ##
## $ make help ##
## ##
###################
###################
# IMPORTANT NOTES:
# 1. Set EXECUTABLE to the command name given in the project specification.
# 2. To enable automatic creation of unit test rules, your program logic
# (where main() is) should be in a file named project*.cpp or specified
# in the PROJECTFILE variable.
# 3. Files you want to include in your final submission cannot match the
# test*.cpp pattern.
# Version 4 - 2015-05-03, Marcus M. Darden (mmdarden@umich.edu)
# * Updated build rules for tests
# Version 3.0.1 - 2015-01-22, Waleed Khan (wkhan@umich.edu)
# * Added '$(EXECUTABLE): $(OBJECTS)' target. Now you can compile with
# 'make executable', and re-linking isn't done unnecessarily.
# Version 3 - 2015-01-16, Marcus M. Darden (mmdarden@umich.edu)
# * Add help rule and message
# * All customization locations are cleary marked.
# Version 2 - 2014-11-02, Marcus M. Darden (mmdarden@umich.edu)
# * Move customization section to the bottom of the file
# * Add support for submit without test cases, to prevent submission
# deduction while testing, when code fails to compile
# usage: make partialsubmit <- includes no test case files
# make fullsubmit <- includes all test case files
# * Add automatic creation of test targets for test driver files
# usage: (add cpp files to the project folder with a test prefix)
# make alltests <- builds all test*.cpp
# make test_insert <- builds testinsert from test_insert.cpp
# make test2 <- builds testinsert from test2.cpp
# * Add documentation and changelog
# Version 1 - 2014-09-21, David Snider (sniderdj@umich.edu)
# Vertion 0 - ????-??-??, Matt Diffenderfer (mjdiffy@umich.edu)
# enables c++11 on CAEN
PATH := /usr/um/gcc-4.8.2/bin:$(PATH)
LD_LIBRARY_PATH := /usr/um/gcc-4.8.2/lib64
LD_RUN_PATH := /usr/um/gcc-4.8.2/lib64
# TODO
# Change EXECUTABLE to match the command name given in the project spec.
EXECUTABLE = project0
# designate which compiler to use
CXX = g++
# list of test drivers (with main()) for development
TESTSOURCES = $(wildcard test*.cpp)
# names of test executables
TESTS = $(TESTSOURCES:%.cpp=%)
# list of sources used in project
SOURCES = $(wildcard *.cpp)
SOURCES := $(filter-out $(TESTSOURCES), $(SOURCES))
# list of objects used in project
OBJECTS = $(SOURCES:%.cpp=%.o)
# TODO
# If main() is in a file named project*.cpp, use the following line
PROJECTFILE = $(wildcard project*.cpp)
# TODO
# If main() is in another file delete the line above, edit and uncomment below
#PROJECTFILE = mymainfile.cpp
# name of the tar ball created for submission
PARTIAL_SUBMITFILE = partialsubmit.tar.gz
FULL_SUBMITFILE = fullsubmit.tar.gz
#Default Flags
CXXFLAGS = -std=c++11 -Wall -Werror -Wextra -pedantic
# make release - will compile "all" with $(CXXFLAGS) and the -O3 flag
# also defines NDEBUG so that asserts will not check
release: CXXFLAGS += -O3 -DNDEBUG
release: all
# make debug - will compile "all" with $(CXXFLAGS) and the -g flag
# also defines DEBUG so that "#ifdef DEBUG /*...*/ #endif" works
debug: CXXFLAGS += -g3 -DDEBUG
debug: clean all
# make profile - will compile "all" with $(CXXFLAGS) and the -pg flag
profile: CXXFLAGS += -pg
profile: clean all
# highest target; sews together all objects into executable
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
ifeq ($(EXECUTABLE), executable)
@echo Edit EXECUTABLE variable in Makefile.
@echo Using default a.out.
$(CXX) $(CXXFLAGS) $(OBJECTS)
else
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $(EXECUTABLE)
endif
# Automatically generate any build rules for test*.cpp files
define make_tests
ifeq ($$(PROJECTFILE),)
@echo Edit PROJECTFILE variable to .cpp file with main\(\)
@exit 1
endif
SRCS = $$(filter-out $$(PROJECTFILE), $$(SOURCES))
OBJS = $$(SRCS:%.cpp=%.o)
HDRS = $$(wildcard *.h)
$(1): CXXFLAGS += -g3 -DDEBUG
$(1): $$(OBJS) $$(HDRS) $(1).cpp
$$(CXX) $$(CXXFLAGS) $$(OBJS) $(1).cpp -o $(1)
endef
$(foreach test, $(TESTS), $(eval $(call make_tests, $(test))))
alltests: clean $(TESTS)
# rule for creating objects
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $*.cpp
# make clean - remove .o files, executables, tarball
clean:
rm -f $(OBJECTS) $(EXECUTABLE) $(TESTS) $(PARTIAL_SUBMITFILE) $(FULL_SUBMITFILE)
# make partialsubmit.tar.gz - cleans, runs dos2unix, creates tarball omitting test cases
PARTIAL_SUBMITFILES=$(filter-out $(TESTSOURCES), $(wildcard Makefile *.h *.cpp))
$(PARTIAL_SUBMITFILE): $(PARTIAL_SUBMITFILES)
rm -f $(PARTIAL_SUBMITFILE) $(FULL_SUBMITFILE)
dos2unix $(PARTIAL_SUBMITFILES)
tar -vczf $(PARTIAL_SUBMITFILE) $(PARTIAL_SUBMITFILES)
@echo !!! WARNING: No test cases included. Use 'make fullsubmit' to include test cases. !!!
# make fullsubmit.tar.gz - cleans, runs dos2unix, creates tarball including test cases
FULL_SUBMITFILES=$(filter-out $(TESTSOURCES), $(wildcard Makefile *.h *.cpp test*.txt))
$(FULL_SUBMITFILE): $(FULL_SUBMITFILES)
rm -f $(PARTIAL_SUBMITFILE) $(FULL_SUBMITFILE)
dos2unix $(FULL_SUBMITFILES)
tar -vczf $(FULL_SUBMITFILE) $(FULL_SUBMITFILES)
@echo !!! Final submission prepared, test cases included... READY FOR GRADING !!!
# shortcut for make submit tarballs
partialsubmit: $(PARTIAL_SUBMITFILE)
fullsubmit: $(FULL_SUBMITFILE)
define MAKEFILE_HELP
EECS281 Advanced Makefile Help
* This Makefile uses advanced techniques, for more information:
$$ man make
* General usage
1. Follow directions at each "TODO" in this file.
a. Set EXECUTABLE equal to the name given in the project specification.
b. Set PROJECTFILE equal to the name of the source file with main()
c. Add any dependency rules specific to your files.
2. Build, test, submit... repeat as necessary.
* Preparing submissions
A) To build 'partialsubmit.tar.gz', a tarball without tests used to find
buggy solutions in the autograder. This is useful for faster autograder
runs during development and free submissions if the project does not
build.
$$ make partialsubmit
B) Build 'fullsubmit.tar.gz' a tarball complete with autograder test cases.
ALWAYS USE THIS FOR FINAL GRADING! It is also useful when trying to
find buggy solutions in the autograder.
$$ make fullsubmit
* Unit testing support
A) Source files for unit testing should be named test*.cpp. Examples
include test_input.cpp or test3.cpp.
B) Automatic build rules are generated to support the following:
$$ make test_input
$$ make test3
$$ make alltests (this builds all test drivers)
C) If test drivers need special dependencies, they must be added manually.
D) IMPORTANT: NO SOURCE FILES THAT BEGIN WITH test WILL BE ADDED TO ANY
SUBMISSION TARBALLS.
endef
export MAKEFILE_HELP
help:
@echo "$$MAKEFILE_HELP"
#######################
# TODO (begin) #
#######################
# individual dependencies for objects
# Examples:
# "Add a header file dependency"
# project2.o: project2.cpp project2.h
#
# "Add multiple headers and a separate class"
# HEADERS = some.h special.h header.h files.h
# myclass.o: myclass.cpp myclass.h $(HEADERS)
# project5.o: project5.cpp myclass.o $(HEADERS)
#
# ADD YOUR OWN DEPENDENCIES HERE
# tests
class.o: class.cpp class.h
project0.o: project0.cpp class.h
######################
# TODO (end) #
######################
# these targets do not create any files
.PHONY: all release debug profile clean alltests partialsubmit fullsubmit help
# disable built-in rules
.SUFFIXES:
EECS 281 - Project 0
====================
This example project is a multi-file solution for a simple, but nonexistant
EECS 281 project. Included are the following files:
* Makefile
* project0.cpp
* class.h, class.cpp
* test_class.cpp
* test_data.txt
### Makefile
This is the "EECS 281 Advanced Makefile". It attempts to do all things for all
people in EECS 281. This lofty goal is far from achieveable, but when used
correctly, this Makefile can really "make" your life easy!
There are 3 sections in the file that need to be customized for each project.
* An _EXECUTABLE_ variable needs to be set, following the instructions given in whatever project for which your solution is written.
* A _PROJECTFILE_ variable needs to be set, naming the file with the main() function for your solution.
* A _DEPENDENCIES_ section needs to be edited to include any custom file dependencies your solution requires. Project 0 has two custom dependencies, one for the standalone class and one for the full solution that includes the standalone class.
For more information about how to use this Makefile, see the [documentation
page for make](http://linux.die.net/man/1/make). There will be a segment on
make and this Makefile in discussion section. You can also come to office
hours for additional help with make/Makefile.
### project0.cpp
This is the _PROJECTFILE_ for Project 0, it contains a simple main() that
would be responsible for the execution of a solution. It incorporates a
standalone class, from the files described below.
If you reuse this solution structure and Makefile for your EECS 281 projects,
make sure to put your solution's main() in a file named with the project*.cpp
glob pattern (filename starts with "project" all lowercase, ends with ".cpp").
### class.h, class.cpp
This is a standalone class, for use in an Object Oriented (OO) solution. It
consists of a class declaration (class.h) and a class definition (class.cpp).
Using classes in your solutions has benefits. For starters C++ is an Object
Oriented language, so by learning and using classes, you will be leveraging a
major feature of the language you are required to use in this course. A second
benefit is that the source code modularity that OO programs require can make
your programs easier to write, test, debug, and read.
### test_class.cpp
This file will make a "test executable". It includes a main(), but not the
one from the solution. This main() function is strictly for testing the
standalone class described in the section above.
When used the Makefile included in Project 0, you can build this test with
either 'make test_class' or 'make alltests'.
The Makefile supports testing by automatically creating build recipes for any
source file that matches the test*.cpp glob pattern (filename starts with
"test" all lowercase, and ends with ".cpp"). A file named "testX.cpp" will
automatically be built into an executable named "testX" with either 'make
testX' or 'make alltests'. These tests will not interfere with your solution
main(), can access any modules you write outside of _PROJECTFILE_, and will
not be included in submissions built using the Makefile (either 'make
fullsubmit' or 'make partialsubmit').
### test_data.txt
This is a simple text file that is similar to tests you will include in your
submissions to find "bugs" in the instructor solution. It will be included in
your submissions built with 'make fullsubmit', but excluded in submissions
built with 'make partialsubmit'. Full submissions will be subtracted from your
daily allotment on the autograder, even if your project fails to build. On the
other hand, a partial submission that fails to build will not subtract from
your daily allotment on the autograder.
// class.cpp
//
// The Makefile expects that the project solution has main() in a file
// named project*.cpp
//
// This class is declared in class.h and implemented in class.cpp
#include <iostream>
using std::cout;
using std::endl;
#include "class.h"
void Class::display() const {
cout << "(A, B) = (" << a << ", " << b << ')' << endl;
}
#ifndef CLASS_H
#define CLASS_H
class Class {
long a, b;
public:
Class(long x, long y) : a(x), b(y) {}
void display() const;
};
#endif
// project0.cpp
//
// The Makefile expects that the project solution has main() in a file
// named project*.cpp
//
// The project can be built in a number of ways:
// $ make // An easy way to compile and link everything with O3
// $ make release // ibid.
// $ make all // ibid.
// $ make -R -r // This is what the autograder does!
// $ make debug // Make with debug flag set for gdb and/or valgrind
// $ make profile // For profiling the project code with gprof or others
#include <iostream>
using std::cin;
#include <getopt.h>
#include "class.h"
int main() {
int num_values;
long x, y;
// Use getopt_long here, to get command line options
cin >> num_values;
while (cin >> x >> y) {
Class c(x, y);
c.display();
}
return 0;
}
// test_class.cpp
//
// The Makefile expects that the project solution has main() in a file
// named project*.cpp. For your own testing purposes, .cpp files that
// begin with 'test' can include a main(), that will not conflict with
// the project solution main(). Also, the test*.cpp files will not be
// included in any submission archives.
//
// Tests can be built in two ways:
// $ make test_class // Make the test in test_class.cpp with all other
// // source (and header) files.
// $ make alltests // Make all tests in test*.cpp with all other
// // source (and header) files.
#include "class.h"
int main () {
// Stack
Class a(0, 0);
a.display();
// Heap
Class *b = new Class(1, 1);
b->display();
delete b;
return 0;
}
3
0 0
-1 -1
5 10
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment