Commit 48358384 authored by Donjan Rodic's avatar Donjan Rodic
Browse files

added Makefile examples

parent a42d04e6
# Define our tools and parameters.
CC = g++
CXXFLAGS = -std=c++14 -Wall -Wextra
SYSFLAGS = -fopenmp -pthread # <- example, use only those you need
LIBS = # this is also used below, so we can set libraries to link in
# The first target is called "all" by convention.
# Set it "phony" since no file with this name is used for timestamp comparison.
# Here we want to compile our binary and also run it.
.PHONY: all
all: main runmain
# Our executable, built from the object files we wrote.
# The automatic variable $@ expands to the target name and $^ to the dependency
# list.
# We can also use subdirectories for a cleaner hierarchy
main: foo.o helpers/bar.o helpers/bar2.o
$(CC) $(CXXFLAGS) $(SYSFLAGS) -o $@ $^ $(LIBS)
# Compile any .o file if it has a .cpp and .hpp file with the same base name.
# This object (xyz.o) will be recompiled when xyz.cpp or xyz.hpp get changed.
# % is a wildcard (matches e.g. helpers/bar) and the automatic variable $<
# expands to just the first dependency (we want to compile the cpp file, but not
# the hpp).
%.o: %.cpp %.hpp
$(CC) $(CXXFLAGS) $(SYSFLAGS) -c -o $@ $< $(LIBS)
# Execute our main program.
# Important: offer a way to clean up after ourselves!
.PHONY: clean
rm -f *.o
rm -f helpers/*.o
rm -f main
Run on euler (or your local machine, if you have g++ and make installed) to
create and execute the binary executable 'main':
This runs the default 'all' target.
Rerun 'make' and check the output.
Edit any of the cpp files and rerun 'make', which will recompile only that file
and then relink the executable.
To clean up the generated files, run:
make clean
By default, make uses the file called exactly 'Makefile'. We can select others
with '-f'. Run the second Makefile twice and compare the results.
make -f mAkefile2
make -f mAkefile2
make -f mAkefile2 clean
Check the content of the respective Makefiles for more explanations.
Exercise for the reader: change Makefile such that all object files are
generated in a directory called 'obj' (or subdirectories thereof) and the
executable binary is generated in a directory called 'bin'. Hint: 'mkdir -p'
(and run 'man mkdir' to see what '-p' does) This gives a nicer/cleaner directory
structure, and when writing the 'clean' target we don't have to hunt for odd
files in subdirectories of subdirectories.
#include "helpers/bar.hpp"
#include <iostream>
int main() {
std::cout << "hi there!" << std::endl;
return 0;
#include <iostream>
void bar() {
std::cout << "PRINTING FROM " << __FILE__
<< ":" << __LINE__ << std::endl;
// declaration of the function
void bar();
// declaration of the function
void bar2();
.PHONY: all
all: t1
# In this example, we touch (=update the timestamp) a certain target when it's
# recipe (body of make rule) gets executed.
# We also have a prerequisite for that target, which gets executed if the file
# 't1_prerequisite' is newer than the file 't1' (as both are not phony).
# Run this Makefile (make -f mAkefile2) twice and observe the behaviour.
# Manually 'touch t1_prerequisite' and rerun this Makefile.
# Uncomment out the '.PHONY: t1_prerequisite' line, rerun this Makefile and
# observe the difference.
t1: t1_prerequisite
touch t1
#.PHONY: t1_prerequisite
touch t1_prerequisite
.PHONY: clean
rm -f t1*
@# WARNING: make sure there are no files starting with 't1' you want to keep
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