简体   繁体   中英

Compile multiple .c files with makefile

I would like to compile multiple .c files at once using a makefile. I already made this:

CC= gcc

CPPFLAGS = -I.

CFLAGS = -W -Wall -ansi -pedantic

TARGET = test

RM = rm

OBJECTS = xxx.o yyy.o zzz.o

SOURCES = $(OBJECTS:.o =.c)

.PHONY: all clean

all: $(TAREGT)

clean:

         $(RM) $(TARGET) $(OBJECTS)

$(TAREGT) : $(OBJECTS)

         $(CC) $^ -o $@

$(OBJECTS) : $(SOURCES) 

         $(CC) $(CFLAGS) $(CPPFLAGS) -c $^

I have no Idea why this does not work("nothing to be done for "all"). Someone has an idea?

This line is creating a circular dependency:

SOURCES = $(OBJECTS:.o =.c)

Try replacing it with this:

SOURCES = $(patsubst %.o,%.c,$(OBJECTS))

You forgot -o $@ in your 'sources to objects' rule. Thus it doesn't create anything.

You have also spelling error - your $(TARGET) is 'test', but your 'all' rule depends on $(TAREGT) which is empty. You are also using $(TAREGT) as input to compile 'test'.

You don't need to specify $(SOURCES) or "sources to objects" rule - implicit rules will do the trick.

In fact your "sources to objects" rule is incorrect - it says that each object depends on all sources. If you want each object to depend on one source you should use either suffix rule, pattern rule or static pattern rule. Or just implicit rule.

$(OBJECTS) : $(SOURCES) 

The above tells Make that every .o file depends on all sources, ie if you change one of your .c files Make will recompile all .o files. Not something what you really want, I guess. I'd rework this rule as follows:

$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))

This will iterate every source in SOURCES , find corresponding .o file in OBJECTS and create correct rule: <obj>: <source> . It is that complicated to work in case of more complex mapping between source and object files. Say, when building object files in separate directory.

This cryptic code will work even for the following weird source to object file mapping:

SOURCES := a.cpp boo/b.c c.C
OBJECTS := foo/a.o bar/b.o c.o
$(foreach s,$(SOURCES),$(eval $(filter %$(basename $(notdir $s)).o,$(OBJECTS)): $s))

It will generate the following rules:

foo/a.o: a.cpp
bar/b.o: boo/b.c
c.o: c.C

Thank you guys for you help, it is working now

I just added some rules:

CC= gcc
CPPFLAGS = -I.
CFLAGS = -W -Wall -ansi -pedantic
TARGET = test
RM = rm
SOURCES = xxx.c yyy.c zzz.c
OBJECTS = $(SOURCES:.c=.o)

.PHONY: all clean

all: $(TARGET)

clean:
    $(RM) $(TARGET) $(OBJECTS)

$(TARGET) : $(OBJECTS)
    $(CC) $^ -o $@

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM