[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Dependencies and clean
Re: Dependencies and clean
Tue, 09 Jul 2002 17:47:22 -0400
On the topic of Paul's autodependency whitepaper, address@hidden wrote:
> I checked this out and I have to say its excellent as an approach. It is
> clear to me how and why to use dependencies with this than as described in
> the GNU make manual.
> I do however have a question - I'm not that familiar with SED, so a few of
> the SED commands confused me. I have looked in what manuals/books I have and
> I am not sure what they are supposed to mean - can a SED wizard please
Paul's response explains the purpose. Below I'll show how I
changed it to work with windows, with detailed comments.
> 's/#.*//' This is to remove make style comments from the stream?
> 's/^[^:]*: *//' Remove everything to the last :?
> 's/ *\\$//' Remove the trailing \ from a line.
> '/^$/ d' Delete any blank lines from the stream.
> 's/$/ :/' Append a trailing : to all the lines.
> In practise, the second expression is dangerous to use as it stands over a
> whole file - it is common for Windows based compilers to use the drive
> letter in a pathname which can cause a little trouble. I haven't entirely
> worked around it as yet, however.
Yes, and '/^$/ d' doesn't work with every version of sed IIRC.
I tried various prebuilt sed binaries, and I tried working under
both win95 and win2k with COMMAND.COM and CMD.EXE, and to make
a long off-topic story short, that way lies madness. This works,
on win2k at least:
Get this win32 bash:
Use it to build this sed from source:
in the usual *nix way ('./configure' then 'make')
(don't worry that it's a "beta" version--it's been
around for years and is the best sed I've found).
And don't use *any* ms shell--use the bash above, or
which I just like better than bash, but tastes vary.
Below is some autodependency code I've used for years.
I found it easier to use the standard "magic" sed idiom
-e :a -e '/\\$$/N; s/\\\n//; ta'
to get everything onto one line first. I should have
explained that better, but I hope the rest of the inline
documentation is fairly clear.
# See Paul D. Smith's discussion at this URL:
# I changed Paul's sed commands to work with win95.
# Here's a line by line explanation:
# Concatenate all lines continued with '\'
# -e :a -e '/\\$$/N; s/\\\n//; ta' \
# Note that sed commands in a makefile must double any
# dollar sign.
# Paul's sed script copies the original output of CPP to
# a file, then appends to it with >> . The worst problem
# here is that DOS creates the file even if sed fails.
# Therefore, we'll store what we've got so far in the hold
# space with 'h', then later append it with 'G', and write
# it with 'w'.
# -e 'h' \
# Here is what Paul does to prevent ugly errors when a file
# previously in the dependency list has been erased or renamed.
# Remove the target at the beginning,
# -e 's/^[^:]*: *//' \
# and place a colon at the end. We can skip his steps to delete
# blank lines because we started out by making the whole
# expression one single line.
# -e 's/$$/ :/' \
# As described above, append the contents of the hold space
# that we saved above,
# -e 'G' \
# then write the whole thing to the target file
# (stem plus .d extension). If sed terminated early due to
# an error, the 'w' command will not be reached, and no file
# will be written. Redirect the sed output to /dev/nul so
# that it doesn't clutter the screen.
# -e 'w $*.d' > $(DEVNUL)
# Changed 2001-12-03 by GWC: output redirected to '$*.d'.
# Rationale: we now check for zero-byte .d files and report them
# as errors. Thus, a zero-byte file is preferable to no file.
# It seems that writing a zero-byte file was already the
# behavior with the original technique anyway.
# We make the dependency files in a separate step. If we're
# sure we're never going to use any other compiler than gcc,
# then we can combine this into the compile step e.g. with -MM .
# Changed 2001-12-03 by GWC: replaced single quote with double
# quote throughout. Required for win2k.
MAKEDEPEND = \
-e :a -e '/\\$$/N; s/\\\n//; ta' \
-e 'h' \
-e 's/^[^:]*: *//' \
-e 's/$$/ :/' \
-e 'G' \
-e 's_/usr/include_/Cygwin/usr/include_g' \
-e 's_/usr/lib_/Cygwin/lib_g' \
Then I just put $(MAKEDEPEND) in the usual rules, e.g.
%.o : %.c
$(CXX) -c -xc $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< -o$@
%.o : %.cpp
$(CXX) -c $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< -o$@