vesii
vesii

Reputation: 3128

Creating a makefile with different tests

I'm trying to understand if I have create the Makefile right. I have the following files:

Student.h Student.C University.h University.c list.h IDCard.h IDCard.c union.h

Also I have a library mylib which I use the list.h and union.h from.
Furthermore, I have the following hierarchy:

- University
    - Student
        - list
        - IDCard
    - union

This means that University imports Student and union and Student import list and IDCard.

The steps I need to follow:

  1. Use the make command to create testing1.exe - release mode without asserts. This file is the runnable of the given testing1.c.

  2. Use make testing2.exe for creating test2.exe - release mode without asserts. This file is the runable of testing2.c.

  3. Use make testing2_debug.exe for creating testing2_debug.exe - debug mode, with asserts. This file is the runable of test2.c.

  4. Use make test for creating test.exe - release mode without asserts. This file is runnable of test.c.

  5. Use make clean to clean so the rebuild will succeed.

The Makefile I wrote looks like:

CC = gcc
OBJS = IDCard.o Student.o University.o
DEBUG_OBJS = IDCard_debug.o Student_debug.o University_debug.o
SOURCE = IDCard.c Student.c University.c
HEADER = IDCard.h Student.h University.h list.h union.h
CFLAGS = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -L. -mylib
EXEC = testing.exe testing1.exe testing2.exe testing2_debug.exe
testing_O = testing1.o testing2.o testing2_debug.o testing.o

#make testing1.exe
testing1.exe : $(OBJS) $*.o
    $(CC) -o $@ -DNDEBUG $(OBJS) -L. mylib

#make testing2.exe
testing2.exe : $(OBJS) $*.o
    $(CC) -o $@ -DNDEBUG $(OBJS) -L. mylib

#testing2_debug.exe
testing2_debug.exe : $(DEBUG_OBJS) $*.o
    $(CC) -o $@ -DNDEBUG $(OBJS) -L. mylib

#make testing.exe
testing.exe : $(OBJS) $*.o
    $(CC) -o $@ -DNDEBUG $(OBJS) -L. mylib

testing1.o : testing1.c Student.h University.h
    $(CC) -c -DNDEBUG $(CFLAGS) $*.c
Student.o : list.h IDCard.h Student.c Student.h
    $(CC) -c -DNDEBUG $(CFLAGS) $*.c
University.o :  union.h University.c University.h
    $(CC) -c -DNDEBUG $(CFLAGS) $*.c
IDCard.o : IDCard.h
    $(CC) -c -DNDEBUG $(CFLAGS) $*.c

testing2_debug.o : testing2.c Student.h University.h
    $(CC) -c -g $(CFLAGS) $*.c -o $@
Student_debug.o : list.h IDCard.h Student.c Student.h
    $(CC) -c -g $(CFLAGS) $*.c -o $@
University_debug.o : union.h University.c University.h
    $(CC) -c -g $(CFLAGS) $*.c -o $@
IDCard_debug.o : IDCard.h
    $(CC) -c -g $(CFLAGS) $*.c -o $@

clean :
    rm -f $(OBJS) $(DEBUG_OBJS) $(EXEC) $(testing_O)

I'm a bit new to creating Makefiles so I'm try to make as few mistakes as possible. Does my Makefile do what I need? Can it be simplified? Does it follow the conventions?

Upvotes: 2

Views: 646

Answers (2)

Joshua
Joshua

Reputation: 43317

IDCard.o : IDCard.h
        $(CC) -c -DNDEBUG $(CFLAGS) $*.c

but .h files aren't compiled

As a general style form list .c dependencies before .h dependencies.

EDIT: Community Wiki. If it weren't for the clarifying comment by OP I would now delete this post.

Upvotes: 0

S.S. Anne
S.S. Anne

Reputation: 15586

$*.o shouldn't be a dependency. $(OBJS) already covers that.

As a general rule, you can avoid targets for individual object files.

Here's an example target that may need modification to suit your needs:

%.o: %.c %.h
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $@ $<

%_debug.o: %.c %.h
<tab>$(CC) -c -g $(CFLAGS) -o $@ $< 

This requires the header file to have the same base name as the source file.

Another option that may work is listing off the header file dependencies of each object file and then doing the matching:

testing1.o: Student.h University.h
Student.o: list.h IDCard.h Student.h
University.o: union.h University.h
IDCard.o: IDCard.h
testing2_debug.o: Student.h University.h
Student_debug.o: list.h IDCard.h Student.h
University_debug.o: union.h University.h
IDCard_debug.o: IDCard.h

%.o: %.c
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $@ $<

%_debug.o: %.c
<tab>$(CC) -c -g $(CFLAGS) -o $@ $< 

A similar rule can be followed for .exe files:

%.exe: $(OBJS)
<tab>$(CC) -DNDEBUG $(CFLAGS) $^ -o $@ -L. -lmylib

%_debug.exe: $(DEBUG_OBJS)
<tab>$(CC) -g $(CFLAGS) $^ -o $@ -L. -lmylib

Also, make sure to replace <tab> in these examples with hard tabs for your Makefile to be valid.

Upvotes: 1

Related Questions