I don’t know much about creating Makefiles, but I’ve been reading the make manual and I have made some progress. My Makefile works and does what I want.
My situation usually involves between 1 and 3 different program needed to be compiled and sent to my TA for marking and such via a webform. The structure of each application is ‘prog.c’, ‘prog_lib.h’, and ‘prog_lib.c’. In the past, I have been creating separate directories for each program and creating separate Makefiles for each directory to build the program contained within. I then tar each folder and submit them separately.
Recently, the TAs have been asking for all source files to be in one directory and one Makefile with the various targets to be built so their marking applications can work without any human intervention.
I was wondering how someone more experienced would improve this Makefile and how my situation in general is usually solved? I would like to reduce the amount of typing I need to do when I move on to my next assignment and have to update several places.
Here is my Makefile:
ASSIGNMENT = 3 TARNAME = Assignment$(ASSIGNMENT).tar.bz2 CC = gcc CFLAGS = -O2 -Wall -ansi -pedantic -W # I like warnings LDFLAGS = -lm DEBUG = -g # to resolve symbols in GDB and valgrind FREQ_OUT = frequency_table FREQ_SOURCES = frequency_table.c frequency_table_lib.c FREQ_OBJECTS = frequency_table.o frequency_table_lib.o DECODE_OUT = decode DECODE_SOURCES = decode.c decode_lib.c DECODE_OBJECTS = decode.o decode_lib.o SOURCES = $(FREQ_SOURCES) $(DECODE_SOURCES) OBJECTS = $(FREQ_OBJECTS) $(DECODE_OBJECTS) OUT = $(FREQ_OUT) $(DECODE_OUT) .PHONY: info info: @echo -e 'make info\n' \ '\tmake all \t\t\tMake all targets\n' \ '\tmake frequency_table \t\tMakes frequency table\n' \ '\tmake decode \t\t\tMakes decode\n' \ '\tmake dist \t\t\tMakes tar archive of sources and Makefile\n' \ '\tmake clean \t\t\tRemoves all the object files and executables\n' \ '\tmake distclean \t\t\tPerforms clean and removes tar archive' .PHONY: all all: $(OUT) $(FREQ_OUT): $(FREQ_OBJECTS) $(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(FREQ_OBJECTS) -o $@ $(DECODE_OUT): $(DECODE_OBJECTS) $(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(DECODE_OBJECTS) -o $@ .o: $(CC) -c $(CFLAGS) -o $@ $< .PHONY: dist dist: $(SOURCES) @echo 'Creating tar archive. See $(TARNAME)' tar cvjf $(TARNAME) $(SOURCES) $(wildcard *_lib.h) Makefile .PHONY: clean clean: rm -f $(OUT) $(OBJECTS) .PHONY: distclean distclean: clean rm -f $(TARNAME)
You really don’t need the
$(CC) $(CFLAGS) $(DEBUG) $(LDFLAGS) $(FREQ_OBJECTS) -o $@lines. make already knows how to build binaries.If your filenames are constant for different binaries (binary.c and binary_lib.c), you can also create a general rule for that:
EDIT: Here’s how it works: