Makefile does not allow incremental build

I have a makefile from a sample project and it unfortunately forces a re-build when any one file in the project changes. I don't have much experience with makefiles, so I'm not sure how to fix this problem.

The makefile defines the files to compile as one variable SRCS

, as shown below. Of course, there are about 40 files in this list, in quite different directories.

SRCS = \
  ../../src/file1.c \
  ../../src/file2.c

      

It then defines the build rules for each file .o

generated from each file .c

.

$(OBJ_PATH)/%.o: $(SRCS)
    $(CC) $(FLAGS) $(filter %/$(subst .o,.c,$(notdir $@)), $(SRCS)) -o $@

      

According to running with the parameter, -d

all object files must be compiled again when one file .c

changes as it $(SRCS)

is defined as a dependency above.

How can I change this, so if one file changes, only file 1 .o

needs to be compiled again?

+3


source to share


4 answers


Another solution would be to use vpath

. Sample code:



OBJ_PATH := build

SRCS := \
    src/foodir/foo.c \
    src/bardir/bar.c

OBJS := $(addprefix $(OBJ_PATH)/,$(notdir $(SRCS:%.c=%.o)))

vpath %.c $(dir $(SRCS))

all: $(OBJS)

$(OBJ_PATH)/%.o: %.c
    $(CC) $(FLAGS) $< -o $@

      

+2


source


Your recipe was written by someone knowledgeable about makefiles; this is almost correct. One adjustment is to move the statement $(filter)

to the prerequisite line. In this case, this is exactly what it should be.

Once it appears, you need to make a few additional settings, which you can read about in the manual. So, like this:



PERCENT := %
.SECONDEXPANSION:
$(OBJ_PATH)/%.o: $$(filter $$(PERCENT)/$$(subst .o,.c,$$(notdir $$@)), $(SRCS))
    $(CC) $(FLAGS) $< -o $@

      

+2


source


Something like this will work as well.

SRCS = \
  ../../src/file1.c \
  ../../src/file2.c

# Set prerequisites for each output .o file from the matching .c file
$(foreach src,$(SRCS),$(eval $(OBJ_PATH)/$(notdir $(src:.c=.o)): $(src)))

# Create pattern rule with no additional prerequisites.
$(OBJ_PATH)/%.o:
    $(CC) $(FLAGS) $< -o $@

      

So it occurred to me that in some ways an even more minimal change would be:

$(OBJ_PATH)/%.o: $(SRCS)
    file='$(filter %/$(subst .o,.c,$(notdir $@)), $?)'; [ "$$file" ] && \
    $(CC) $(FLAGS) "$$file" -o $@

      

+2


source


Typically, in the Makefile, you don't put specific .c files as dependencies.

Typically, you specify .o files as dependencies of the main executable.

Make has internal rules for how to create a .o file from a .c file, you can override them with your own custom rule, or often just change a few config.

The complete make tutorial is more than what I want to type in this box, but they can be found with a quick web search.

0


source







All Articles