For an assignment in one of my classes we need to create a makefile for our C program that's more complex than just compile: gcc whatever
. I believe we're expected to do something like this:
outputname: file1.o file2.o file3.o file4.o
gcc -o outputname file1.o file2.o file3.o file4.o
clean:
rm -f outputname file1.o file2.o file3.o file4.o
file1.o: file1.c
gcc -c file1.c
file2.o: file2.c
gcc -c file2.c
file3.o: file3.c
gcc -c file3.c
file4.o: file4.c
gcc -c file4.c
But having to list the same file names multiple times irritates me. If I need to update a name I need to ensure I replace each instance of it in the file. Or if I add a file I have to add new lines that are practically identical to four others already in the file. I've managed to get really close to the functionality of the above makefile:
files := file1.o file2.o file3.o file4.o
output := outputname
$(output): $(files)
gcc -o $(output) $(files)
clean:
rm -f $(output) $(files)
$(files): $(files:.o=.c)
gcc -c $(@:.o=.c)
The only difference I can tell is that unlike the first example, this will recompile all of the c files if any one of them has been updated, removing one of the advantages of makefiles. Is there something else I can do that will remove the redundancy but keep all the functionality?
Most make
utilities already have built-in implicit dependencies for things like generating a .o file from a .c file. So since you're not specifying anything special in your compile steps, you condense your file down to something like:
OBJS = file1.o file2.o file3.o file4.o
outputname: $(OBJS)
gcc -o outputname $(OBJS)
...and it can handle the rest on its own (oh--except that you'll probably still want your clean:
rule).