Krixen
Krixen

Reputation: 45

Creating a more generic makefile

I have the following makefile:

CC=gcc
CFLAGS= ---
LDFLAGS = ---

all: abc_test   
abc_test: abc_test.o defn_abc.o abc.o cmocka_compass.o
    $(CC) $(LDFLAGS) abc_test.o defn_abc.o abc.o cmocka_compass.o -o 
abc_test    
abc_test.o : abc_test.c 
    $(CC) $(CFLAGS) abc_test.c 
defn_abc.o : ../defn_abc.c
    $(CC) $(CFLAGS) ../defn_abc.c
abc.o : ../abc.c
    $(CC) $(CFLAGS) ../abc.c    
knownfile.o : ../../../../../knownpath.c 
    $(CC) $(CFLAGS) ../../../../../knownpath.c
clean: 
    rm *o *.log abc_test

Which will work (changed some files names) but I want to make it generic. I tried the following but I keep getting errors that there are no targets.

CC=gcc
CFLAGS= ---
LDFLAGS = ---

SRCFILES := $(shell find ../ -name '*.c')
OBJFILES := $(patsubst %.c,%.o,%(SRCFILES))

OBJFILES: all
all: $(OBJFILES)

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

knownfile.o : knownpath.c 
    $(CC) $(CFLAGS) knownpath.c

the make file is a test folder, which contains all the test code (abs_test.c). This is also where all the objects should go. One directory up contains the c files defn_abc.c and abc.c.

Any idea what I am doing wrong?


UPDATE: Here is my latest makefile, with the error 'missing separator'

CC=gcc
CFLAGS=-c -Wall -DUNIT_TESTING -DSYS_LINUX -Ipath1 -Ipath2
LDFLAGS = -Wl,---


SRCFILES := $(shell find ../ -name '*.c')
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))

all: $(PROG)

$(PROG): $(OBJFILES)
    $(CC) $(CFLAGS) $(OBJFILES) -o $@ $(LDFLAGS)

all: $(OBJFILES)

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

knownfile.o : knownpath.c 
    $(CC) $(CFLAGS) knownfile.c

Upvotes: 1

Views: 184

Answers (2)

physicist
physicist

Reputation: 904

I would recommend you read about the basics of Makefile. This is a useful link intro to makefile

The variable OBJFILES is being over-written in consecutive lines in the example provided. I suspect removing line

OBJFILES: all

and using patsubst as

$(patsubst %suffix,%replacement,$(var))

might help.

@edit: Since now you asked on how to use LDFLAGS and get rid of the 'missing separator' error, here are some suggestions.

  • Purpose of LDFLAGS is to use to provide link time flags to compiler when all the object files are linked to make the final executable. They could look like this
all: $(PROG)

$(PROG): $(OBJFILES)
    $(CC) $(CFLAGS) $(OBJFILES) -o $@ $(LDFLAGS)
  • The error 'missing seperator' is fixed by inserting tabs instead of space in the beginning of a line describing an action/recipe to a rule. Open the Makefile again in an editor and remove the spaces in front of below lines and replace with tab.. the arrow I am using to show a tab
---->$(CC) $(CFLAGS) $(OBJFILES) -o $@ $(LDFLAGS)

---->$(CC) $(CFLAGS) %< -o %@

---->$(CC) $(CFLAGS) knownfile.c

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 181199

This line does not do what you think it does:

OBJFILES: all

Or at least I assume so, for although it is mostly harmless, it is also useless. It declares that a target named 'OBJFILES' depends on target 'all'. It also happens to be the first target in the file, so it is the default target, but because 'all' is its prerequiste, it will cause the 'all' target to be rebuilt by default. This is precisely what would happen if you omitted that line altogether. Note, too, that this has nothing to do with the variable $(OBJFILES).

Your main problem appears to be that you are using the wrong syntax for most of your variable references. The values of variables with multi-character names are obtained via expressions of the form $(VAR) or ${VAR}, not %(var). The parentheses / braces can be omitted for single-character names. I advise you to favor the form with parentheses over the one with curly braces, especially in commands in recipes, for the latter is easy to confuse with shell syntax.

Upvotes: 1

Related Questions