From: Jan Nieuwenhuizen Date: Thu, 15 Mar 2001 17:57:45 +0000 (+0100) Subject: patch::: 1.3.137.jcn3 X-Git-Tag: release/1.3.138~2 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d1639a6fd5bc462e4b18f27aa959c69c81756ac7;p=lilypond.git patch::: 1.3.137.jcn3 1.3.136.jcn3 ============ * Bugfix: ly2dvi: can't remove cwd on Solaris. * Better --enable-conf=CONF message, better INSTALL.tely documentation. * Bugfix: built of Documentation/user for different conf=CONF. * Don't append "." to version string without my_patch_level. * Faked titling for tutorial example. * Bugfix: don't override GUILE environment settings. --- Generated by janneke@gnu.org, From = lilypond-1.3.137.jcn2, To = lilypond-1.3.137.jcn3 usage cd lilypond-source-dir; patch -E -p1 < lilypond-1.3.137.jcn3.diff Patches do not contain automatically generated files or (urg) empty directories, i.e., you should rerun autoconf, configure --- diff --git a/CHANGES b/CHANGES index 84b4279a4e..0a6e56de76 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,24 @@ ---- ../lilypond-1.3.137.jcn1/CHANGES Mon Mar 12 22:39:39 2001 +--- ../lilypond-1.3.137.jcn2/CHANGES Wed Mar 14 23:37:02 2001 +++ b/CHANGES Thu Mar 15 18:57:45 2001 +@@ -1,3 +1,18 @@ +1.3.136.jcn3 +============ + +* Bugfix: ly2dvi: can't remove cwd on Solaris. + +* Better --enable-conf=CONF message, better INSTALL.tely documentation. + +* Bugfix: built of Documentation/user for different conf=CONF. + +* Don't append "." to version string without my_patch_level. + +* Faked titling for tutorial example. + +* Bugfix: don't override GUILE environment settings. + + 1.3.136.jcn2 + ============ + --- ../lilypond-1.3.137.jcn1/CHANGES Mon Mar 12 22:39:39 2001 ++ b/CHANGES Wed Mar 14 23:37:02 2001 @@ -1,3 +1,14 @@ 1.3.136.jcn2 diff --git a/Documentation/topdocs/INSTALL.texi b/Documentation/topdocs/INSTALL.texi index 19e1623757..9d7e01ad9d 100644 --- a/Documentation/topdocs/INSTALL.texi +++ b/Documentation/topdocs/INSTALL.texi @@ -235,9 +235,11 @@ Options to configure include: unreliable on some compiler/platform combinations (eg, DEC Alpha and PPC) @item @code{--enable-profiling} Compile with support for profiling. -@item @code{--enable-config} - Output to a different configuration file. Needed for multi-platform - builds +@item @code{--enable-config=CONF} + Output to different configuration files. Enables different binary + builds alongside eachother, eg, multi-configuration (debugging, + profiling), or multi-platform builds. Use `make conf=CONF' to + build for a specific configuration. @end table All options are documented in the @file{configure} help @@ -257,10 +259,11 @@ contain all files generated during compilation). @section Configuring for multiple platforms -If you want to compile LilyPond with different configuration settings, -then, you can use the @code{--enable-config} option. Example: suppose I -want to build with and without profiling. Then I'd use the -following for the normal build, +If you want to build multiple versions of LilyPond with different +configuration settings, you can use the @code{--enable-config=CONF} +option. You should use @samp{make conf=CONF} to generate the output in +@file{out-CONF}. Example: suppose I want to build with and without +profiling. Then I'd use the following for the normal build, @example @@ -275,9 +278,9 @@ and for the profiling version, I specify a different configuration. @example ./configure --prefix=~ --enable-profiling --enable-config=prof --enable-optimise --disable-checking - make config=prof - make config=prof install - + make conf=prof + make conf=prof install + @end example diff --git a/Documentation/user/GNUmakefile b/Documentation/user/GNUmakefile index b6c5d83f79..db0ed79d93 100644 --- a/Documentation/user/GNUmakefile +++ b/Documentation/user/GNUmakefile @@ -107,11 +107,10 @@ local-clean: backdoc-WWW: $(outdir)/lilypond-internals/lilypond-internals.html $(SHELL) $(buildscript-dir)/install-info-html.sh --dir=$(outdir) lilypond lilypond-internals -#ugh. lily/OUT/lilypond hardcoded. # when cross-compiling, we don't have lilypond ifneq ($(CROSS),yes) $(outdir)/lilypond-internals.nexi $(outdir)/lilypond-internals.texi: - cd $(outdir) && ../$(depth)/$(builddir)/lily/out/lilypond ../$(src-depth)/ly/generate-documentation + cd $(outdir) && ../$(depth)/$(builddir)/lily/$(outconfbase)/lilypond ../$(src-depth)/ly/generate-documentation -ln $(outdir)/lilypond-internals.texi $(outdir)/lilypond-internals.nexi else $(outdir)/lilypond-internals.nexi $(outdir)/lilypond-internals.texi: diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 286cf7d264..5ef45450a0 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -933,7 +933,7 @@ not generated by ly2dvi, so details will differ.} @center @strong{Two miniatures} @flushright - Opus 1. +Opus 1. @end flushright @flushleft @var{Up} @@ -946,7 +946,7 @@ not generated by ly2dvi, so details will differ.} } @end lilypond @flushright - Opus 2. +Opus 2. @end flushright @flushleft @var{Down} @@ -1446,16 +1446,22 @@ If you've come this far, you should have seen enough LilyPond source to feel comfortable with an orchestral score. We will not go through the input line by line, but only indicate and explain the new elements. -% os-music.ly -@quotation +This orchestral score example consists of three input files. In the +first file, @file{os-music.ly}, we define the music for all instruments. +This file is to be used by the other two files, as you will see below. +If you run lilypond on this file, no output will be produced. + + @example +% os-music.ly \header @{ title = "Zo, goed lieverd?"; subtitle = "How's, this babe?"; composer = "JCN"; + opus = "1"; piece = "Laid back"; @} -global = \notes @{ +global = @{ \time 2/4; \skip 2*4; \bar "|."; @} @@ -1481,12 +1487,17 @@ corno = \notes\relative c' @{ bes4 d f, bes d f, bes d @} @end example -@end quotation -% geen titels, wat jammer :-( +Things to note here are the definition of @code{\global} where we define +meter, and set the end bar. And the separate definition of @code{\Key} +that we will use all staffs except staffs for transposing instruments. + +The second file, @file{os-score.ly} reads the definitions of the first +(@file{os-music.ly}), and defines the @code{\score} block for the full +conductor's score. + +@example % os-score.ly -@quotation -@lilypond[verbatim] \include "os-music.ly"; \include "paper13.ly"; @@ -1494,8 +1505,8 @@ corno = \notes\relative c' @{ #(define text-flat '((font-relative-size . -2) (music "accidentals--1"))) -\score { - \notes < +\score @{ + < \global \context StaffGroup = woodwind < \context Staff = flauti < @@ -1503,8 +1514,8 @@ corno = \notes\relative c' @{ \property Staff.instrument = "2 Flauti" \property Staff.instr = "Fl." \Key - \context Voice=one { \voiceOne \flautoI } - \context Voice=two { \voiceTwo \flautoII } + \context Voice=one @{ \voiceOne \flautoI @} + \context Voice=two @{ \voiceTwo \flautoII @} > > \context StaffGroup = timpani < @@ -1520,9 +1531,8 @@ corno = \notes\relative c' @{ \context StaffGroup = brass < \context Staff = trombe < \property Staff.midiInstrument = #"trumpet" - \property Staff.instrument = #`(lines "2 Trombe" - (rows "(C)")) - \property Staff.instr = #`(lines "Tbe." (rows "(C)")) + \property Staff.instrument = #`(lines "2 Trombe" "(C)") + \property Staff.instr = #`(lines "Tbe." "(C)") \Key \context Voice=one \partcombine Voice \context Thread=one \tromboI @@ -1540,65 +1550,264 @@ corno = \notes\relative c' @{ > > > - \paper { + \paper @{ indent = 15 * \staffspace; linewidth = 60 * \staffspace; textheight = 90 * \staffspace; - \translator{ + \translator@{ \ThreadContext \consists "Rest_engraver"; - } - \translator{ + @} + \translator@{ \VoiceContext \remove "Rest_engraver"; - } - \translator{ + @} + \translator@{ \HaraKiriStaffContext - } - \translator { + @} + \translator @{ \OrchestralScoreContext BarNumber \override #'padding = #3 - } - } - \midi { + @} + @} + \midi @{ \tempo 4 = 75; - } -} -@end lilypond -@end quotation + @} +@} +@end example + +% geen echte titels, wat jammer :-( +@center @strong{Zo, goed lieverd?} +@sp 1 +@center How's, this babe? +@flushright +Opus 1. +@end flushright +@flushleft +@sc{Laid back} +@end flushleft + +@lilypondfile{os-score.ly} + +First, we need to include the music definitions we made in +@file{os-music.ly}. +@example +\include "os-music.ly"; +@end example + +In a large orchestral score like this you're bound to make some small +mistakes, so we enable point and click (See @ref{Point and click}) +editing. +@example +#(set! point-and-click #t) +@end example + +We need a flat to specify the tuning of the french horn, so we predefine +it with bit of scheme markup text (See @ref{Text markup}). +@example +#(define text-flat '((font-relative-size . -2) + (music "accidentals--1"))) +@end example + +Of course, all staffs are simultaneous and use the same global settings. +@example + < + \global +@end example + +Then, we start a new staff group for the woodwind section (just the +flutes in this case). Immediately after that, we start the staff for +the two flutes, that also play simultaneously. +@example + \context StaffGroup = woodwind < + \context Staff = flauti < +@end example + +We specify the intrument for MIDI output (see @ref{MIDI instrument +names}). +@example + \property Staff.midiInstrument = #"flute" +@end example + +And define the intrument names to be printed in the margin, +@code{instrument} for the first line of the score, @code{instr} for the +rest of the score. +@example + \property Staff.instrument = "2 Flauti" + \property Staff.instr = "Fl." +@end example + +The flutes play in the default key. +@example + \Key +@end example + +Last come the actual flute parts. Remember that we're still in +simultaneous mode. We name both voices differently, so that LilyPond +will actually create two Voice contexts. The flute parts are simple, so +we specify manually which voice is which: @code{\voiceOne} forces the +direction of stems, beams, slurs and ties up, @code{\voiceTwo} sets +directions down. +@example + \context Voice=one @{ \voiceOne \flautoI @} + \context Voice=two @{ \voiceTwo \flautoII @} +@end example + +We close the flutes staff and woodwind staff group. +@example + > + > +@end example + +The timpani staff only shows a new piece of scheme markup, it sets two +lines of text. +@example + \property Staff.instrument = #'(lines "Timpani" "(C-G)") +@end example + +For the trumpets we use the automatic part combiner (see @ref{Automatic +part combining}) to combine the two simultaneous trumpet parts onto the +trumpet staff. Each trumpet gets its own Thread context, which must be +named @code{one} and @code{two}). The part combiner makes these two +threads share a Voice when they're similar, and splits the threads up +when they're different. +@example + \context Voice=one \partcombine Voice + \context Thread=one \tromboI + \context Thread=two \tromboII +@end example + +The french horn has the most complex scheme markup name, made up of two +lines of text. The second line has two elements (rows), the @code{E} +and the flat sign @code{text-flat} that we defined before. +@example + \property Staff.instrument = #`(lines "Corno" + (rows "(E" ,text-flat ")")) +@end example + +The french horn is to be tuned in E-flat, so we tell the MIDI backend to +transpose this staff by three steps. +@example + \property Staff.transposing = #3 +@end example + +Therefore, it has a different key. +@example + \notes \key bes \major; +@end example + +We specify a big indent for the first line and a small linewith for this +tuturial. +@example + indent = 15 * \staffspace; + linewidth = 60 * \staffspace; +@end example + +Because we have a Thread representing one instument, we move the +need the @code{Rest_engraver} from Voice to Thread level. +@example + \translator@{ + \ThreadContext + \consists "Rest_engraver"; + @} + \translator@{ + \VoiceContext + \remove "Rest_engraver"; + @} +@end example + +In orchestral scores, it often happens that one instrument has only +rests during one line of the score. The @code{HaraKiriStaffContext} can +be used as a regular @code{StaffContext} drop-in and will take care of +the automatic removing of empty staffs. +@example + \translator@{ + \HaraKiriStaffContext + @} +@end example + +Lastly, we want bar numbering at score level and want to move the bar +number a few staff-spaces up. +@example + \translator @{ + \OrchestralScoreContext + BarNumber \override #'padding = #3 + @} +@end example @node Part extraction @section Part extraction -@quotation -@lilypond[verbatim] +The third file, @file{os-flute-2.ly} also reads the definitions of the +first (@file{os-music.ly}), and defines the @code{\score} block for the +second flute part. + +@example \include "os-music.ly"; \include "paper16.ly"; -\score { +\score @{ \context Staff < \property Staff.midiInstrument = #"flute" \global \Key \flautoII > - \header { - instrument = "flute I"; - } - \paper { + \header @{ + instrument = "Flauto II"; + @} + \paper @{ linewidth = 80 * \staffspace; textheight = 200 * \staffspace; - \translator { + \translator @{ \OrchestralScoreContext skipBars = ##t - } - } - \midi { + @} + @} + \midi @{ \tempo 4 = 75; - } -} -@end lilypond -@end quotation + @} +@} +@end example + +@center @strong{Zo, goed lieverd?} +@sp 1 +@center How's, this babe? +@center @emph{Flauto II} +@flushright +Opus 1. +@end flushright +@flushleft +@sc{Laid back} +@end flushleft +@lilypondfile{os-flute-2.ly} + + +Because we separated the music definitions from the @code{\score} +instantiations, we can easily define a second score from the music of +the second flute. This then is the part for the second flute player. +Of course, we make separate parts for all individual instruments. + +In this individual part the second flute has a whole staff for itself, +so we don't want to force stem or tie directions. +@example + \flautoII +@end example + +The @code{\header} definitions were also read from @file{os-music.ly}, +but we need to set the instrument for this particular score. +@example + \header @{ + instrument = "Flauto II"; + @} +@end example + +In the conductor's full score, all bars with rests are printed, but for +the individual parts, we want to contract pieces of consecutive empty +bars. +@example + skipBars = ##t +@end example @node end of tutorial @section The end diff --git a/VERSION b/VERSION index af2b8c7ece..2cfe4f0892 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=137 -MY_PATCH_LEVEL=jcn2 +MY_PATCH_LEVEL=jcn3 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/aclocal.m4 b/aclocal.m4 index 702c151614..b5684b86ad 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -328,7 +328,8 @@ AC_DEFUN(AC_STEPMAKE_INIT, [ CONFIGSUFFIX= AC_ARG_ENABLE(config, - [ --enable-config=FILE put configure settings in config-FILE.make], + [ --enable-config=CONF put settings in config-CONF.make and config-CONF.h; + do \`make conf=CONF' to get output in ./out-CONF], [CONFIGSUFFIX=-$enableval]) CONFIGFILE=config$CONFIGSUFFIX diff --git a/input/tutorial/os-music.ly b/input/tutorial/os-music.ly index 4c22730ba9..96136d0f3b 100644 --- a/input/tutorial/os-music.ly +++ b/input/tutorial/os-music.ly @@ -2,9 +2,10 @@ title = "Zo, goed lieverd?"; subtitle = "How's, this babe?"; composer = "JCN"; + opus = "1"; piece = "Laid back"; } -global = \notes { +global = { \time 2/4; \skip 2*4; \bar "|."; } @@ -14,7 +15,6 @@ flautoI = \notes\relative c'' { bes as bes as bes as bes as } flautoII = \notes\relative c'' { -% d8 es d es R1 d4 ~ d as8 bes as bes R1 d4 ~ d } tromboI = \notes\relative c'' { diff --git a/input/tutorial/os-score.ly b/input/tutorial/os-score.ly index b489c7a5b6..adb670fab6 100644 --- a/input/tutorial/os-score.ly +++ b/input/tutorial/os-score.ly @@ -6,7 +6,7 @@ #(define text-flat '((font-relative-size . -2) (music "accidentals--1"))) \score { - \notes < + < \global \context StaffGroup = woodwind < \context Staff = flauti < @@ -31,8 +31,8 @@ \context StaffGroup = brass < \context Staff = trombe < \property Staff.midiInstrument = #"trumpet" - \property Staff.instrument = #`(lines "2 Trombe" (rows "(C)")) - \property Staff.instr = #`(lines "Tbe." (rows "(C)")) + \property Staff.instrument = #`(lines "2 Trombe" "(C)") + \property Staff.instr = #`(lines "Tbe." "(C)") \Key \context Voice=one \partcombine Voice \context Thread=one \tromboI diff --git a/lily/lily-version.cc b/lily/lily-version.cc index 081504324a..40220a5532 100644 --- a/lily/lily-version.cc +++ b/lily/lily-version.cc @@ -10,12 +10,13 @@ #include "version.hh" #include "lily-version.hh" -#define VERSION MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL "." MY_PATCH_LEVEL - String version_str () { - String str = VERSION; + String str (MAJOR_VERSION "." MINOR_VERSION "." PATCH_LEVEL); + String mpl ("." MY_PATCH_LEVEL); + if (mpl != ".") + str += mpl; return str; } diff --git a/lily/main.cc b/lily/main.cc index 7f122864d8..acaafadc00 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -387,6 +387,17 @@ main_prog (int, char**) exit (exit_status_global); } +static int +sane_putenv (char const* key, char const* value) +{ + /* + putenv is POSIX, setenv is BSD 4.3 + Urg, but putenv blindly overwrites environment settings. + */ + if (!getenv (key)) + return putenv ((char*)((String (key) + "=" + value).ch_C ())); + return -1; +} int main (int argc, char **argv) @@ -394,13 +405,18 @@ main (int argc, char **argv) debug_init (); // should be first (can see that; but Why?) setup_paths (); - /* - prepare guile for heavy mem usage. + /* Prepare GUILE for heavy memory usage. If you have plenty memory, + this may speed up GUILE a bit. If you're short on memory, these + settings + + export GUILE_INIT_SEGMENT_SIZE_1=36000 + export GUILE_MAX_SEGMENT_SIZE=576000 - putenv is POSIX, setenv is BSD 4.3 - */ - putenv ("GUILE_INIT_SEGMENT_SIZE_1=4194304"); - putenv ("GUILE_MAX_SEGMENT_SIZE=8388608"); + may considerably decrease memory footprint (~*0.85), with a small + execution time penalty (~*1.10). */ + + sane_putenv ("GUILE_INIT_SEGMENT_SIZE_1", "4194304"); + sane_putenv ("GUILE_MAX_SEGMENT_SIZE", "8388608"); ly_init_kpath (argv[0]); diff --git a/lily/music.cc b/lily/music.cc index 64044b1f5a..75bf2746fb 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -184,10 +184,14 @@ Music::set_mus_property (SCM s, SCM v) mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v); } +#include "main.hh" void Music::set_spot (Input ip) { - set_mus_property ("origin", make_input (ip)); + /* misuse midi-debug flag: don't store origin */ + if (midi_debug_global_b) + return; + set_mus_property ("origin", make_input (ip)); } diff --git a/make/lilypond-vars.make b/make/lilypond-vars.make index e90de95871..5f94a465bd 100644 --- a/make/lilypond-vars.make +++ b/make/lilypond-vars.make @@ -18,9 +18,10 @@ ifneq ($(the-script-dir),) ABC2LY = $(script-dir)/abc2ly.py CONVERT_LY = $(script-dir)/convert-ly.py -LY2DVI = $(script-dir)/ly2dvi.py +LILYPOND = $(depth)/$(builddir)/lily/$(outconfbase)/lilypond LILYPOND_BOOK = $(script-dir)/lilypond-book.py LILYPOND_BOOK_INCLUDES = -I $(pwd) -I $(input-dir)/tricks/ -I $(input-dir)/regression/ -I $(input-dir)/test/ -I $(input-dir)/tutorial/ +LY2DVI = $(script-dir)/ly2dvi.py PS_TO_GIFS = $(buildscript-dir)/ps-to-gifs.sh PS_TO_PNGS = $(buildscript-dir)/ps-to-pngs.sh @@ -29,10 +30,11 @@ else ### $(message running from installed stepmake) ABC2LY = $(shell $(SHELL) -c 'type -p abc2ly') -LY2DVI = $(shell $(SHELL) -c 'type -p ly2dvi') CONVERT_LY = $(shell $(SHELL) -c 'type -p convert-ly') +LILYPOND = $(shell $(SHELL) -c 'type -p lilypond') LILYPOND_BOOK = $(shell $(SHELL) -c 'type -p lilypond-book') LILYPOND_BOOK_INCLUDES = -I. -I.. -I$(outdir) +LY2DVI = $(shell $(SHELL) -c 'type -p ly2dvi') PS_TO_GIFS = $(shell $(SHELL) -c 'type -p ps-to-gifs') PS_TO_PNGS = $(shell $(SHELL) -c 'type -p ps-to-pngs') diff --git a/make/stepmake.make b/make/stepmake.make index ae5f5cb46a..6d25f54696 100644 --- a/make/stepmake.make +++ b/make/stepmake.make @@ -50,6 +50,10 @@ endif outdir=$(outroot)/$(outbase) config_h=$(depth)/$(builddir)/config$(CONFIGSUFFIX).h +# The outdir that was configured for: best guess to find binaries +outconfbase=out$(CONFIGSUFFIX) +outconfdir=$(outroot)/$(outconfbase) + # user package stepdir = $(stepmake)/stepmake # for stepmake package diff --git a/scripts/ly2dvi.py b/scripts/ly2dvi.py index 03b04ae75c..cb6606d621 100644 --- a/scripts/ly2dvi.py +++ b/scripts/ly2dvi.py @@ -215,7 +215,7 @@ def setup_temp (): temp_dir = tempfile.mktemp ('ly2dvi') try: - os.mkdir (temp_dir) + os.mkdir (temp_dir, 0777) except OSError: pass @@ -552,6 +552,7 @@ if files: if track_dependencies_p: generate_dependency_file (depfile, dest) + os.chdir (original_dir) cleanup_temp () # most insteresting info last diff --git a/stepmake/aclocal.m4 b/stepmake/aclocal.m4 index 702c151614..b5684b86ad 100644 --- a/stepmake/aclocal.m4 +++ b/stepmake/aclocal.m4 @@ -328,7 +328,8 @@ AC_DEFUN(AC_STEPMAKE_INIT, [ CONFIGSUFFIX= AC_ARG_ENABLE(config, - [ --enable-config=FILE put configure settings in config-FILE.make], + [ --enable-config=CONF put settings in config-CONF.make and config-CONF.h; + do \`make conf=CONF' to get output in ./out-CONF], [CONFIGSUFFIX=-$enableval]) CONFIGFILE=config$CONFIGSUFFIX diff --git a/stepmake/make/stepmake.make b/stepmake/make/stepmake.make index 39cea41b9b..b98bd15401 100644 --- a/stepmake/make/stepmake.make +++ b/stepmake/make/stepmake.make @@ -49,6 +49,10 @@ endif outdir=$(outroot)/$(outbase) config_h=$(depth)/$(builddir)/config$(CONFIGSUFFIX).h +# The outdir that was configured for: best guess to find binaries +outconfbase=out$(CONFIGSUFFIX) +outconfdir=$(outroot)/$(outconfbase) + # user package # stepdir = $(stepmake)/stepmake # for stepmake package diff --git a/stepmake/stepmake/documentation-targets.make b/stepmake/stepmake/documentation-targets.make index 7084ab5b69..fab3e31af9 100644 --- a/stepmake/stepmake/documentation-targets.make +++ b/stepmake/stepmake/documentation-targets.make @@ -5,7 +5,7 @@ default: local-WWW: $(OUTHTML_FILES) footify local-web: - $(MAKE) CONFIGSUFFIX=www local-WWW + $(MAKE) out=www local-WWW footify: $(footify) $(sort $(wildcard $(outdir)/*.html out/*.html out-www/*.html))