Jason R. Mick
Jason R. Mick

Reputation: 5287

Confusing Sed One-Liner in Makefile Tutorial

Can anyone explain this sed one-liner in English (the more detail, the better)?

@sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' < $*.d > $@; \
             rm -f $*.d; [ -s $@ ] || rm -f $@

It's part of this tutorial: http://mad-scientist.net/make/autodep.html

I have a non-constant set of source files and want to auto-generate my dependency tree, based on the contents (includes) spelled out in my source files.

I was following the tutorial pretty well up until that...

P.S. I have basic understanding of sed select/replace, but I'm confused by the matching string and all the layers of redirection.... I've also read through the makefile tutorial once so have basic knowledge of standard makefiles...

Upvotes: 7

Views: 915

Answers (1)

CB Bailey
CB Bailey

Reputation: 791879

The sed pattern will be processed by make first, so if the rule that it applies to is trying to build foo.P then $@ will be translated to foo.P and $* to foo. This means that the actual sed command will be something like:

sed 's/\(foo\)\.o[ :]*/\1.o foo.P : /g' < foo.d > foo.P

\(foo\) matches foo exactly and sets the first replacement to what matches (i.e. foo) \. matches a literal dot and [ :]* matches any number of spaces and colons.

As you can see the \1 replacement is a bit redundant as the matched string is fixed. This would have worked just as well.

sed 's/foo\.o[ :]*/foo.o foo.P : /g' < foo.d > foo.P

which could have been made from:

sed 's/$*\.o[ :]*/$*.o $@ : /g' < $*.d > $@

Upvotes: 12

Related Questions