Autodependency generation in makefiles

585 Views Asked by At

I am trying to understand how autodependency is generated in makefiles in the given link, i cannot understand the following piece of code:

DEPDIR = .deps
df = $(DEPDIR)/$(*F)

SRCS = foo.c bar.c ...

%.o : %.c
        @$(MAKEDEPEND); \
          cp $(df).d $(df).P; \
          sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
              -e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \
          rm -f $(df).d
        $(COMPILE.c) -o $@ $<

-include $(SRCS:%.c=$(DEPDIR)/%.P)

I got it from this link. I know it will generate dependency files but I am not able to understand what this line does:

sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
    -e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \

Can somebody please explain me this code, so many wildcards give me butterflies, i am new to makefiles.

2

There are 2 best solutions below

2
On BEST ANSWER

That is a number of distinct commands so break it up.

  1. -e 's/#.*//'

    Delete everything that starts with a # (Comments? Pre-processor directives?)

  2. -e 's/^[^:]*: *//'

    Delete everything up to a : on any that has : it.

  3. -e 's/ *\\$$//'

    Delete line-continuation slashes (and spaces before them) from the end of lines.

  4. -e '/^$$/ d'

    Delete any blank lines.

  5. -e 's/$$/ :/'

    Add : to the end of every line.

This adds explicit targets for every listed dependency file so that make "knows" how to build them to avoid the "No rule to make target" errors. The reasoning here is explained in your link in an earlier section.

Briefly, this creates a .P file with the original prerequisites list, then adds targets to it by taking each line, removing any existing target information and any line continuation (\) characters, then adding a target separator (:) to the end. This works with the values for MAKEDEPEND I suggest below; it’s possible you will need to modify the translation for other dependency generators you might use.

2
On

This is not meant to be an answer to your actual question, but since you said you were new to GNU make, I think spreading the words that a simpler way to handle auto dependencies exists won't do any harm.

Nowadays compilers like GCC or Clang can do this for you while compiling your code !

Simply pass them a preprocessor flag:

# Preprocessor flags
CPPFLAGS += -MMD

And include the generated files into the Makefile:

-include $(wildcard *.d)

And you're done.


You can learn more about the preprocessor options here for GCC, Clang simply mirror these options.

A relatively good example lies here too.