Makefile always rebuilds

I am using the following simple Makefile to create some simple files. I am really new to making Makefile. I don't know why it is being restored, even if the files are created after the first creation and I am not editing any files.

EXE    = nextgenrsm
CC     = gcc
LIBS   = StarterWare_Files/
CFLAGS = -c 

INCLUDE_PATH =  StarterWare_Files/

MAIN_SRC = $(wildcard *.c)
MAIN_OBS = $(patsubst %.c,%.o,$(MAIN_SRC))

LIB_SRC = $(wildcard StarterWare_Files/*.c)
LIB_OBS = $(patsubst StarterWare_Files/%.c,%.o,$(LIB_SRC))

output: $(EXE)

$(EXE): $(MAIN_OBS) $(LIB_OBS)
    $(CC) $(MAIN_OBS) $(LIBS)$(LIB_OBS) -o $(EXE) 

$(MAIN_OBS): $(MAIN_SRC) 
    $(CC) $(CFLAGS) *.c -I$(INCLUDE_PATH)

$(LIB_OBS): $(LIB_SRC) 
    cd $(LIBS); \
    $(CC) $(CFLAGS) *.c -I../

clean:
    rm -rf $(LIBS)*.o $(EXE) *.o

      

NEW EDITED MAKEFILE

EXE    = nextgenrsm
CC     = gcc
LIBS   = StarterWare_Files/
CPPFLAGS = _IStarterWare_Files/


MAIN_OBS = $(patsubst %.c,%.o,$(wildcard *.c))
LIB_OBS  = $(patsubst %.c,%.o,$(wildcard StarterWare_Files/*.c))

all: $(EXE)

$(EXE): $(MAIN_OBS) $(LIB_OBS)
   $(CC) -o $@ $(LDFLAGS) $(MAIN_OBS) $(LIB_OBS) $(LDLIBS)

%.o: %.c 
   $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $^

ALL_DEPS = $(patsubst %.o,%.d,$(MAIN_OBS), $(LIB_OBS))
-include $(ALL_DEPS)

clean:
   rm -f $(LIB_OBS) $(EXE) $(MAIN_OBS) $(ALL_DEPS)

.PHONY: all clean

      

Whenever I touch StarterWare_Files / example.h and try to do it again it throws an error that gcc cannot specify -o with -c or -S with multiple files. Basically the command becomes something like gcc -o main.o -IStarterWare_Files -c main.c StarterWare_Files / test.h StarterWare_Files / add.h ..

+4


source to share


2 answers


Your target is the default output

, but your makefile never creates such a file, so every time you call make

it tries to create a file output

.

The solution is to mark output

target as a fake target . Just like clean

target:

.PHONY: output clean

      




You can use built-in rules that compile .o

from .c

and automatic variables to reduce your makefile to:

EXE    := nextgenrsm
CC     := gcc
LIBS   := StarterWare_Files/
CPPFLAGS := -IStarterWare_Files

MAIN_OBS := $(patsubst %.c,%.o,$(wildcard *.c))
LIB_OBS  := $(patsubst %.c,%.o,$(wildcard StarterWare_Files/*.c))

all: $(EXE)
$(EXE) : $(MAIN_OBS) $(LIB_OBS)
    $(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS)

clean:
    rm -f $(MAIN_OBS) $(LIB_OBS) $(EXE)

.PHONY: all clean   

      

And if you want the auto-generation of the header header add:

# This rule produces .o and also .d (-MD -MP) from .c.
%.o : %.c
    $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

# This includes all .d files produced along when building .o.
# On the first build there are not going to be any .d files.
# Hence, ignore include errors with -.
ALL_DEPS := $(patsubst %.o,%.d,$(MAIN_OBS) $(LIB_OBS))
-include $(ALL_DEPS)

clean:
    rm -f $(MAIN_OBS) $(LIB_OBS) $(EXE) $(ALL_DEPS)

      

+13


source


The problem is this:

$(MAIN_OBS): $(MAIN_SRC) 

      

You stated that every object file depends on every source file. Likewise for the library. The above rule expands to:

foo.o bar.o xyzzy.o .... : foo.c bar.c xyzzy.c ...

      

Therefore, if the timestamp changes in any source file, each object file will be rebuilt.

What you need to do is have separate dependencies:

# foo.o depends only on foo.c, not on bar.c
foo.o: foo.c

# bar.o depends only on bar.c, not on foo.c
bar.o: bar.c

      

etc. This is usually not done. Rather, we use the GNU Make template rules to write one general rule:



%.o: %c
        # build commands to make .o from .c

      

There is already a built-in rule for this, which is often sufficient, and can be customized by modifying variables such as CC

and CFLAGS

.

Because of built-in rules, simple makefiles usually have to declare a dependency between an executable and object files. Make will automatically infer the precondition from the object file by trying various possibilities. When asked to rate foo.o

, it will automatically detect that there is a file foo.c

that should be foo.o

required. Then, if foo.o

older foo.c

or doesn't exist, Make will search its rule database and find that this combination matches a pattern rule %.o: %.c

, and it will run its recipe body to update foo.o

.

You should use an immediate style variable assignment :=

, not a delay =

. Since you have $(wildcard ...)

on the right side of the assignment =

, every time the variable is replaced, the syntax $(wildcard ...)

is evaluated and the filesystem is moved around to find files.

Do not use $(wildcard ...)

primarily to collect source files. If you don't work carefully, it will lead to unwanted files, for example, random ones test.c

that you created and therefore test.o

bind to your program (perhaps successfully). It doesn't take much effort to list all object files explicitly:

OBJS := foo.o bar.o ...

      

for objects in a subdirectory, you can use $(addprefix ...)

to shorten it:

OBJS := foo.o bar.o ... $(addprefix subdir/,stack.o parser.o ...)

      

+1


source







All Articles