diff options
Diffstat (limited to 'jmake')
-rw-r--r-- | jmake/Jmakefile | 57 | ||||
-rw-r--r-- | jmake/Makefile.SH | 271 | ||||
-rw-r--r-- | jmake/NOTES | 189 | ||||
-rw-r--r-- | jmake/README | 70 | ||||
-rwxr-xr-x | jmake/bindex.SH | 184 | ||||
-rw-r--r-- | jmake/files/Jmake.rules | 1902 | ||||
-rw-r--r-- | jmake/files/Jmake.tmpl | 208 | ||||
-rw-r--r-- | jmake/fixcpp.SH | 183 | ||||
-rwxr-xr-x | jmake/jmake.SH | 390 | ||||
-rw-r--r-- | jmake/jmake.man | 398 | ||||
-rwxr-xr-x | jmake/jmkmf.SH | 71 | ||||
-rw-r--r-- | jmake/jmkmf.man | 70 |
12 files changed, 3993 insertions, 0 deletions
diff --git a/jmake/Jmakefile b/jmake/Jmakefile new file mode 100644 index 0000000..5fdb3eb --- /dev/null +++ b/jmake/Jmakefile @@ -0,0 +1,57 @@ +/* + * Jmakefile for jmake + */ + +;# $Id: Jmakefile,v 3.0.1.2 1995/03/21 08:34:16 ram Exp $ +;# +;# Copyright (c) 1991-1993, Raphael Manfredi +;# +;# You may redistribute only under the terms of the Artistic Licence, +;# as specified in the README file that comes with the distribution. +;# You may reuse parts of this distribution only within the terms of +;# that same Artistic Licence; a copy of which may be found at the root +;# of the source tree for dist 3.0. +;# +;# $Log: Jmakefile,v $ +;# Revision 3.0.1.2 1995/03/21 08:34:16 ram +;# patch52: now installs new fixcpp script in the private libdir +;# +;# Revision 3.0.1.1 1994/01/24 13:42:36 ram +;# patch16: added dependency generation stage +;# +;# Revision 3.0 1993/08/18 12:04:09 ram +;# Baseline for dist 3.0 netwide release. +;# + +AllTarget(Index) + +Index: bindex + chmod +x bindex + ./bindex + +ShellScriptTarget(jmake jmkmf) +SimpleShellScriptTarget(bindex fixcpp) + +>PRIVLIB /* We need the privlib definition */ + +MakeInstallDirectories($(PRIVLIB) $(PRIVLIB)/files) +InstallNonExec(Index,$(PRIVLIB)) +InstallScript(bindex,$(PRIVLIB)) +InstallScript(fixcpp,$(PRIVLIB)/files) +InstallMultipleFlags(files/Jmake*,$(PRIVLIB)/files,-m 444) + +BINSH = jmake.SH fixcpp.SH + +>SED +>RM +>MKDEP + +depend:: + ($(SED) '/^# DO NOT DELETE/q' Makefile && \ + grep '^\$$grep' $(BINSH) | \ + $(SED) -e "s/^.*' \([^ ]*\) >>\([^ ]*\)/\2: \1/" \ + ) > Makefile.new + cp Makefile Makefile.bak + cp Makefile.new Makefile + $(RM) Makefile.new + diff --git a/jmake/Makefile.SH b/jmake/Makefile.SH new file mode 100644 index 0000000..987b3ab --- /dev/null +++ b/jmake/Makefile.SH @@ -0,0 +1,271 @@ +: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL51] +: $X-Id: Jmake.tmpl,v 3.0.1.2 1995/01/11 14:50:21 ram Exp ram $ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +CURRENT=jmake +DIR=`echo $CURRENT/ | sed -e 's/\.\///g'` +echo "Extracting ${DIR}Makefile (with variable substitutions)" + +INSTALL=`echo $install | sed -e 's,\./i,\$(TOP)/i,'` +INSTALLDIR=`echo $installdir | sed -e 's,\./i,\$(TOP)/i,'` +DATE=`date` + +$spitshell >Makefile <<!GROK!THIS! +######################################################################## +# Makefile generated from Makefile.SH on $DATE + +SHELL = /bin/sh +JMAKE = jmake +TOP = .. +CURRENT = $CURRENT +DIR = $DIR +INSTALL = $INSTALL +INSTALLDIR = $INSTALLDIR + +######################################################################## +# Parameters set by Configure -- edit config.sh if changes are needed + +CTAGS = ctags +L = $manext +MANSRC = $installmansrc +MAKE = make +MKDEP = $mkdep \$(DPFLAGS) -- +MV = $mv +PRIVLIB = $installprivlib +RM = $rm -f +SCRIPTDIR = $installscript +SED = $sed + +######################################################################## +# Automatically generated parameters -- do not edit + +SCRIPTS = jmake jmkmf + +!GROK!THIS! +$spitshell >>Makefile <<'!NO!SUBS!' +######################################################################## +# Jmake rules for building libraries, programs, scripts, and data files +# $X-Id: Jmake.rules,v 3.0.1.2 1995/01/11 14:49:55 ram Exp ram $ +######################################################################## +# Force 'make depend' to be performed first -- do not edit + +.FORCE_DEPEND:: + +all:: .FORCE_DEPEND + +######################################################################## +# Start of Jmakefile + +# $X-Id: Jmakefile,v 3.0.1.2 1995/03/21 08:34:16 ram Exp ram $ +# +# Copyright (c) 1991-1993, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 3.0. +# +# $X-Log: Jmakefile,v $ +# Revision 3.0.1.2 1995/03/21 08:34:16 ram +# patch52: now installs new fixcpp script in the private libdir +# +# Revision 3.0.1.1 1994/01/24 13:42:36 ram +# patch16: added dependency generation stage +# +# Revision 3.0 1993/08/18 12:04:09 ram +# Baseline for dist 3.0 netwide release. +# + +all:: Index + +local_realclean:: + $(RM) Index + +Index: bindex + chmod +x bindex + ./bindex + +all:: jmake jmkmf + +local_realclean:: + $(RM) jmake jmkmf + +jmake: jmake.SH + /bin/sh jmake.SH + +jmkmf: jmkmf.SH + /bin/sh jmkmf.SH + + +install:: $(SCRIPTS) $(LSCRIPTS) + @for file in $(SCRIPTS) $(LSCRIPTS); do \ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ + (set -x; $(INSTALL) -c -m 555 $$file $(SCRIPTDIR)); \ + done + +deinstall:: + @for file in $(SCRIPTS) $(LSCRIPTS); do \ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ + (set -x; $(RM) $(SCRIPTDIR)/$$file); \ + done + +install.man:: + @if test "$(MANSRC)"; then \ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ + for file in $(SCRIPTS); do \ + (set -x; \ + $(INSTALL) -c -m 444 $$file.man $(MANSRC)/$$file.$(L)); \ + done; \ + else exit 0; fi + +deinstall.man:: + @if test "$(MANSRC)"; then \ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ + for file in $(SCRIPTS); do \ + (set -x; $(RM) $(MANSRC)/$$file.$(L)); \ + done; \ + else exit 0; fi + +all:: bindex fixcpp + +local_realclean:: + $(RM) bindex fixcpp + +bindex: bindex.SH + /bin/sh bindex.SH + +fixcpp: fixcpp.SH + /bin/sh fixcpp.SH + + +install:: + @for dir in $(PRIVLIB) $(PRIVLIB)/files; do \ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ + (set -x; test -d $$dir || $(INSTALLDIR) $$dir); \ + done + +deinstall:: + $(RM) -r $(PRIVLIB) $(PRIVLIB)/files + +install:: Index + $(INSTALL) -c -m 444 Index $(PRIVLIB) + +deinstall:: + $(RM) $(PRIVLIB)/Index + +install:: bindex + $(INSTALL) -c -m 555 bindex $(PRIVLIB) + +deinstall:: + $(RM) $(PRIVLIB)/bindex + +install:: fixcpp + $(INSTALL) -c -m 555 fixcpp $(PRIVLIB)/files + +deinstall:: + $(RM) $(PRIVLIB)/files/fixcpp + +install:: files/Jmake* + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ + for i in files/Jmake*; do \ + (set -x; $(INSTALL) -c -m 444 $$i $(PRIVLIB)/files); \ + done + +deinstall:: + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ + for i in files/Jmake*; do \ + (set -x; $(RM) $(PRIVLIB)/files/$$i); \ + done + +BINSH = jmake.SH fixcpp.SH + +depend:: + ($(SED) '/^# DO NOT DELETE/q' Makefile && \ + grep '^\$$grep' $(BINSH) | \ + $(SED) -e "s/^.*' \([^ ]*\) >>\([^ ]*\)/\2: \1/" \ + ) > Makefile.new + cp Makefile Makefile.bak + cp Makefile.new Makefile + $(RM) Makefile.new + +######################################################################## +# Common rules for all Makefiles -- do not edit + +emptyrule:: + +clean: local_clean +realclean: local_realclean +clobber: local_clobber + +local_clean:: + $(RM) core *~ *.o + +local_realclean:: local_clean + +local_clobber:: local_realclean + $(RM) Makefile config.sh + +Makefile.SH: Jmakefile + -@if test -f $(TOP)/.package; then \ + if test -f Makefile.SH; then \ + echo " $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \ + $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \ + fi; \ + echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \ + $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \ + else touch $@; exit 0; fi + +Makefile: Makefile.SH + /bin/sh Makefile.SH + +tags:: + $(CTAGS) -w *.[ch] + $(CTAGS) -xw *.[ch] > tags + +local_clobber:: + $(RM) tags + +######################################################################## +# Empty rules for directories with no sub-directories -- do not edit + +install:: + @echo "install in $(CURRENT) done." + +deinstall:: + @echo "deinstall in $(CURRENT) done." + +install.man:: + @echo "install.man in $(CURRENT) done." + +deinstall.man:: + @echo "deinstall.man in $(CURRENT) done." +Makefiles:: + +Makefiles.SH:: + +######################################################################## +# Dependencies generated by make depend +# DO NOT DELETE THIS LINE -- make depend relies on it + +# Put nothing here or make depend will gobble it up +.FORCE_DEPEND:: + @echo "You must run 'make depend' in $(TOP) first."; exit 1 +!NO!SUBS! +chmod 644 Makefile +$eunicefix Makefile + diff --git a/jmake/NOTES b/jmake/NOTES new file mode 100644 index 0000000..a11618d --- /dev/null +++ b/jmake/NOTES @@ -0,0 +1,189 @@ +The syntax in Jmake.rules is not elegant at all, but: + + - It is easy to parse (like sendmail.cf or troff files). + - The rules are not supposed to change very often. + - It is simple enough to be mastered in five minutes. :-) + +Here is a small description: + +o To deal with various cpp implementations: + +Final @!\ means: end of line, next line starts at the left margin. +Final @@\ means: end of line, next line is to be indented by one tab. + +The conversion occurs during Pass1. + + +o Symbol definitions + +>SYMBOL: defines the symbol (Pass 1). +?SYMBOL:<text>: keeps <text> iff SYMBOL is defined (Pass 2). +%SYMBOL:<text>: keeps <text> iff SYMBOL is not defined (Pass 2). + +The ?SYM can be nested (logical AND), as in: + + ?SYMBOL:%TOKEN:text /* Keeps text if SYMBOL and not TOKEN */ + +To implement a logical OR, see below. + + +o Commands + +Commands can be passed to 'jmake'. They start with a leading '|'. + +Available commands are: + +|suffix <sx>: adds <sx> to the .SUFFIXES: list in the makefile (Pass 1 & 2). +|rule:<text>: adds <text> to the building rule section (Pass 1 & 2). +|rule: <text>: same as before, with a leading tab. +|skip: skips text until a line starting with '-skip' is found (Pass 2). +|expand <pattern>: expand lines until '-expand' with <pattern> (Pass 2). +|once <symbol>: text up to '-once' appears only the first time (Pass 1). + +Thus, a way to implement a logical OR could be: + + /* Implements SYMBOL or not TOKEN */ + ?SYMBOL:text /* Keeps text if SYMBOL */ + %SYMBOL:|skip + %TOKEN:text /* Keeps text if not TOKEN */ + -skip + +Actually, this is ugly, because the text has to appear twice. +Fortunately, I did not use it. :-) + +The '|' commands cannot be nested. In particular, due to the simple +implementation of '|skip', it is impossible to put '|skip' inside +a skipped part. However, a '|once' section may have '|skip' sections. + +But actually, as you have surely already guessed, the best way to +implement a logical OR is to use De Morgan's Law: + + not (p or q) <=> not p and not q + + /* Implements SYMBOL or not TOKEN (attempt #2) */ + %SYMBOL:?TOKEN:|skip + text /* If SYMBOL or not TOKEN */ + -skip + +Who said they don't care ? ;-) + +o Expansion + +Expansion is done with the 'expand' command. It has been provided to +avoid some cumbersome writings in makefiles when you have to repeat some +silly lines that only differ in file names, for instance. Let's look at +an example first: + + |expand a!foo bar! b!yes no! + !a:: + echo !a, !b + -expand + +Then two rules will be printed, and the values of (a,b) for the first +will be (foo, yes), for the second (bar, no). Substitution is controled +by the '!' character. If the word to be substituted is part of another +one, detach with the ^^ construct as in: !b^^c. It is possible to +use Makefile macros in the <pattern>, and they will be expanded by +jmake. If this is not what you want, escape the first '$' sign (this is +a Makefile escape, i.e. you must double the '$', not precede it with a +backslash). A // stands for the null substitution value. + +Here is another example which shows how the macro Expand can be used. +It is defined in Jmake.rules as: + + #define Expand(rule, pattern) @!\ + |expand pattern @!\ + rule @!\ + -expand + +So we can write in the Jmakefile: + + |skip + A = foo bar + -skip + + #define Rule @!\ + $(DIR)/!a^^.o: !a^^.o @@\ + $(CC) -c !a^^.c @@\ + $(MV) !a^^.o $(DIR) + + Expand(Rule, a!$(A)!) + +which will generate in Makefile.SH: + + $(DIR)/foo.o: foo.o + $(CC) -c foo.c + $(MV) foo.o $(DIR) + + $(DIR)/bar.o: bar.o + $(CC) -c bar.c + $(MV) bar.o $$(DIR) + +The 'A' declaration has been surrounded by skip, so that it does +not appear in the generated Makefile.SH, but it will be taken into +account by jmake for the substitution in the pattern. + +The number of expansions is determined by the number of possible +values for the _first_ parameter. If other parameters have less +substitution values, they will get void ones. + +It is possible to add a regular expression at the end of '-expand'. +This regular expression will be removed from the final set of expansion +at the end of each line. It is also possible to do substitutions in the +expanded item, by using the syntax (if 'f' is the expanded variable) +!f:<p>=<q> where <p> and <q> are two regular expressions (without +spaces). The pattern <p> will be replaced by pattern <q> (only the +first occurrence will be replaced). + +Finally, you may refer in the expanded section to variables whose value +is computed via another expansion, which makes it easy to define generic +Jmakefiles. + +Example: + + SRC = foo.c bar.c + OBJ = \ + |expand f!$(SRC)! + !f:\.c=\.o \ + -expand \\ + INC = \ + |expand f!$(OBJ)! + !f:\.o=\.h \ + -expand \\ + +which will generate in Makefile.SH: + + SRC = foo.c bar.c + OBJ = \ + foo.o \ + bar.o + INC = \ + foo.h \ + bar.h + +Do not forget to protect special characters in your regular expressions such +as backslash, point, etc... + +o Once + +The once command is tagged with a name. The first time the name appears, +the once construct is ignored and the text up to '-once' will be copied +in the generated Makefile.SH. However, future occurences of the same +name will be ignored (once will behave like skip). + +Example: + + |once this_is_a_name + <text> + -once + +o Initializations + ++<line>: Puts the whole line in the initialization section (Pass 1 & 2). +++SYMBOL <value>: Adds <value> to the SYMBOL macro (Pass 1 and 2). + +o User-defined variables + +CFLAGS: added flags to C compiler +DPFLAGS: cpp flags to be added to mkdep for dependency +LDFLAGS: flags/libraries to be added at linking stage diff --git a/jmake/README b/jmake/README new file mode 100644 index 0000000..636cc8f --- /dev/null +++ b/jmake/README @@ -0,0 +1,70 @@ +This is the root directory for jmake. + +The jmake program is a Makefile generator. It comes from 'imake' one +may find in the X11R4 distribution, but it produces a Makefile.SH +instead of a Makefile. Jmake has a template which knows some metaconfig +symbols and has built-in commands which make it more powerful than imake. + +The jmkmf script may be used to produce the Makefile.SH from a Jmakefile. +Once the bootstrap is done, you can run 'make Makefile.SH' to rebuild the +Makefile.SH in the current directory, or 'make Makefiles.SH' to build the +Makefiles in a recursive manner. + +All the rules used by jmake are listed in an automatically built index. +The jmake's cryptic syntax is documented in file NOTES. You may also +have a look at the sample Jmakefiles that come with this package. +Usually, you do not include them in the release, but I kept them so +that you may have a real example and see how things are organized. + +If you choose to use jmake, then you will have to use metaconfig, in +order to get a meaningful value for all the needed symbol. Thus, each +time you change your Jmakefiles, it may be necessary to update the +Configure script. + +Here is how to use jmake... + +First, you have to write a Jmakefile for each directory where you want +to put a Makefile. Be sure to declare all the sub-directories with the +SetSubdirs rule. Usually, the order of the rules is not significant, +but you should make sure the Makefile begins with an 'all::' target, +so that a default 'make' does not run a clean for instance. + +Then, if this is the first time, you have to bootstrap. Go to the main +directory of your package and run: + + jmkmf + make Makefiles.SH + +which will first produce the main makefile and then recursively build +all the makefiles. + +Once you have bootstrapped once, you can edit a Jmakefile and rebuild +the local makefile with + + make Makefile + +or all the hierachy below with: + + make Makefiles.SH + +If you want to extract all the makefiles, you may run + + sh Makefile.SH + make Makefiles + +in the top-level directory. Finally, if you only want to test the +generated Makefile.SH without disturbing the Makefile, run + + make Makefile.SH + +which will stop before running the produced file through sh. + + +CAUTION: + +On machines whose cpp eats up tabs in macro expansion, the Makefile.SH +produced might not be indented properly inside rules. + +Perl 4.0 PL10 sometimes dumps core, while PL3 does not. Thus, perl 4.0 +PL10 should NOT be used with jmake, at least on a MIPS. + diff --git a/jmake/bindex.SH b/jmake/bindex.SH new file mode 100755 index 0000000..b665600 --- /dev/null +++ b/jmake/bindex.SH @@ -0,0 +1,184 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting bindex (with variable substitutions)" +$spitshell >bindex <<!GROK!THIS! +$startperl +!GROK!THIS! +$spitshell >>bindex <<'!NO!SUBS!' + eval 'exec perl -S $0 "$@"' + if $runnning_under_some_shell; + +# $Id: bindex.SH,v 3.0.1.1 1993/08/19 06:42:12 ram Exp $ +# +# Copyright (c) 1991-1993, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 3.0. +# +# $Log: bindex.SH,v $ +# Revision 3.0.1.1 1993/08/19 06:42:12 ram +# patch1: leading config.sh searching was not aborting properly +# +# Revision 3.0 1993/08/18 12:04:13 ram +# Baseline for dist 3.0 netwide release. +# + +$file = "files/Jmake.rules"; + +open(INDEX, ">Index") || die "Cannot create Index.\n"; +open(RULES, "$file") || die "Cannot open $file.\n"; + +print INDEX +"[This Index is automatically generated from Jmake.rules file. Do not +edit this file or your changes will be lost. Edit Jmake.rules instead.] + +This file contains a listing of all the macros that can be used in a +Jmakefile. Only a few of these should be used in the Jmakefile (they +are the top-level macros). However, some low-level ones may be useful, +but it is up to you to make that decision. This explains why this file +holds all the available macros for jmake. + +In the following listing, the macros are separated by a line of dashes. +The signature of the macro is given, then a small comment of what it +does precedes the actual definition. + +Lines preceded by '->' show the set of symbols defined when the macro is +used. Initialization lines are shown as-is, i.e. have the form SYM = val +while concatenation is shown by SYM += val (which means val is added to +the value of SYM). + +Conditional lines are preceded by tests like (if SYM). This means the line +is to be kept if and only if the symbol SYM is defined. Other internal +requests are not formatted yet. + +"; +$inrule = 0; # Not inside a rule at the beginning +$incomment = 0; # Not inside a comment +$last_was_text = 0; # Last line was not a rule text +while (<RULES>) { + $inrule || next unless /^\s\*\s(\w+)\s*:/; + if ($inrule) { # We are already in a rule + if ($incomment) { + if (m|^\s*\*/|) { # End of comment + $incomment = 0; + $Comment{$current} .= "\n"; + } else { + s/^\s*\*\s*//; # Remove leading comment sign + $Comment{$current} .= " $_"; + } + next; # Anyway, go to next line + } + if (/^\s*$/) { # Empty line = end of rule + $inrule = 0; + next; + } + # Here, we have to print the body of the rule, after some cleaning + s/(@#|@@|@!)\\$//; # Remove final continuations + s/^(#define.*)\\/$1/; # Remove single '\' on first rule line + s/\|rule:\s*$/\n/; + s/\|rule:\s+/ /; # Remove rule markers + s/\|rule://; + s/%(\w+):\|skip/#ifdef $1/; # Deal with ugly skip syntax + s/\?(\w+):\|skip/#ifndef $1/; # Deal with ugly skip syntax + s/\-skip/#endif/; + s/\?(\w+):/(if $1) /; # Simple '?' test + s/%(\w+):/(not $1) /; # Simple '%' test + s/\|suffix/.SUFFIXES:/; # Make suffix command explicit + s/\t/ /g; # Expand all tabs to 4 chars + s/\s*$/\n/; # Remove any trailing space + s|\^\^|/**/|; # Restore ^^ to the more visual /**/ + if (/^$/) { # If empty line + $Index{$current} .= "\n" if $last_was_text; + $last_was_text = 0; + next; + } + if (/^[>+]/) { # Special commands + if (s/^>\s*//) { # Wanted symbol + chop; + $Wants{$current} .= " $_"; + } elsif (/^\+\+\s*(\S+)\s*(.*)/) { # Added symbol + $Added{$current} .= "\t$1 += $2\n"; + } else { + s/^\+\s*(.*)//; + $Init{$current} .= "\t$1\n"; + } + next; + } + if (s/^#define\s+//) { # Definition of the rule + chop; + $Sig{$current} = $_; # Signature of rule + } else { + $Index{$current} .= " $_"; # Rule's body + $last_was_text = 1; + } + } else { # We've just entered a rule + $current = $1; + next if $current =~ /patch\d/; # Skip RCS log messages + $inrule = 1; + $incomment = 1; # We're still in the leading comment + $Seen{$current} = 1; + $last_was_text = 0; + } +} +close RULES; + +# Now sort the rules in alphabetical order + +print INDEX '-' x 72, "\n"; +foreach $rule (sort(keys %Seen)) { + print INDEX "$Sig{$rule}:\n"; + print INDEX $Comment{$rule}; + $line = $Wants{$rule}; + if (length($line)) { + $line = "->$line."; + $line = do format($line); + print INDEX "$line\n"; + } + $line = $Init{$rule}; + print INDEX "$line\n" if length($line); + $line = $Added{$rule}; + print INDEX "$line\n" if length($line); + $line = $Index{$rule}; + print INDEX $line; + print INDEX "\n" if (length($line)); + print INDEX '-' x 72, "\n"; +} + +close INDEX; + +# Format $_ to fit in 80 columns (70 + size of tabs) +# Long lines are split, and the all but the first are indented +# by two leading spaces. The whole thing is then indented by +# one tab. +sub format { + local($tmp); + local($head) = ''; + local($_) = shift(@_); + while (length($_) > 70) { + $tmp = substr($_,0,70); + $tmp =~ s/^(.*) .*/$1/; + $head .= "\t$tmp\n"; + $_ = ' ' . substr($_,length($tmp),9999); + } + $head .= "\t$_\n"; +} +!NO!SUBS! +chmod 755 bindex +$eunicefix bindex diff --git a/jmake/files/Jmake.rules b/jmake/files/Jmake.rules new file mode 100644 index 0000000..410fbc8 --- /dev/null +++ b/jmake/files/Jmake.rules @@ -0,0 +1,1902 @@ +;######################################################################## +;# Jmake rules for building libraries, programs, scripts, and data files +;# $Id: Jmake.rules,v 3.0.1.6 1997/02/28 14:56:01 ram Exp $ + +/* + * MACHINE-INDEPENDENT RULES -- DO NOT MODIFY + */ + +/* $Id: Jmake.rules,v 3.0.1.6 1997/02/28 14:56:01 ram Exp $ + * + * Copyright (c) 1991-1993, Raphael Manfredi + * + * You may redistribute only under the terms of the Artistic Licence, + * as specified in the README file that comes with the distribution. + * You may reuse parts of this distribution only within the terms of + * that same Artistic Licence; a copy of which may be found at the root + * of the source tree for dist 3.0. + * + * $Log: Jmake.rules,v $ + * Revision 3.0.1.6 1997/02/28 14:56:01 ram + * patch61: now handles USRINC for dependencies + * patch61: smarter about dependencies computation + * + * Revision 3.0.1.5 1995/09/25 09:07:19 ram + * patch59: smarter sed command to strip /usr/include dependencies + * + * Revision 3.0.1.4 1995/07/25 13:33:59 ram + * patch56: install of script man pages can now cope with missing files + * patch56: the clobber target now removes the .config directory as well + * + * Revision 3.0.1.3 1995/03/21 08:35:28 ram + * patch52: suppressed extra argument to NormalProgramTarget call + * + * Revision 3.0.1.2 1995/01/11 14:49:55 ram + * patch45: new macros ShellScriptTargetExt and SimpleShellScriptTargetExt + * patch45: directory installation is now made via INSTALLDIR (Configure) + * + * Revision 3.0.1.1 1994/10/29 15:46:30 ram + * patch36: added RemoteDependency rule + * + * Revision 3.0 1993/08/18 12:04:14 ram + * Baseline for dist 3.0 netwide release. + * + */ + +/* Please, edit only with tabstops = 4 (":set ts=4" under vi) */ + +/* + * AddedByConfigure: + * Gives name of the files generated by Configure that can safely + * be removed when a "make clobber" is issued. Not that it is useless + * to name config.h or config.sh because these are already taken care + * of by jmake. + */ +#define AddedByConfigure(files) @!\ +>RM @!\ +local_clobber:: @@\ + $(RM) files + +/* + * AddSuffix: + * Adds a sufix to the .SUFFIXES: list. + */ +#define AddSuffix(ext) @!\ +|suffix ext + + +/* + * AllTarget: + * Generate rules to build necessary things during make all. + */ +#define AllTarget(depends) @!\ +>RM @!\ +all:: depends @!\ + @!\ +local_realclean:: @@\ + $(RM) depends + +/* + * RemoveTargetProgram: + * This is used in some other macros in order to remove the target + * before starting its building (saves disk space). There should be + * no '@!' at the end of the '#define' line, because this macro is + * used *inside* building rules. + */ +#define RemoveTargetProgram(program) \ +>RM @!\ +>MV @@\ + $(RM) program @@\ + if test -f program; then $(MV) program program^^~; else exit 0; fi + +/* + * NormalProgramTarget: + * Generate rules to compile and link the indicated program; since + * it does not use any default object files, it may be used for + * multiple programs in the same Jmakefile. + */ +#define NormalProgramTarget(program,sources,objects) @!\ +>CC @!\ +>RM @!\ +>JLDFLAGS @!\ +>LIBS @!\ +++OBJECTS objects @!\ +++SOURCES sources @!\ +NormalObjectRule() @!\ +AllTarget(program) @!\ + @!\ +program: objects @@\ + RemoveTargetProgram($@) @@\ + $(CC) -o $@ objects $(JLDFLAGS) $(LIBS) @!\ + + +/* + * SingleProgramTarget: + * Obsolete version of NormalProgramTarget that doesn't have + * deplibs. + */ +#define SingleProgramTarget(program,objects,libs) \ +NormalProgramTarget(program,objects,libs) + +/* + * SimpleProgramTarget: + * Generate rules for compiling and linking programs that only have + * one C source file. It should only be used in Jmakefiles that + * describe a single program. + */ +#define SimpleProgramTarget(program) @!\ +NormalProgramTarget(program,program.c,program.o) + + + +/* + * ComplexProgramTarget: + * Generate rules for compiling and linking the program specified by + * $(OBJS) and $(SRCS), installing the program and its man page, and + * generating dependencies. It should only be used in Jmakefiles + * that describe a single program. + */ +#define ComplexProgramTarget(program) @!\ +>CC @!\ +>JLDFLAGS @!\ +>LIBS @!\ +>BINDIR @!\ +>MANSRC @!\ +++OBJECTS $(OBJS) @!\ +++SOURCES $(SRCS) @!\ +NormalObjectRule() @!\ +AllTarget(program) @!\ + @!\ +program: $(OBJS) @@\ + RemoveTargetProgram($@) @@\ + $(CC) -o $@ $(OBJS) $(JLDFLAGS) $(LIBS) @!\ + @!\ +InstallProgram(program,$(BINDIR)) @!\ +InstallManPage(program,$(MANSRC)) @!\ +DependTarget() @!\ +LintTarget() + + +/* + * ComplexProgramTarget_1: + * Generate rules for compiling and linking the program specified by + * $(OBJS1) and $(SRCS1), installing the program and its man page, + * and generating dependencies for it and any programs described by + * $(SRCS2) and $(SRCS3). It should be used to build the primary + * program in Jmakefiles that describe multiple programs. + */ +#define ComplexProgramTarget_1(program) @!\ +>CC @!\ +>JLDFLAGS @!\ +>LIBS @!\ +>BINDIR @!\ +>MANSRC @!\ +++OBJECTS $(OBJS1) @!\ +++SOURCES $(SRCS1) @!\ +NormalObjectRule() @!\ +AllTarget(program) @!\ + @!\ +program: $(OBJS1) @@\ + RemoveTargetProgram($@) @@\ + $(CC) -o $@ $(OBJS1) $(JLDFLAGS) $(LIBS) @!\ + @!\ +InstallProgram(program,$(BINDIR)) @!\ +InstallManPage(program,$(MANSRC)) @!\ + @!\ +DependTarget() @!\ +LintTarget() + + +/* + * ComplexProgramTarget_2: + * Generate rules for compiling and linking the program specified by + * $(OBJS2) and $(SRCS2) and installing the program and man page. + * It should be used to build the second program in Jmakefiles + * describing more than one program. + */ +#define ComplexProgramTarget_2(program) @!\ +>CC @!\ +>JLDFLAGS @!\ +>LIBS @!\ +>BINDIR @!\ +>MANSRC @!\ +++OBJECTS $(OBJS2) @!\ +++SOURCES $(SRCS2) @!\ +NormalObjectRule() @!\ +AllTarget(program) @!\ + @!\ +program: $(OBJS2) @@\ + RemoveTargetProgram($@) @@\ + $(CC) -o $@ $(OBJS2) $(JLDFLAGS) $(LIBS) @!\ + @!\ +InstallProgram(program,$(BINDIR)) @!\ +InstallManPage(program,$(MANSRC)) + + +/* + * ComplexProgramTarget_3: + * Generate rules for compiling and linking the program specified by + * $(OBJS3) and $(SRCS3) and installing the program and man page. It + * should be used to build the third program in Jmakefiles describing + * more than one program. + */ +#define ComplexProgramTarget_3(program) @!\ +>CC @!\ +>JLDFLAGS @!\ +>LIBS @!\ +>BINDIR @!\ +>MANSRC @!\ +++OBJECTS $(OBJS3) @!\ +++SOURCES $(SRCS3) @!\ +NormalObjectRule() @!\ +AllTarget(program) @!\ + @!\ +program: $(OBJS3) @@\ + RemoveTargetProgram($@) @@\ + $(CC) -o $@ $(OBJS3) $(JLDFLAGS) $(LIBS) @!\ + @!\ +InstallProgram(program,$(BINDIR)) @!\ +InstallManPage(program,$(MANSRC)) + + +/* + * ComplexShellManualTarget: + * Builds manual pages that are to be extracted from .SH files into + * .$manext files. + */ +#define ComplexShellManualTarget(manpages) @!\ +>INSTALL @!\ +>MANSRC @!\ +>RM @!\ +++MANPAGE manpages @!\ +|once _ShellManualRule_ @!\ +|rule:.SH.$manext: @!\ +|rule: /bin/sh $< @!\ +|rule: @!\ +-once @!\ +AddSuffix(.SH) @!\ +AddSuffix(.$manext) @!\ +AllTarget(manpages) @!\ + @!\ +install.man:: @@\ + @if test "$(MANSRC)"; then \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for file in manpages; do \ @@\ + (set -x; $(INSTALL) -c -m 444 $$file $(MANSRC)); \ @@\ + done; \ @@\ + else exit 0; fi @!\ + @!\ +deinstall.man:: @@\ + @if test "$(MANSRC)"; then \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for file in manpages; do \ @@\ + (set -x; $(RM) $(MANSRC)/$$file); \ @@\ + done; \ @@\ + else exit 0; fi + + +/* + * Initialize: + * Puts the line symbol = value in the initialization section of + * Makefile.SH (the one that is subject to parameter substitutions). + */ +#define Initialize(symbol,value) @!\ ++symbol = value + + +/* + * InstallLibrary: + * Generate rules to install the indicated library. + */ +#define InstallLibrary(libname,dest) @!\ +>RANLIB @!\ +>INSTALL @!\ +>RM @!\ +install:: lib^^libname.a @@\ + $(INSTALL) -c -m 644 lib^^libname.a dest @@\ + $(RANLIB) dest/lib^^libname.a @@\ + chmod 444 dest/lib^^libnane.a @!\ + @!\ +deinstall:: @@\ + $(RM) dest/lib^^libname.a + + +/* + * InstallSharedLibrary: + * Generate rules to install the shared library. + */ +#define InstallSharedLibrary(libname,rev,dest) @!\ +>INSTALL @!\ +>RM @!\ +install:: lib^^libname.so.rev @@\ + $(INSTALL) -c -m 444 lib^^libname.so.rev dest @!\ + @!\ +deinstall:: @@\ + $(RM) dest/lib^^libname.so.rev + + +/* + * InstallSharedLibraryData: + * Generate rules to install the shared library data + */ +#define InstallSharedLibraryData(libname,rev,dest) @!\ +>INSTALL @!\ +>RM @!\ +install:: lib^^libname.sa.rev @@\ + $(INSTALL) -c -m 444 lib^^libname.sa.rev dest @!\ + @!\ +deinstall:: @@\ + $(RM) dest/lib^^libname.sa.rev + + +/* + * InstallLibraryAlias: + * Generate rules to create a link from one library name to another + * for the purposes of aliasing. + */ +#define InstallLibraryAlias(libname,alias,dest) @!\ +>LN @!\ +>RM @!\ +install:: lib^^libname.a @@\ + $(RM) lib^^alias.a @@\ + -(cd dest; $(LN) lib^^libname.a lib^^alias.a) @!\ + @!\ +deinstall:: @@\ + $(RM) dest/lib^^alias.a + + +/* + * InstallLintLibrary: + * Generate rules to install the indicated lint library. + */ +#define InstallLintLibrary(libname,dest) @!\ +>INSTALL @!\ +>RM @!\ +install.ln:: llib-l^^libname.ln @@\ + $(INSTALL) -c -m 444 llib-l^^libname.ln dest @!\ + @!\ +deinstall.ln:: @@\ + $(RM) dest/llib-l^^libname.ln + + +/* + * InstallManPageLong: + * Generate rules to install the indicated manual page, giving it an + * alternate name. This is used for installing man pages whose base + * name without the .man suffix would normally be longer than 8 + * characters (the limit for using source code control systems on + * files systems with short file names). + */ +#define InstallManPageLong(file,destdir,dest) @!\ +>L @!\ +>INSTALL @!\ +>RM @!\ +install.man:: file.man @@\ + $(INSTALL) -c -m 444 file.man destdir/dest.$(L) @!\ + @!\ +deinstall.man:: @@\ + $(RM) destdir/dest.$(L) @!\ + + +/* + * InstallManPage: + * Generate rules to install the indicated manual page. + */ +#define InstallManPage(file,dest) @!\ +InstallManPageLong(file,dest,file) + + +/* + * InstallNonExec: + * Generate rules to install a data file using any special + * install flags. + */ +#define InstallNonExec(file,dest) @!\ +>INSTALL @!\ +>RM @!\ +install:: file @@\ + $(INSTALL) -c -m 444 file dest @!\ + @!\ +deinstall:: @@\ + $(RM) dest/file + + +/* + * InstallProgramWithFlags: + * Generate rules to install an executable program using given + * install flags. + */ +#define InstallProgramWithFlags(program,dest,flags) @!\ +>INSTALL @!\ +>RM @!\ +install:: program @@\ + $(INSTALL) -c -s -m 555 flags program dest @!\ + @!\ +deinstall:: @@\ + $(RM) dest/program + + +/* + * InstallProgram: + * Generate rules to install an executable program using any special + * install flags set in $(INSTALLFLAGS). + */ +#define InstallProgram(program,dest) @!\ +InstallProgramWithFlags(program,dest,^^) + + +/* + * InstallScriptWithFlags: + * Generate rules to install an executable script using given + * install flags. + */ +#define InstallScriptWithFlags(script,dest,flags) @!\ +>INSTALL @!\ +>RM @!\ +install:: script @@\ + $(INSTALL) -c -m 555 flags script dest @!\ + @!\ +deinstall:: @@\ + $(RM) dest/script + + +/* + * InstallScript: + * Generate rules to install an executable script using any special + * install flags set in $(INSTALLFLAGS). + */ +#define InstallScript(script,dest) @!\ +InstallScriptWithFlags(script,dest,^^) + + +/* + * InstallScripts: + * Generate rules to install all the scripts listed in the generated + * $(SCRIPTS) and $(LSCRIPTS) macros. + */ +#define InstallScripts() @!\ +>SCRIPTDIR @!\ +>INSTALL @!\ +>RM @!\ +|once _InstallScripts_ @!\ +install:: $(SCRIPTS) $(LSCRIPTS) @@\ + @for file in $(SCRIPTS) $(LSCRIPTS); do \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + (set -x; $(INSTALL) -c -m 555 $$file $(SCRIPTDIR)); \ @@\ + done @!\ + @!\ +deinstall:: @@\ + @for file in $(SCRIPTS) $(LSCRIPTS); do \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + (set -x; $(RM) $(SCRIPTDIR)/$$file); \ @@\ + done @!\ +-once + +/* + * InstallManScripts: + * Generate rule to install/deinstall manual pages for scripts listed + * in the automatically generated $(SCRIPTS) macro. + */ +#define InstallManScripts() @!\ +>RM @!\ +>INSTALL @!\ +>MANSRC @!\ +>L @!\ +|once _InstallManScripts_ @!\ +?NOMAN:|skip @!\ +install.man:: @@\ + @if test "$(MANSRC)"; then \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for file in $(SCRIPTS); do \ @@\ + if test -f $$file.man; then \ @@\ + (set -x; \ @@\ + $(INSTALL) -c -m 444 $$file.man $(MANSRC)/$$file.$(L)); \ @@\ + fi; \ @@\ + done; \ @@\ + else exit 0; fi @!\ + @!\ +deinstall.man:: @@\ + @if test "$(MANSRC)"; then \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for file in $(SCRIPTS); do \ @@\ + (set -x; $(RM) $(MANSRC)/$$file.$(L)); \ @@\ + done; \ @@\ + else exit 0; fi @!\ + @!\ +-skip @!\ +-once + + + +/* + * LinkFileList: + * Link a list of list of files from one place to another + */ +#define LinkFileList(step,list,dir,sub) @!\ +>LN @!\ +step:: list @@\ + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + echo " cd" dir; cd dir; for i in list; do (set -x; $(LN) sub/$$i .); done + + +/* + * InstallMultipleDestFlags: + * Generate rules to install multiple files at once during a particular + * step in the build using a specific set of install flags. The `step' + * must begin with "install". + */ +#define InstallMultipleDestFlags(step,list,dest,flags) @!\ +>INSTALL @!\ +>RM @!\ +step:: list @@\ + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for i in list; do \ @@\ + (set -x; $(INSTALL) -c flags $$i dest); \ @@\ + done @!\ + @!\ +de^^step:: @@\ + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + for i in list; do \ @@\ + (set -x; $(RM) dest/$$i); \ @@\ + done + + +/* + * InstallMultipleDest: + * Generate rules to install multiple files at once during a particular + * step in the build using any install flags set in $(INSTALLFLAGS). + */ +#define InstallMultipleDest(step,list,dest) @!\ +InstallMultipleDestFlags(step,list,dest,$(INSTALLFLAGS)) + +/* + * InstallMultiple: + * Generate rules to install multiple files at once during the install + * step of the build using any install flags set in $(INSTALLFLAGS). + */ +#define InstallMultiple(list,dest) @!\ +InstallMultipleDest(install,list,dest) + + +/* + * InstallMultipleFlags: + * Generate rules to install multiple files at once during the + * install step of the build using the given install flags. + */ +#define InstallMultipleFlags(list,dest,flags) @!\ +InstallMultipleDestFlags(install,list,dest,flags) + + +/* + * InstallMultipleMan: + * Generate rules to install a variety of manual pages + * during the install.man step of the build. + */ +#define InstallMultipleMan(list,dest) @!\ +>L @!\ +InstallMultipleDest(install.$(L),list,dest) + + +/* + * DependDependency: + * Generate rules to build the makedepend program. + */ +#define DependDependency() @!\ +depend:: TOPDIR/mkdep @!\ + @!\ +TOPDIR/mkdep: @!\ +?TOP: @echo "You have to run Configure first."; exit 1 @!\ +%TOP: @echo "You have to run Configure in $(TOP) first."; exit 1 + + +/* + * DependTarget: + * Generate rules to compute dependencies for all files listed + * in $(SOURCES) (automatically generated macro). + */ +#define DependTarget() @!\ +>MKDEP @!\ +>SED @!\ +>RM @!\ ++USRINC = $usrinc @!\ +|once _DependTarget_ @!\ +DependDependency() @!\ + @!\ +depend:: @@\ + ($(SED) '/^# DO NOT DELETE/q' Makefile && \ @@\ + $(MKDEP) $(SOURCES) | \ @@\ + $(SED) -e 's:/usr/include[^ ]*::g; s:$(USRINC)[^ ]*::g; ' \ @@\ + -e '/: / b print' -e 'H; d; n; : print' -e 'x; s/\\\n//g' \ @@\ + -e 's/ ^^ */ /g; s/ :/:/;' -e '/: *$$/d' \ @@\ + ) > Makefile.new @@\ + cp Makefile Makefile.bak @@\ + cp Makefile.new Makefile @@\ + $(RM) Makefile.new @!\ + @!\ +-once + + +/* + * CleanTarget: + * Generate rules to remove any garbage files. + */ +#define CleanTarget() @!\ +>RM @!\ +?SUBDIRS:clean: sub_clean local_clean @!\ +%SUBDIRS:clean: local_clean @!\ +?SUBDIRS:realclean: sub_realclean local_realclean @!\ +%SUBDIRS:realclean: local_realclean @!\ +?SUBDIRS:clobber: sub_clobber local_clobber @!\ +%SUBDIRS:clobber: local_clobber @!\ + @!\ +local_clean:: @@\ + $(RM) core *~ *.o @!\ + @!\ +local_realclean:: local_clean @!\ +?TOP: $(RM) -r UU @!\ + @!\ +local_clobber:: local_realclean @!\ +%TOP: $(RM) Makefile config.sh @!\ +?TOP: $(RM) config.sh config.h @!\ +?TOP: $(RM) -r .config @!\ +?TOP: $(RM) Makefile @!\ + + +/* + * TagsTarget: + * Generate rules to compute tags files for C source code. + */ +#define TagsTarget() @!\ +>CTAGS @!\ +>RM @!\ +tags:: @@\ + $(CTAGS) -w *.[ch] @@\ + $(CTAGS) -xw *.[ch] > tags @!\ + @!\ +local_clobber:: @@\ + $(RM) tags + + + +/* + * BuildMakefileSH: + * Generate rules to build a Makefile.SH from an Jmakefile and any + * special jmake flags. This is generally done automatically by the + * template or by any special Jmakefiles. + * This function will simply touch Makefile.SH if no $(TOP)/.package + * exists, assuming the Jmakefile is not in a production environment. + */ +#define BuildMakefileSH(jmakeflags) @!\ +>RM @!\ +>MV @!\ +Makefile.SH: Jmakefile @@\ + -@if test -f $(TOP)/.package; then \ @@\ + if test -f Makefile.SH; then \ @@\ + echo " $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \ @@\ + $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \ @@\ + fi; \ @@\ + echo " $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" jmakeflags; \ @@\ + $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) jmakeflags; \ @@\ + else touch $@; exit 0; fi + + +/* + * BuildMakefile: + * Generate rules to build a Makefile from a Makefile.SH. + */ +#define BuildMakefile() @!\ +Makefile: Makefile.SH @@\ + /bin/sh Makefile.SH + + +/* + * MakefileTarget: + * Generate rules to build a normal Makefile. + */ +#define MakefileTarget() @!\ +BuildMakefileSH(^^) @!\ +BuildMakefile() + + +/* + * NormalObjectRule: + * Generate make rule to build usual object files. + */ +#define NormalObjectRule() @!\ +>CC @!\ +>JCFLAGS @!\ +|once _ObjectRule_ @!\ +|rule:.c.o: @!\ +|rule: $(CC) -c $(JCFLAGS) $< @!\ +|rule: @!\ +-once + +/* + * NormalLibraryObjectRule: + * Generate make rules to build "normal" objects. + */ +#define NormalLibraryObjectRule() @!\ +>CC @!\ +>JCFLAGS @!\ +>RM @!\ +|once _ObjectRule_ @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ @!\ +|rule: $(CC) -c $(JCFLAGS) $< @!\ +|rule: @!\ +-once + +/* + * ProfiledLibraryObjectRule: + * Generate make rules to build both profiled and "normal" objects. + */ +#define ProfiledLibraryObjectRule() @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi @!\ + @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ profiled/$@ @!\ +|rule: $(CC) -pg -c $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o profiled/$*.o @!\ +|rule: $(CC) -c $(JCFLAGS) $*.c @!\ +|rule: @!\ +local_clean:: @@\ + -@if [ -d profiled ]; then echo " $(RM) profiled/?*.o"; \ @@\ + $(RM) profiled/?*.o; else exit 0; fi + + +/* + * DebuggedLibraryObjectRule: + * Generate make rules to build both debuggable and "normal" + * objects. + */ +#define DebuggedLibraryObjectRule() @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ debugger/$@ @!\ +|rule: $(CC) -g -c $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o debugger/$*.o @!\ +|rule: $(CC) -c $(JCFLAGS) $*.c @!\ +|rule: @!\ +local_clean:: @@\ + -@if [ -d debugger ]; then echo " $(RM) debugger/?*.o"; \ @@\ + $(RM) debugger/?*.o; else exit 0; fi + + +/* + * DebuggedAndProfiledLibraryOjbectRule: + * Generate make rules to build debuggable, profiled, and "normal" + * objects. + */ +#define DebuggedAndProfiledLibraryObjectRule() @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ profiled/$@ debugger/$@ @!\ +|rule: $(CC) -pg -c $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o profiled/$*.o @!\ +|rule: $(CC) -g -c $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o debugger/$*.o @!\ +|rule: $(CC) -c $(JCFLAGS) $*.c @!\ +|rule: @!\ +local_clean:: @@\ + -@if [ -d profiled ]; then echo " $(RM) profiled/?*.o"; \ @@\ + $(RM) profiled/?*.o; else exit 0; fi @@\ + -@if [ -d debugger ]; then echo " $(RM) debugger/?*.o"; \ @@\ + $(RM) debugger/?*.o; else exit 0; fi + + +/* + * SharedLibraryObjectRule: + * Generate make rules to build shared and "normal" object files. + */ +#define SharedLibraryObjectRule() @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d shared ]; then mkdir shared; else exit 0; fi @!\ + @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ shared/$@ @!\ +|rule: $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o shared/$*.o @!\ +|rule: $(CC) -c $(SHLIBDEF) $(JCFLAGS) $*.c @!\ +|rule: @!\ +local_clean:: @@\ + -@if [ -d shared ]; then echo " $(RM) shared/?*.o"; \ @@\ + $(RM) shared/?*.o; else exit 0; fi + +/* + * SharedAndDebuggedLibraryObjectRule: + * Generate make rules to build shared, debuggable, and "normal" + * object files. + */ +#define SharedAndDebuggedLibraryObjectRule() @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d shared ]; then mkdir shared; else exit 0; fi @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +|rule:.c.o: @!\ +|rule: $(RM) $@ shared/$@ debugger/$@ @!\ +|rule: $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o shared/$*.o @!\ +|rule: $(CC) -g -c $(SHLIBDEF) $(JCFLAGS) $*.c @!\ +|rule: $(MV) $*.o debugger/$*.o @!\ +|rule: $(CC) -c $(SHLIBDEF) $(JCFLAGS) $*.c @!\ +|rule: @!\ +local_clean:: @@\ + -@if [ -d shared ]; then echo " $(RM) shared/?*.o"; \ @@\ + $(RM) shared/?*.o; else exit 0; fi @@\ + -@if [ -d debugger ]; then echo " $(RM) debugger/?*.o"; \ @@\ + $(RM) debugger/?*.o; else exit 0; fi + +/* + * SpecialSharedAndDebuggedObjectRule: + * Generate rules to compile a file with special flags and to make + * shared and debuggable versions. + */ +#define SpecialSharedAndDebuggedObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d shared ]; then mkdir shared; else exit 0; fi @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +objs: depends @@\ + $(RM) $@ shared/$@ debugger/$@ @@\ + $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) options $*.c @@\ + $(MV) $*.o shared/$*.o @@\ + $(CC) -g -c $(SHLIBDEF) $(JCFLAGS) options $*.c @@\ + $(MV) $*.o debugger/$*.o @@\ + $(CC) -c $(SHLIBDEF) $(JCFLAGS) options $*.c + +/* + * SpecialSharedObjectRule: + * Generate rules to compile a file with special flags and to make + * shared and debuggable versions. + */ +#define SpecialSharedObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d shared ]; then mkdir shared; else exit 0; fi @!\ + @!\ +objs: depends @@\ + $(RM) $@ shared/$@ @@\ + $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) options $*.c @@\ + $(MV) $*.o shared/$*.o @@\ + $(CC) -c $(SHLIBDEF) $(JCFLAGS) options $*.c + + +/* + * SpecialObjectRule: + * Generate rules to compile a file with special flags. + */ +#define SpecialObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>JCFLAGS @!\ +objs: depends @@\ + $(RM) $@ @@\ + $(CC) -c $(JCFLAGS) options $*.c + + +/* + * SpecialProfiledObjectRule: + * Generate rules to compile a file with special flags and to make a + * profiled version. + */ +#define SpecialProfiledObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi @!\ + @!\ +objs: depends @@\ + $(RM) $@ profiled/$@ @@\ + $(CC) -pg -c $(JCFLAGS) options $*.c @@\ + $(MV) $*.o profiled/$*.o @@\ + $(CC) -c $(JCFLAGS) options $*.c + + +/* + * SpecialDebuggedObjectRule: + * Generate rules to compile a file with special flags and to make a + * debuggable version. + */ +#define SpecialDebuggedObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +objs: depends @@\ + $(RM) $@ debugger/$@ @@\ + $(CC) -g -c $(JCFLAGS) options $*.c @@\ + $(MV) $*.o debugger/$*.o @@\ + $(CC) -c $(JCFLAGS) options $*.c + + +/* + * SpecialDebuggedAndProfiledObjectRule: + * Generate rules to compile a file with special flags and to make + * debuggable and profiled versions. + */ +#define SpecialDebuggedAndProfiledObjectRule(objs,depends,options) @!\ +>RM @!\ +>CC @!\ +>MV @!\ +>JCFLAGS @!\ +all:: @@\ + @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi @@\ + @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi @!\ + @!\ +objs: depends @@\ + $(RM) $@ profiled/$@ debugger/$@ @@\ + $(CC) -pg -c $(JCFLAGS) options $*.c @@\ + $(MV) $*.o profiled/$*.o @@\ + $(CC) -g -c $(JCFLAGS) options $*.c @@\ + $(MV) $*.o debugger/$*.o @@\ + $(CC) -c $(JCFLAGS) options $*.c + + +/* + * NormalLibraryTarget: + * Generate rules to create a library. The 'srclist' and 'objlist' + * parameters are added to SOURCES and OBJECTS macros. The 'srclist' + * is not otherwise used by this rule, but is necessary for make depend. + */ +#define NormalLibraryTarget(libname,srclist,objlist) @!\ +>RM @!\ +>AR @!\ +>RANLIB @!\ +++OBJECTS objlist @!\ +++SOURCES srclist @!\ +NormalLibraryObjectRule() @!\ +AllTarget(lib^^libname.a) @!\ + @!\ +lib^^libname.a: objlist @@\ + $(RM) $@ @@\ + $(AR) $@ objlist @@\ + $(RANLIB) $@ + + +/* + * NormalSharedLibraryTarget: + * Generate rules to create a shared library; build it into a + * different name so that the we don't hose people by having the + * library gone for long periods. + */ +#define NormalSharedLibraryTarget(libname,rev,solist) @!\ +>RM @!\ +>LD @!\ +>MV @!\ +AllTarget(lib^^libname.so.rev) @!\ + @!\ +lib^^libname.so.rev: solist @@\ + $(RM) $@~ @@\ + (cd shared; $(LD) -o ../$@~ -assert pure-text solist) @@\ + $(RM) $@ @@\ + $(MV) $@~ $@ + +/* + * NormalSharedLibraryDataTarget: + * Generate rules to create shlib data file; build it into a + * different name so that the we don't hose people by having the + * library gone for long periods. + */ +#define NormalSharedLibraryDataTarget(libname,rev,salist) @!\ +>RM @!\ +>AR @!\ +>RANLIB @!\ +AllTarget(lib^^libname.sa.rev) @!\ + @!\ +lib^^libname.sa.rev: salist @@\ + $(RM) $@ @@\ + $(AR) $@ salist @@\ + $(RANLIB) $@ + + +/* + * NormalLibraryTarget2: + * Generate rules to create a library in two steps. This is used to + * create libraries with large numbers of files. + */ +#define NormalLibraryTarget2(libname,srclist,objlist1,objlist2) @!\ +>RM @!\ +>AR @!\ +>RANLIB @!\ +++SOURCES srclist @!\ +++OBJECTS objlist1 @!\ +++OBJECTS objlist2 @!\ +NormalLibraryObjectRule() @!\ +AllTarget(lib^^libname.a) @!\ + @!\ +lib^^libname.a: objlist1 objlist2 @@\ + $(RM) $@ @@\ + $(AR) $@ objlist1 @@\ + $(AR) $@ objlist2 @@\ + $(RANLIB) $@ + + +/* + * ProfiledLibraryTarget: + * Generate rules to create a profiled library. + */ +#define ProfiledLibraryTarget(libname,srclist,objlist) @!\ +>RM @!\ +>AR @!\ +>RANLIB @!\ +++SOURCES srclist @!\ +++OBJECTS objlist @!\ +AllTarget(lib^^libname^^_p.a) @!\ + @!\ +lib^^libname^^_p.a: objlist @@\ + $(RM) $@ @@\ + cd profiled; $(AR) ../$@ objlist @@\ + $(RANLIB) $@ + + +/* + * DebuggedLibraryTarget: + * Generate rules to create a debuggable library. + */ +#define DebuggedLibraryTarget(libname,srclist,objlist) @!\ +>RM @!\ +>AR @!\ +>RANLIB @!\ +++SOURCES srclist @!\ +++OBJECTS objlist @!\ +AllTarget(lib^^libname^^_d.a) @!\ + @!\ +lib^^libname^^_d.a: objlist @@\ + $(RM) $@ @@\ + cd debugger; $(AR) ../$@ objlist @@\ + $(RANLIB) $@ + + +/* + * AliasedLibraryTarget: + * Generate rules to link one library to another. + */ +#define AliasedLibraryTarget(libname,alias) @!\ +>RM @!\ +>LN @!\ +AllTarget(lib^^alias.a) @!\ + @!\ +lib^^alias.a: lib^^libname.a @@\ + $(RM) $@ @@\ + $(LN) lib^^libname.a $@ + + +/* + * PrelinkedRelocatableTarget: + * Generate rules to produce a relocatable object file instead of a + * library. + */ +#define PrelinkedRelocatableTarget(objname,objlist,libs) @!\ +>RM @!\ +>LD @!\ +>JLKFLAGS @!\ +AllTarget(objname.o) @!\ + @!\ +objname.o: objlist @@\ + $(RM) $@ @@\ + $(LD) $(JLKFLAGS) -r objlist -o $@ libs + + +/* + * NormalRelocatableTarget: + * Generate rules to produce a relocatable object file instead of a + * library. + */ +#define NormalRelocatableTarget(objname,objlist) @!\ +>RM @!\ +>LD @!\ +>JLKFLAGS @!\ +AllTarget(objname.o) @!\ + @!\ +objname.o: objlist @@\ + $(RM) $@ @@\ + $(LD) $(JLKFLAGS) -r objlist -o $@ + + +/* + * ProfiledRelocatableTarget: + * Generate rules to produce a profiled relocatable object file + * instead of a library. + */ +#define ProfiledRelocatableTarget(objname,objlist) @!\ +>RM @!\ +>LD @!\ +AllTarget(objname^^_p.o) @!\ + @!\ +objname^^_p.o: objlist @@\ + $(RM) $@ @@\ + $(LD) -X -r objlist -o $@ + + +/* + * DebuggedRelocatableTarget: + * Generate rules to produce a debuggable relocatable object file + * instead of a library. + */ +#define DebuggedRelocatableTarget(objname,objlist) @!\ +>RM @!\ +>LD @!\ +AllTarget(objname^^_d.o) @!\ + @!\ +objname^^_d.o: objlist @@\ + $(RM) $@ @@\ + $(LD) -X -r objlist -o $@ + +/* + * LintLibraryTarget: + * Generate rules to create a lint library. Note that the lint + * library is always forced to be newer than the library itself. + */ +#define LintLibraryTarget(libname,srclist) @!\ +>RM @!\ +>LINT @!\ +lintlib:: llib-l^^libname.ln @!\ + @!\ +llib-l^^libname.ln: srclist @@\ + $(RM) $@ @@\ + $(LINT) $(LINTLIBFLAG)^^libname $(LINTFLAGS) srclist + + +/* + * NormalLintTarget: + * Generate rules to lint a set of sources. + */ +#define NormalLintTarget(srclist) @!\ +>LINT @!\ +lint: @@\ + $(LINT) $(LINTFLAGS) srclist $(LINTLIBS) + + +/* + * LintTarget: + * Generate rules to lint $(SOURCES) (automatically generated) + */ +#define LintTarget() @!\ +|once _LintTarget_ @!\ +NormalLintTarget($(SOURCES)) @!\ +-once + + +/* + * LinkSourceFile: + * Snag source file from some other directory + */ +#define LinkSourceFile(src,dir) @!\ +>RM @!\ +>LN @!\ +src: dir/src @@\ + $(RM) $@ @@\ + $(LN) $? $@ @!\ + + +/* + * MakeSubincludesForBuild: + * Make includes in sub directories. + */ +#define MakeSubincludesForBuild(step,dir,srclist) @!\ +>RM @!\ +>LN @!\ +step:: dir srclist @@\ + @-(list=`echo srclist | sed -e 's/[^ ]*\///g'`; \ @@\ + set -x; cd dir; $(RM) $$list) @@\ + @for i in srclist; do \ @@\ + (set -x; cd dir; $(LN) ../$$i .); \ @@\ + done @!\ + @!\ +MakeDirectories(dir,dir) @!\ + @!\ +local_realclean:: @@\ + @-(if [ -d dir ]; then \ @@\ + list=`echo srclist | sed -e 's/[^ ]*\///g'`; \ @@\ + set -x; cd dir; $(RM) $$list; else exit 0; fi) + + +/* + * CommonSubdirsRule: + * Rule for making $(TARGET) in every subdirectory, with $(VERB) as + * verbose message and $(FLAGS) as additional flags. + */ +#define CommonSubdirsRule(dirs) @!\ +>MAKE @!\ +subdirs: @@\ + @case '${MFLAGS}' in *[ik]*) set +e;; esac; \ @@\ + for i in dirs ;\ @@\ + do \ @@\ + (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \ @@\ + $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \ @@\ + done + + +/* + * NamedTargetSubdirsRule: + * Recursively make a series of steps in the specified directories. + */ +#define NamedTargetSubdirsRule(dirs,name,verb,flags) @!\ +>MAKE @!\ +name:: @@\ + @case '${MFLAGS}' in *[ik]*) set +e;; esac; \ @@\ + for i in dirs ;\ @@\ + do \ @@\ + (cd $$i ; echo verb "in $(DIR)$$i..."; \ @@\ + $(MAKE) $(MFLAGS) flags name); \ @@\ + done + + +/* + * NamedTargetSubdirs: + * Recursively make a series of steps. + */ +#define NamedTargetSubdirs(name,verb,flags) @!\ +>MAKE @!\ +name:: @@\ + @$(MAKE) subdirs TARGET=name VERB=verb FLAGS=flags + + +/* + * NamedCleanTargetSubdirs: + * Recursively make a series of cleaning. We first clean the + * subdirectories, in case the Makefile is removed by the + * clean entry. + */ +#define NamedCleanTargetSubdirs(name,verb,flags) @!\ +>MAKE @!\ +sub_^^name:: @@\ + @$(MAKE) subdirs TARGET=name VERB=verb FLAGS=flags @@\ + @echo "Back to $(CURRENT) for "name^^... + + +/* + * MakeSubdirs: + * Generate rules to do makes in the given subdirectories. + */ +#define MakeSubdirs() \ +NamedTargetSubdirs(all,"Making all",^^) + + +/* + * DependDirs: + * Generate rules to recursively compute dependencies as part of the + * make depend step. + */ +#define DependDirs(dirs) \ +NamedTargetSubdirsRule(dirs,depend,"Depending",^^) + + +/* + * DependSubdirs: + * Generate rules to recursively compute dependencies as part of the + * make depend step. + */ +#define DependSubdirs() \ +DependDirs($(SUBDIRS)) + + +/* + * InstallSubdirs: + * Generate rules to recursively install and deinstall programs and + * files. + */ +#define InstallSubdirs() \ +NamedTargetSubdirs(install,"Installing",^^) @!\ +NamedTargetSubdirs(deinstall,"Deinstalling",^^) + + +/* + * InstallManSubdirs: + * Generate rules to recursively install and deinstall manual pages. + */ +#define InstallManSubdirs() \ +NamedTargetSubdirs(install.man,"Installing man pages",^^) @!\ +NamedTargetSubdirs(deinstall.man,"Deinstalling man pages",^^) + + +/* + * IncludesSubdirs: + * Generate rules to recursively put include files in build + */ +#define IncludesSubdirs() \ +NamedTargetSubdirs(includes,including,^^) + + +/* + * CleanSubdirs: + * Generate rules to recursively clean out garbage files. + */ +#define CleanSubdirs() \ +NamedCleanTargetSubdirs(clean,"Cleaning",^^) @!\ +NamedCleanTargetSubdirs(realclean,"Real cleaning",^^) @!\ +NamedCleanTargetSubdirs(clobber,"Clobbering",^^) + + +/* + * TagSubdirs: + * Generate rules to recursively create tags files. + */ +#define TagSubdirs(dirs) \ +NamedTargetSubdirsRule(dirs,tag,"Tagging",^^) + +/* + * MakeLintSubdirs: + * Generate rules to recursively lint directories as part of the + * named step. + */ +#define MakeLintSubdirs(dirs,target) \ +NamedTargetSubdirsRule(dirs,target,"Linting",^^) + + +/* + * LintDirs: + * Generate rules to recursively lint directories as part of the + * make lint step. + */ +#define LintDirs(dirs) \ +MakeLintSubdirs(dirs,lint) + + +/* + * LintSubdirs: + * Generate rules to recursively lint directories as part of the + * make lint step. + */ +#define LintSubdirs() \ +LintDirs($(SUBDIRS)) + + +/* + * MakeDirs: + * Creates a set of directories, even if some directories in the path + * do not already exist.There should be no '@!' at the end of the + * '#define' line, because this macro is used *inside* building rules. + */ +#define MakeDirs(dirs) \ +>INSTALLDIR @@\ + @for dir in dirs; do \ @@\ + case '${MFLAGS}' in *[i]*) set +e;; esac; \ @@\ + (set -x; test -d $$dir || $(INSTALLDIR) $$dir); \ @@\ + done + +/* + * MakeDirectories: + * Generate rules to create a hierarchy of directories. + */ +#define MakeDirectories(step,dirs) @!\ +step:: @@\ + MakeDirs(dirs) + + +/* + * MakeInstallDirectories: + * Generate a rule to create a set of directories at installation + * time (removed by deinstall). + */ +#define MakeInstallDirectories(dirs) @!\ +>RM @!\ +install:: @@\ + MakeDirs(dirs) @!\ + @!\ +deinstall:: @@\ + $(RM) -r dirs + + +/* + * MakeLintLibSubdirs: + * Generate rules to recursively create lint libraries. + */ +#define MakeLintLibSubdirs(dirs) @!\ +MakeLintSubdirs(dirs,lintlib) + + +/* + * MakeMakeSubdirs: + * Generate rules to recursively recreate target as part of the + * specified step in the build. This assumes Makefile.SH has + * already been built (which is the case for a delivery), but does + * not rely on the existence of a Makefile. + */ +#define MakeMakeSubdirs(target) @!\ +>MAKE @!\ +target:: @@\ + @case '${MFLAGS}' in *[ik]*) set +e;; esac; \ @@\ + for i in $(SUBDIRS);\ @@\ + do \ @@\ + echo "Making "target" in $(DIR)$$i..."; \ @@\ + (cd $$i || exit 1; \ @@\ + if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \ @@\ + $(MAKE) $(MFLAGS) target) \ @@\ + done + + +/* + * MakeMakefilesSH: + * Generate rules to recursively recreate target as part of the + * specified step in the build. If $(TOP) is set to an absolute + * path, don't prepend the ../ prefix. This makes running things + * outside of the source tree to be much easier. + */ +#define MakeMakefilesSH() @!\ +>MAKE @!\ +Makefiles.SH:: Makefile.SH @@\ + @case '${MFLAGS}' in *[ik]*) set +e;; esac; \ @@\ + for i in $(SUBDIRS);\ @@\ + do \ @@\ + case "$(DIR)$$i/" in \ @@\ + ^^*^^/^^*^^/^^*^^/^^*^^/) newtop=../../../..;; \ @@\ + ^^*^^/^^*^^/^^*^^/) newtop=../../..;; \ @@\ + ^^*^^/^^*^^/) newtop=../..;; \ @@\ + *^^/) newtop=..;; \ @@\ + esac; \ @@\ + case "$(TOP)" in \ @@\ + /^^*) newtop="$(TOP)" ;; \ @@\ + esac; \ @@\ + echo "Making Makefiles.SH in $(DIR)$$i..."; \ @@\ + (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \ @@\ + Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\ @@\ + $(MAKE) $(MFLAGS) Makefiles.SH) \ @@\ + done + + +/* + * MakefileSubdirs: + * Generate rules to create Makefiles. + */ +#define MakefileSubdirs() @!\ +MakeMakeSubdirs(Makefiles) @!\ +MakeMakefilesSH() + + +/* + * CppScriptTarget: + * Generate rules to create a shell script by running the input + * through cpp. + */ +#define CppScriptTarget(dst,src,defs,deplist) @!\ +>RM @!\ +>CPP @!\ +dst:: src deplist @@\ + $(RM) $@ @@\ + $(CPP) defs <src | \ @@\ + sed -e '/^# *[0-9][0-9]* *.*$$/d' >$@ @@\ + chmod a+x $@ + + +/* + * MakeScriptFromCpp: + * Generate rules to create a script from a file with a + * .cpp suffix. + */ +#define MakeScriptFromCpp(name,defs) @!\ +CppScriptTarget(name,name.cpp,defs,^^) + + +/* + * ShellScriptTargetExt: + * Generate rules to create and install a set of scripts from + * ext files (.sh and .SH are the most common examples). Man pages + * derived from the name of the scripts are also installed unless + * NoManPages() is specified. + */ +#define ShellScriptTargetExt(scripts,ext) @!\ +++SCRIPTS scripts @!\ +SimpleShellScriptTargetExt(scripts,ext) @!\ +InstallScripts() @!\ +InstallManScripts() + + +/* + * ShellScriptTarget: + * Generate rules to create and install a set of scripts from + * .SH files. Man pages derived from the name of the scripts are + * also installed unless NoManPages() is specified. + */ +#define ShellScriptTarget(scripts) @!\ +ShellScriptTargetExt(scripts,.SH) + + +/* + * SimpleShellScriptTargetExt: + * Generate rules to create a set of scripts from ext files where + * ext is usually something like .sh or .SH, or whatever file + * extension you like.. + */ +#define SimpleShellScriptTargetExt(scripts,ext) @!\ +>RM @!\ +AllTarget(scripts) @!\ + @!\ +|expand s!scripts! @!\ +!s: !s^^ext @@\ + /bin/sh !s^^ext @!\ + @!\ +-expand + + +/* + * SimpleShellScriptTarget: + * Generate rules to create a set of scripts from .SH files. + */ +#define SimpleShellScriptTarget(scripts) @!\ +SimpleShellScriptTargetExt(scripts,.SH) + + +/* + * ShellScriptLongTarget: + * Generate rules to create a set of scripts from .SH files where + * the name of the generated file is different from the basename of + * the .SH file (when, for instance, the total length with the .SH + * extension would not leave enough space for RCS ,v extension). + */ +#define ShellScriptLongTarget(basename,scriptname) @!\ +>RM @!\ +>MANSRC @!\ +++LSCRIPTS scriptname @!\ +AllTarget(scriptname) @!\ + @!\ +scriptname: basename^^.SH @@\ + /bin/sh basename^^.SH @!\ + @!\ +InstallScripts() @!\ +?NOMAN:|skip @!\ +InstallManPageLong(basename,$(MANSRC),scriptname) @!\ +-skip + + +/* + * ForceTarget: + * The force target will force reconstruction of all the other + * targets which include .FORCE in their own dependencies. + */ +#define ForceTarget() @!\ +|once _force_ @!\ +.FORCE: @!\ + @!\ +-once + + +/* + * RemoteTargetDependency: + * A local target may rely on a remote dependency (e.g. a library) + * made in a separate directory. This rule explicits the dependency + * and forces a make of that dependency in the remote directory. + */ +#define RemoteTargetDependency(target,directory,dependency) @!\ +>MAKE @!\ +RemoteDependency(directory,dependency) @!\ +target: directory/dependency @!\ + + +/* + * RemoteDependency: + * Specify rules for making a remote dependency. + */ +#define RemoteDependency(directory,dependency) @!\ +>MAKE @!\ +ForceTarget() @!\ +|once =directory/dependency= @!\ +directory/dependency: .FORCE @@\ + @echo "Checking "dependency" in "directory"..." @@\ + cd directory; $(MAKE) dependency @@\ + @echo "Continuing in $(CURRENT)..." @!\ + @!\ +-once + +/* + * SetSubdirs: + * Actually forces the definition of SUBDIRS, and lets the user + * specify what the sub-directories are. This will be added to the + * customization part. + */ +#define SetSubdirs(subdirs) @!\ +>SUBDIRS @!\ ++SUBDIRS = subdirs + + +/* + * NoManPages: + * Actually forces the definition of NOMAN, which tells the jmake + * program to not generate rules for installing manual pages. + */ +#define NoManPages() @!\ +>NOMAN + + +/* + * Expand: + * This powerful macro expands the `rule' given a `pattern'. It + * relies on a built-in command in jmake. The expansion is + * documented in the short notes file that comes with jmake and + * gives some insights on the internal syntax. + */ +#define Expand(rule, pattern) @!\ +|expand pattern @!\ +rule @!\ +-expand + + +/* + * Lex and yacc stuff. + */ + +/* + * YaccRule: + * This is the rule which is used to build a .c file from a .y file. + */ +#define YaccRule() @!\ +AddSuffix(.y) @!\ +|once _YaccRule_ @!\ +|rule:.y.c: @!\ +|rule: $(YACC) $(JYFLAGS) $< @!\ +|rule: $(MV) y.tab.c $@ @!\ +|rule: @!\ +-once + +/* + * SimpleYaccTarget: + * Declare a yacc base.y file to be used in the building of the + * specified target program. The source file must be given without + * its final .y extension. The name of the .c and .o will be + * derived from the source file basename provided. + */ +#define SimpleYaccTarget(program,base) @!\ +>JYFLAGS @!\ +>YACC @!\ +>RM @!\ +>MV @!\ +++SOURCES base.y @!\ +++OBJECTS base.o @!\ +YaccRule() @!\ +program: base.c @!\ + @!\ +local_realclean:: @@\ + $(RM) base.c @!\ + + +/* + * ComplexYaccTarget: + * Declare a yacc base.y file to be used in the building of the + * specified target program. The source file must be given without + * its final .y extension. The name of the .c and .o will be + * derived from the source file basename provided. + * The difference with SimpleYaccTarget is the identifying process + * where all the 'yy' are replaced by the specified prefix. + */ +#define ComplexYaccTarget(program,base,prefix) @!\ +>JYFLAGS @!\ +>YACC @!\ +>RM @!\ +>SED @!\ +++SOURCES base.y @!\ +++OBJECTS base.o @!\ +program: base.c @!\ + @!\ +base.c: base.y @@\ + $(YACC) $(JYFLAGS) base.y @@\ + $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.c > base.c @@\ + $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h @@\ + $(RM) y.tab.c y.tab.h @!\ + @!\ +local_realclean:: @@\ + $(RM) base.c @!\ + + +/* + * SimpleYaccInclude: + * Declare that program will need an include file produced by + * the output of yacc on base.y, which typically produces a file + * named y.tab.h, which will be renamed as base.h. + * The only problem is that the dependencies towards base.h have + * to be manually given in the Jmakefile. + */ +#define SimpleYaccInclude(base) @!\ +>MV @!\ +>RM @!\ +base.h: base.c @@\ + @if test -f y.tab.h; then \ @@\ + echo " $(MV) y.tab.h $@"; \ @@\ + $(MV) y.tab.h $@; \ @@\ + else \ @@\ + exit 0; \ @@\ + fi @!\ + @!\ +local_realclean:: @@\ + $(RM) base.h + +/* + * ComplexYaccInclude: + * Declare that program will need an include file produced by + * the output of yacc on base.y, which typically produces a file + * named y.tab.h, which will be renamed as base.h. + * The difference with SimpleYaccInclude is the identifying process + * of the y.tab.h file where all 'yy' are renamed to prefix. + * The only problem is that the dependencies towards base.h have + * to be manually given in the Jmakefile. + */ +#define ComplexYaccInclude(base,prefix) @!\ +>RM @!\ +>SED @!\ +>CP @!\ +base.h: base.c @@\ + @if test -f y.tab.h; then \ @@\ + echo " $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h"; \ @@\ + $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h; \ @@\ + echo " $(RM) y.tab.h"; \ @@\ + $(RM) y.tab.h; \ @@\ + elif test -f base.h; then \ @@\ + echo " $(CP) base.h base.ht"; \ @@\ + $(CP) base.h base.ht; \ @@\ + echo " $(SED) -e 's/yy\(.\)/prefix\1/g' < base.ht > base.h"; \ @@\ + $(SED) -e 's/yy\(.\)/prefix\1/g' < base.ht > base.h; \ @@\ + echo " $(RM) base.ht"; \ @@\ + $(RM) base.ht; \ @@\ + else \ @@\ + exit 0; \ @@\ + fi @!\ + @!\ +local_realclean:: @@\ + $(RM) base.h + + +/* + * NormalYaccTarget: + * Declare a yacc base.y file which should produce a base.c and + * base.h file as derived from the output of yacc, to be used by + * the specified program. + */ +#define NormalYaccTarget(program,base) @!\ +SimpleYaccTarget(program,base) @!\ +SimpleYaccInclude(base) + + +/* + * IdentifiedYaccTarget: + * Declare a yacc base.y file which should produce a base.c and + * base.h file as derived from the output of yacc, to be used by + * the specified program. The specified prefix is used to remplace + * all the 'yy' in the generated file, for use when more than a + * single parser is needed in one executable. + */ +#define IdentifiedYaccTarget(program,base,prefix) @!\ +ComplexYaccTarget(program,base,prefix) @!\ +ComplexYaccInclude(base,prefix) + + +/* + * SimpleLexTarget: + * This declares a lex base.l file which is to be ran through + * lex to produce a base.c file. + */ +#define SimpleLexTarget(program,base) @!\ +>JLFLAGS @!\ +>LEX @!\ +>RM @!\ +>MV @!\ +++SOURCES base.l @!\ +++OBJECTS base.o @!\ +|once _LexRule_ @!\ +|rule:.l.c: @!\ +|rule: $(LEX) $(JLFLAGS) $< @!\ +|rule: $(MV) lex.yy.c $@ @!\ +|rule: @!\ +-once @!\ +AddSuffix(.l) @!\ +program: base.c @!\ + @!\ +local_realclean:: @@\ + $(RM) base.c @!\ + + +/* + * IdentifiedLexTarget: + * This declares a lex base.l file which is to be ran through + * lex to produce a base.c file. The prefix is used to replace + * the 'yy', so that the lexical analyzer may be identified. + */ +#define IdentifiedLexTarget(program,base,prefix) @!\ +>JLFLAGS @!\ +>LEX @!\ +>RM @!\ +>SED @!\ +++SOURCES base.l @!\ +++OBJECTS base.o @!\ +program: base.c @!\ + @!\ +base.c: base.l @@\ + $(LEX) $(JLFLAGS) base.l @@\ + $(SED) -e 's/yy\(.\)/prefix\1/g' < lex.yy.c > base.c @@\ + $(RM) lex.yy.c @!\ + @!\ +local_realclean:: @@\ + $(RM) base.c @!\ + + +/* + * NormalLexDependTarget: + * Declare that program will need an include file produced by + * the output of lex on base.l, which typically produces a file + * named lex.yy.c which will be renamed as base.c. Besides, the + * lexical analyzer needs the file parser.h produced by running + * parser.y through yacc and renaming y.tab.h as parser.h. + */ +#define NormalLexDependTarget(program,base,parser) @!\ +base.o: parser.h @!\ + @!\ +SimpleLexTarget(program,base) + + +/* + * IdentifiedLexDependTarget: + * Declare that program will need an include file produced by + * the output of lex on base.l, which typically produces a file + * named lex.yy.c which will be renamed as base.c. Besides, the + * lexical analyzer needs the file parser.h produced by running + * parser.y through yacc and renaming y.tab.h as parser.h. + * The lexical analyzer is identified with the supplied prefix, + * which replaces the regular 'yy' prefix in the symbol names. + */ +#define IdentifiedLexDependTarget(program,base,parser,prefix) @!\ +base.o: parser.h @!\ + @!\ +IdentifiedLexTarget(program,base,prefix) + + +/* + * NormalParserTarget: + * Specify that program is using the lex/yacc combination to + * produce a parser. The lexic and parser parameters are the + * base name of the .l and .y file, respectively. + */ +#define NormalParserTarget(program,lexic,parser) @!\ +NormalLexDependTarget(program,lexic,parser) @!\ +NormalYaccTarget(program,parser) + + +/* + * IdentifiedParserTarget: + * Specify that program is using the lex/yacc combination to + * produce a parser. The lexic and parser parameters are the + * base name of the .l and .y file, respectively. The parser + * produced is identified via its prefix, which replaces all + * the normally supplied 'yy' prefix, hence making it possible + * to have multiple parsers in a single executable. + */ +#define IdentifiedParserTarget(program,lexic,parser,prefix) @!\ +IdentifiedLexDependTarget(program,lexic,parser,prefix) @!\ +IdentifiedYaccTarget(program,parser,prefix) + + diff --git a/jmake/files/Jmake.tmpl b/jmake/files/Jmake.tmpl new file mode 100644 index 0000000..dceb604 --- /dev/null +++ b/jmake/files/Jmake.tmpl @@ -0,0 +1,208 @@ +/* + * Generic jmake template + * + * $Id: Jmake.tmpl,v 3.0.1.3 1997/02/28 14:56:16 ram Exp $ + * + * Copyright (c) 1991-1993, Raphael Manfredi + * + * You may redistribute only under the terms of the Artistic Licence, + * as specified in the README file that comes with the distribution. + * You may reuse parts of this distribution only within the terms of + * that same Artistic Licence; a copy of which may be found at the root + * of the source tree for dist 3.0. + * + * $Log: Jmake.tmpl,v $ + * Revision 3.0.1.3 1997/02/28 14:56:16 ram + * patch61: lex path can now be configured + * + * Revision 3.0.1.2 1995/01/11 14:50:21 ram + * patch45: now pre-computes INSTALL and INSTALLDIR variables + * + * Revision 3.0.1.1 1993/08/20 07:36:36 ram + * patch3: config.sh searching was not aborting properly + * + * Revision 3.0 1993/08/18 12:04:16 ram + * Baseline for dist 3.0 netwide release. + * + */ + +: Makefile.SH generated from Jmake.tmpl and Jmakefile <TAG> +: $Id: Jmake.tmpl,v 3.0.1.3 1997/02/28 14:56:16 ram Exp $ + +/************************************************************************* + * * + * DO NOT MODIFY BELOW THIS LINE * + * * + *************************************************************************/ + +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/#*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +|expand cur!CURDIR! +CURRENT=!cur:^\./= +-expand +DIR=`echo $CURRENT/ | sed -e 's/\.\///g'` +echo "Extracting ${DIR}Makefile (with variable substitutions)" +/* + * Variable pre-computation. + */ +?INSTALL:INSTALL=`echo $install | sed -e 's,\./i,\$(TOP)/i,'` +?INSTALLDIR:INSTALLDIR=`echo $installdir | sed -e 's,\./i,\$(TOP)/i,'` +DATE=`date` +/* + * Makefile generation. + */ +$spitshell >Makefile <<!GROK!THIS! +;######################################################################## +;# Makefile generated from Makefile.SH on $DATE + +SHELL = /bin/sh +JMAKE = jmake +TOP = TOPDIR +CURRENT = $CURRENT +DIR = $DIR +?INSTALL:INSTALL = $INSTALL +?INSTALLDIR:INSTALLDIR = $INSTALLDIR + +;######################################################################## +;# Parameters set by Configure -- edit config.sh if changes are needed + +?AR:AR = ar rc /* FIXME */ +?BINDIR:BINDIR = $installbin +?CC:CC = $cc +?CP:CP = $cp +?CPP:CPP = $cpp $cppminus $cppflags +?CTAGS:CTAGS = ctags /* FIXME */ +?JCFLAGS:JCFLAGS = \$(CFLAGS) $optimize $ccflags $large +?JLDFLAGS:JLDFLAGS = \$(LDFLAGS) $optimize $ldflags +?JLFLAGS:JLFLAGS = \$(LFLAGS) +?JYFLAGS:JYFLAGS = \$(YFLAGS) $yaccflags +?L:L = $manext +?LD:LD = ld +?LEX:LEX = $lex +?LIBS:LIBS = $libs +?LINT:LINT = lint +?LN:LN = $ln +?MANSRC:MANSRC = $installmansrc +?MAKE:MAKE = make /* Otherwise $(MAKE) doesn't work on SONY */ +?MKDEP:MKDEP = $mkdep \$(DPFLAGS) -- +?MV:MV = $mv +?PRIVLIB:PRIVLIB = $installprivlib +?RANLIB:RANLIB = $ranlib +?RM:RM = $rm -f +?SCRIPTDIR:SCRIPTDIR = $installscript +?SED:SED = $sed +?YACC:YACC = $yacc + +/* + * The following will only be added if at least one initialization + * rule was found in the Jmakefile. + */ +%INIT:|skip /* Skip if no initializations are necessary */ +;######################################################################## +;# Automatically generated parameters -- do not edit + +INIT_SECTION + +-skip /* Initializations */ +%SUFFIX:|skip /* Skip if no suffixes/rules are defined */ +;######################################################################## +;# New suffixes and associated building rules -- edit with care + +SUFFIX_SECTION +-skip /* Suffixes/Rules */ +!GROK!THIS! +$spitshell >>Makefile <<'!NO!SUBS!' +#include <Jmake.rules> + +%MKDEP:|skip /* Skip if no depend target */ +;######################################################################## +;# Force 'make depend' to be performed first -- do not edit + +.FORCE_DEPEND:: + +all:: .FORCE_DEPEND + +-skip /* Depend target */ +;######################################################################## +;# Start of Jmakefile +#include <Jmakefile> + +;######################################################################## +;# Common rules for all Makefiles -- do not edit +/* + * These need to be here so that rules in Jmakefile occur first; the blank + * all is to make sure that an empty Jmakefile doesn't default to make clean. + */ +emptyrule:: + +CleanTarget() +MakefileTarget() +TagsTarget() + +%SUBDIRS:|skip /* Skip if no sub-directories */ +;######################################################################## +;# Rules for building in sub-directories -- do not edit + +CommonSubdirsRule($(SUBDIRS)) +InstallSubdirs() +InstallManSubdirs() +CleanSubdirs() +TagSubdirs($(SUBDIRS)) +MakefileSubdirs() +MakeSubdirs() + +-skip /* Sub-directories */ +?SUBDIRS:|skip /* Skip if sub-directories */ +;######################################################################## +;# Empty rules for directories with no sub-directories -- do not edit + +install:: + @echo "install in $(CURRENT) done." + +deinstall:: + @echo "deinstall in $(CURRENT) done." + +install.man:: + @echo "install.man in $(CURRENT) done." + +deinstall.man:: + @echo "deinstall.man in $(CURRENT) done." + +/* + * Action for 'Makefiles' would be required, if a .SUFFIXES: .SH rule + * were added, because in that case, a "/bin/sh Makefiles.SH" would + * be issued and raise an error. + */ +Makefiles:: + +Makefiles.SH:: + +-skip /* No sub-directories */ +%MKDEP:|skip /* Skip if no depend target */ +;######################################################################## +;# Dependencies generated by make depend +;# DO NOT DELETE THIS LINE -- make depend relies on it + +;# Put nothing here or make depend will gobble it up +.FORCE_DEPEND:: +?TOP: @echo "You haven't run a 'make depend' yet!"; exit 1 +%TOP: @echo "You must run 'make depend' in $(TOP) first."; exit 1 +-skip /* Depend target */ +!NO!SUBS! +chmod 644 Makefile +$eunicefix Makefile + diff --git a/jmake/fixcpp.SH b/jmake/fixcpp.SH new file mode 100644 index 0000000..804325b --- /dev/null +++ b/jmake/fixcpp.SH @@ -0,0 +1,183 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting jmake/fixcpp (with variable substitutions)" +$spitshell >fixcpp <<!GROK!THIS! +$startperl + eval 'exec perl -S \$0 "\$@"' + if \$runnning_under_some_shell; + +# $Id: fixcpp.SH,v 3.0.1.1 1995/03/21 08:35:37 ram Exp $ +# +# Copyright (c) 1991-1993, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 3.0. +# +# $Log: fixcpp.SH,v $ +# Revision 3.0.1.1 1995/03/21 08:35:37 ram +# patch52: created +# + +# Thank you HP-UX for having a cpp that strips trailing backslashes in the +# text. As of today, you are the only reason for this program to exist. +# People designing such things should have their hands cut off to prevent +# them from doing further damage :-) +# +# This program is meant to be called from jmake. All it does is pre-process +# the file it is given as argument, focusing on #include directives and +# resolving them as cpp would (but without the #line stuff since we don't +# really care about it), escaping all the trailing \ into '\ ^M'. The resulting +# temporary file is then handed off to the real cpp for macro processing, and +# the output is printed on stdout, after restoration of any original trailing \. +# Again, thanks HP-UX for making this so challenging and exciting... :-) +# +# Note that we MUST leave alone all the trailing @!\ or @@\, since those appear +# in macros and must go away some way or the other. Also trailing backslashes +# on #define lines are really continuations and are left un-escaped. + +\$cpp = '$cpp'; +\$version = '$VERSION'; +\$patchlevel = '$PATCHLEVEL'; +!GROK!THIS! +$spitshell >>fixcpp <<'!NO!SUBS!' + +while ($ARGV[0] =~ /^-/) { + $_ = shift; + last if /--/; + $cpp_opt .= "$_ "; + next unless s/-I//; + push(@lookpath, $_); +} + +($file) = @ARGV; +$counter = 0; # Counter for temporary files + +$SIG{'INT'} = 'PLUMBER'; # Install cleaner in case of an interrupt... + +$result = &process($file); # Process file, result in a temporary +&cpp($result); # Pass resulting file with escaped \ to cpp +unlink $result; +exit 0; + +# Cleanup any temporary files... +sub PLUMBER { + warn "Could not cleanup all temporaries.\n" if @tmps != unlink(@tmps); + exit 1; +} + +# Compute a suitable temporary file name +sub mktmp { + $counter++; + local($tmp) = "/tmp/jmk.$counter.$$"; + push(@tmps, $tmp); # Keep track of them for &PLUMBER... + $tmp; +} + +# Process a given file, returning the name of the temporary file into which +# the result is left over. +# This routine is recursively called to process nested include directives. +sub process { + local($file) = @_; + local(*FILE, *TMP); + open(FILE, $file) || die "Can't read $file: $!\n"; + local($tmpfile) = &mktmp; + open(TMP, ">$tmpfile") || die "Can't create $tmpfile: $!\n"; + local($here, $include); + local($_); + while (<FILE>) { + if (s/^#\s*include\s*//) { # Ah, we found a #include something... + chop; + if (/"(\S+)"/) { + ($include, $here) = ($1, 1); + } elsif (/<(\S+)\>/) { + ($include, $here) = ($1, 0); + } else { + warn "Ignoring unkown include directive $_.\n"; + next; + } + local($incfile) = &lookup($include, $here); + unless (defined $incfile) { + warn "Can't locate include file $include.\n"; + next; + } + $include = &process($incfile); # Recursively process this file + &append($include, 'TMP'); # Append result to current tmp file + unlink $include; + } else { + &escape; + print TMP; + } + } + close FILE; + close TMP; + $tmpfile; # Return name of file where results has been left over +} + +# Perform necessary escaping work on current line. +sub escape { + # Don't escape trailing backslashes in macro definition or cpp + # won't see them as macro continuation any longer, and also within + # macro definitions, all those @@ or @! continuations... + s/\\$/\\ \015/ unless /\@[!@]\\$/ || /^#define/; +} + +# Append file to given (opened) file descriptor +sub append { + local($file, $fd) = @_; + local(*FILE); + open(FILE, $file) || die "Can't re-open $file: $!\n"; + local($_); + while (<FILE>) { + &escape; + print $fd $_; + } + close FILE; +} + +# Lookup file, returning its located name or undef if not found. +sub lookup { + local($file, $here) = @_; + unless ($here) { + foreach $dir (@lookpath) { + if (-r "$dir/$file") { # Use -r instead of -f for symlinks + $file = "$dir/$file"; + last; + } + } + } + return undef unless -r $file; + $file; +} + +# This is the final cpp processing. The output from cpp is filtered to un-escape +# all the trailing backslashes. +sub cpp { + local($file) = @_; + open(CPP, "$cpp $cpp_opt $file |") || die "Can't fork: $!\n"; + while (<CPP>) { + s/\\ \015$/\\/; # Un-escape trailing \ + print STDOUT; + } + close CPP; +} + +!NO!SUBS! +chmod 755 fixcpp +$eunicefix fixcpp diff --git a/jmake/jmake.SH b/jmake/jmake.SH new file mode 100755 index 0000000..38a49eb --- /dev/null +++ b/jmake/jmake.SH @@ -0,0 +1,390 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting jmake/jmake (with variable substitutions)" +$spitshell >jmake <<!GROK!THIS! +$startperl + eval 'exec perl -S \$0 "\$@"' + if \$runnning_under_some_shell; + +# $Id: jmake.SH,v 3.0.1.6 1995/09/25 09:08:01 ram Exp $ +# +# Copyright (c) 1991-1993, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 3.0. +# +# $Log: jmake.SH,v $ +# Revision 3.0.1.6 1995/09/25 09:08:01 ram +# patch59: will now force macro definitions to the left +# +# Revision 3.0.1.5 1995/07/25 13:34:47 ram +# patch56: all error messages are now prefixed with the program name +# +# Revision 3.0.1.4 1995/03/21 08:45:27 ram +# patch52: now invokes cpp through new fixcpp script +# patch52: first pass now skips cpp comments alltogether +# +# Revision 3.0.1.3 1994/10/29 15:47:01 ram +# patch36: added various escapes in strings for perl5 support +# +# Revision 3.0.1.2 1993/08/24 12:12:50 ram +# patch3: privlib dir was ~name expanded in the wrong place +# +# Revision 3.0.1.1 1993/08/19 06:42:13 ram +# patch1: leading config.sh searching was not aborting properly +# +# Revision 3.0 1993/08/18 12:04:17 ram +# Baseline for dist 3.0 netwide release. +# + +\$dir = '$privlib/files'; +\$cpp = '$cpp'; +\$version = '$VERSION'; +\$patchlevel = '$PATCHLEVEL'; +!GROK!THIS! +$spitshell >>jmake <<'!NO!SUBS!' + +($me = $0) =~ s|.*/(.*)|$1|; +$dir = &tilda_expand($dir); # ~name expansion +$file = $dir . '/Jmake.tmpl'; + +$cpp_opt = "-I. "; # For Jmakefile, which is local +while ($ARGV[0] =~ /^-/) { + $_ = shift; + last if /--/; + $cpp_opt .= "$_ "; +} +$cpp_opt .= "-I$dir"; + +# Thank you HP-UX for having a cpp that blindly strips trailing backslashes +# in the text. Run through cpp by using the fixcpp script... + +open(CPP, "$dir/fixcpp $cpp_opt $file |"); +while (<CPP>) { + # Record defined symbols in Jmakefile. We won't catch symbols + # in conditional commands, but that's ok, I hope. + if ($in_symbol) { + $val = $_; + $in_symbol = 0 if !($val =~ s/\\\s*$//); # Last line + if ($val = /^\|expand/) { # Found an expand command + $in_symbol = 0; # Stop gathering value + $val .= "void::x"; # Stop any incomplete escape sequence + } + chop($val); + $Makesym{$current_symbol} .= $val; + } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) { + # Found a makefile's macro declaration + $val = $2; + $current_symbol = $1; + if ($val =~ s/\\\s*$//) { # Remove final '\' + $in_symbol = 1; # This is a continuation line + } + $Makesym{$current_symbol} = $val; + push(@Order, $current_symbol); # Keep track of order + } + # Protect RCS keyword Id or Header from normal substitution + s/\$(Id|Header|Log)/\$X-$1/; + # Restore possibly escaped C comments + s|/#\*|/*|g; + s|\*#/|*/|g; + # Remove all ^^ (null space character) + s|\^\^||g; + # Restore escaped ^^ sequence + s|\^\\\^|^^|g; + next if /^#\s+\d+/; # Skip cpp commments + + s/^;#/#/; + s/@#\s?/\n/g; # Kept for backward compatibility + s/@!\s?/\n/g; + s/@@\s?/\n\t/g; + + $* = 1; + # A '\r' is added to all lines, in order to let 'split' keep them + # As lines ending with '\' won't fit in the next regular + # expression (why ?), we have to treat that special case separately + s/\n$/\r\n/g; + s/\\\s*$/\\\r/g; # Remove spaces after final '\' and add '\r' + $* = 0; + @macro = split(/\n/); + for ($i = 0; $i <= $#macro; $i++) { + chop($_ = $macro[$i]); # Remove final '\r' + s/\s+$//g; # Remove possible useless spaces + if (/^TOP\s*=\s*(\S+)/) { # Get the top from generated file + $top = $1; + } + if (s/^\s*>//) { # '>' means "symbol wanted" + $symbol{$_} = 1; + } elsif (s/^\s*\+//) { # '+' means "initialization section" + if (s/^\+(\w+)//) { # '++' means add to variable list + $added{$1} .= $_; + } else { # A single '+' means "add as is". + push(@init, $_); + } + } elsif (s/^\|//) { # Command for us + if (/suffix\s+(\S+)/) { # Add suffix + push(@suffix, $1) unless $seen{$1}; + $seen{$1} = 1; + } elsif (s/^rule://) { # Add building rule + s/^\s(\s*\S+)/\t$1/; # Make sure leading tab is there + push(@rule, $_); + } elsif (/^skip/) { # Unconditional skip... funny! + push(@makefile, "|$_"); # Skip handled in pass 2 + } elsif (/^expand/) { + push(@makefile, "|$_"); # Expand handled in pass 2 + } elsif (/^once\s+(\S+)/) { # Once handled in pass 1 + if ($Once{$1}++) { # Symbol already seen -- skip + for (; $i <= $#macro; $i++) { + last if $macro[$i] =~/^-once/; + } + warn("$me: -once not found for $1") + unless $macro[$i] =~/^-once/; + } + } else { + print "$me: Warning: unknown command $_\n"; + } + } else { + next if /^-once/; # Control statement removed + push(@makefile, $_); + } + } +} +close CPP; + +@key = keys(%added); +$last_was_blank = 1; # To avoid blank line at the top of the file +$symbol{'INIT'} = 1 if ($#init >= 0 || $#key >=0); # Initializations +$symbol{'SUFFIX'} = 1 if ($#suffix >= 0 || $#rule >=0); # Rules or suffixes +$symbol{'TOP'} = 1 if $top eq '.'; # If imake invoked for the top + +open(MAKEFILE, ">Makefile.SH"); +# We have to use for instead of foreach to handle 'skip' easily +line: for ($i = 0; $i <= $#makefile; $i++) { + $_ = $makefile[$i]; + next if /^-skip|-expand/; # They might have made a mistake + + s/<TAG>/[jmake $version PL$patchlevel]/; + if (/^\s*$/) { + next if ($last_was_blank); + $last_was_blank = 1; + } else { + $last_was_blank = 0; + } + + # Lines starting with ?SYMBOL: (resp. %SYMBOL:) are to be processed + # only if SYMBOL is defined (resp. undefined). + + # Apply in sequence + while (/^\s*\?|\s*%/) { + if (s/^\s*\?(\w+)://) { # Wanted symbol ? + next line unless $symbol{$1}; + } elsif (s/^\s*%(\w+)://) { # Unwanted symbol ? + next line if $symbol{$1}; + } else { + print "$me: Warning: missing ':' in $_\n"; + last; + } + } + + # We wish to make sure there is a leading tab if the line starts with + # a space to prevent problems later on. However, variable definitions + # might want to be aligned on the '=' (imake style). Not all make + # may be able to cope with those though, so they are left justified + # again. + + s/^\s/\t/ unless /^\s+\w+\s+=/; # Make sure leading tab is there + s/^\s+(\w+\s+=)/$1/; # Left justify variable definition + s/^;#/#/; # Comments in Jmakefile + + if (s/^\|//) { # Command for us + if (/^skip/) { # Skip until -skip + for (; $i <= $#makefile; $i++) { + last if $makefile[$i] =~ /^-skip/; + } + } elsif (s/^expand//) { + do init_expand($_); # Initializes data structures + $i++; # Skip expand line + undef @Expand; # Storage for expanded lines + $pattern = ''; # Assume no pattern + for (; $i <= $#makefile; $i++) { + $_ = $makefile[$i]; + if (s/^-expand//) { # Reached end of expansion + if (s/^\s*(.*)/$1/) { # Expand followed by a pattern + $pattern = $_; # Get pattern to be removed + } + last; + } + s/^\s/\t/; # Make sure leading tab is there + push(@Expand, $_); # Line to be expanded + } + do expand($pattern); # Expand all lines in buffer + } else { + print "$me: Warning: unknown command $_\n"; + } + } elsif (/^INIT/) { # Initialization section + # All the initializations are put in the variable substitution + # section of the Makefile.SH. Therefore, we have to protect all + # the '$' signs that are not followed by an alphanumeric character. + foreach (@init) { + # Dumps core sometimes with perl 4.0 PL10 + # do protect_dollars(*_); + $_ = do protect_dollars($_); + do print_makefile($_); + } + foreach (@key) { # @key set earlier to keys(%added) + $_ .= " = " . $added{$_}; + # Dumps core sometimes with perl 4.0 PL10 + # do protect_dollars(*_); + $_ = do protect_dollars($_); + do print_makefile($_); + } + } elsif (/^SUFFIX/) { # Suffixes/Rules section + # Rules and suffixes are put in the variable substitution + # section of the Makefile.SH. Therefore, we have to protect all + # the '$' signs that are not followed by an alphanumeric character. + if ($#suffix >= 0) { + print MAKEFILE ".SUFFIXES:"; + foreach (@suffix) { + # Dumps core sometimes with perl 4.0 PL10 + # do protect_dollars(*_); + $_ = do protect_dollars($_); + print MAKEFILE " $_"; + } + print MAKEFILE "\n\n"; + } + foreach (@rule) { + # Dumps core sometimes with perl 4.0 PL10 + # do protect_dollars(*_); + $_ = do protect_dollars($_); + print MAKEFILE "$_\n"; + } + } else { + do print_makefile($_); + } +} +close MAKEFILE; + +sub protect_dollars { + # Dumps core sometimes with perl 4.0 PL10 + # local(*_) = shift(@_); + s/\\\$/\\=/g; # Protect already escaped '$' + s/(\$\W)/\\$1/g; # Escape unprotected '$' + s/\\=/\\\$/g; # Restore escaped '$' + $_; # Because perl dumps core... :-( +} + +# Initializes data structures for expansion. If we detect Makefile +# macro in the 'expand' line (the argument), then we write a small +# makefile that will do the substitution for us -- I'm lazy today :-) +sub init_expand { + local($_) = shift(@_); + undef %Vars; # Reset array of variables + $Vars_len = 0; # Number of "symbols" in first expanded + if (/\$\(\w+\)/) { # If at least one macro + local($make) = "/tmp/mkjm$$"; + open(MAKE, ">$make") || die "$me: can't create $make: $!\n"; + do gen_variables(); # Generates already computed variables + foreach $var (@Order) { # Print each in order we found them + print MAKE "$var = $Makesym{$var}\n" if !$Gvars{$var}; + } + print MAKE "all:\n\t\@echo '$_'\n"; + close MAKE; + chop($_ = `make -f $make all`); + unlink($make); + } + while (s/^\s*(\w+)!([^!]*)!//) { + $Vars{$1} = $2; + # Record only length for _first_ expanded symbol + $Vars_len = split(/\s\s*/, $2) unless $Vars_len; + } +} + +# Expand lines in the @Expand array. The argument is a pattern which is to +# be removed from the last chunk of expanded lines. +# For each symbol s, !s is replaced by the next item, and !s:p=q does the +# same after having replaced the pattern 'p' by pattern 'q' in the item. +# Spaces are NOT allowed in 'p' or 'q'. Substitution is done once (no /g). +sub expand { + local($pattern) = shift; # To-be-removed pattern for last chunk + local($_); + local($sub); + local($i); + local(@expands); + for ($i = 0; $i < $Vars_len; $i++) { + foreach $line (@Expand) { + $_ = $line; # Don't modify elements in array + foreach $sym (keys %Vars) { + @expands = split(/\s\s*/, $Vars{$sym}); + $sub = $expands[$i]; + $sub =~ s/\/\///g; # // is a void value + while (s/!${sym}:([^\s]*)=([^\s]*)/,x##x,/) { + # Replacing item is altered by some pattern + local($p) = $1; + local($q) = $2; + local($subq) = $sub; + eval "\$subq =~ s=${p}=${q}="; + s/,x##x,/${subq}/; + } + s/!${sym}/${sub}/g; + } + # Protect substitution in an 'eval' in case of error + eval "s/${pattern}\$//" if $pattern && $i == ($Vars_len - 1); + do print_makefile($_); + } + } +} + +# Prints its argument in MAKEFILE and records it also in Generated +sub print_makefile { + local($_) = shift(@_); # Line to be printed + print MAKEFILE "$_\n"; + push(@Generated, "$_\n"); +} + +# Generates in MAKE file all the generated variable we have so far for +# final Makefile. This is mainly intended to allow expansion of variables +# which are already defined with an expand. +sub gen_variables { + undef %Gvars; # Reset already generated variables + local ($in_symbol) = 0; # True when in variable (Makefile's macro) + foreach (@Generated) { + if ($in_symbol) { + if (/^\s*(\w+)\s*=(.*)/) { # Missed the end of previous macro + $in_symbol = 0; + $Gvars{$1} = 1; # Definition of variable seen + $in_symbol = 1 if (/\\\s*$/); # There is a final '\' + print MAKE "void::\n"; # Cut incomplete esc sequence + } else { + $in_symbol = 0 if !(/\\\s*$/); # Last line + } + print MAKE; + } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) { + # Found a makefile's macro declaration + $Gvars{$1} = 1; # Definition of variable seen + $in_symbol = 1 if (/\\\s*$/); # There is a final '\' + print MAKE; + } + } + print MAKE "void::\n"; # Cut incomplete escape sequence +} + +!NO!SUBS! +$grep -v '^;#' ../pl/tilde.pl >>jmake +chmod 755 jmake +$eunicefix jmake diff --git a/jmake/jmake.man b/jmake/jmake.man new file mode 100644 index 0000000..235b0ba --- /dev/null +++ b/jmake/jmake.man @@ -0,0 +1,398 @@ +''' $Id: jmake.man,v 3.0.1.1 1995/05/12 11:57:58 ram Exp $ +''' +''' Copyright (c) 1991-1993, Raphael Manfredi +''' +''' You may redistribute only under the terms of the Artistic Licence, +''' as specified in the README file that comes with the distribution. +''' You may reuse parts of this distribution only within the terms of +''' that same Artistic Licence; a copy of which may be found at the root +''' of the source tree for dist 3.0. +''' +''' $Log: jmake.man,v $ +''' Revision 3.0.1.1 1995/05/12 11:57:58 ram +''' patch54: updated my e-mail address +''' +''' Revision 3.0 1993/08/18 12:04:18 ram +''' Baseline for dist 3.0 netwide release. +''' +.TH JMAKE 1 ram +.SH NAME +jmake \- a generic makefile builder +.SH SYNOPSIS +.B jmake +[ +.I cpp options +] +.SH DESCRIPTION +.I Jmake +builds a makefile out of a rather high level description held in a +.I Jmakefile +file. The generated file is a +.I Makefile.SH +rather than a simple makefile, which means it is ready to be used in +conjonction with +.I metaconfig. +In particular, parameters such as "where to install executables" will +be automatically determined by +.I Configure +and only the needed parameters will be taken into account. +.PP +To use +.I jmake +you have to write a +.I Jmakefile +first, which describes the way things are to be built. Your +.I Jmakefile +will be included inside a generic template through the C pre-processor. +This means you may use the usual C /**/ comments, but not the shell # comments. +The C comments will not appear in the generated +.I Makefile.SH +but lines starting with ;# will finally appear as shell comments. If you +have to write the string /* in the generated +.I Makefile.SH +then you have to escape it (otherwise +.I jmake +will think of it as the start of a C comment). Simply put a # in front +of the *, as in /#*. +.PP +You have a set of macros at your disposal, and all these macros are +listed in the Index file, along with the piece of code they will +expand to. Usually, a +.I Jmakefile +is fairly small and thus easier to maintain than a huge +.I Makefile. +Some internal powerful commands allow you to write +portable makefiles easily, without having to spend many efforts, because +someone else already did the job for you :-). +.PP +When you want to generate your makefile, you usually do not run +.I jmake +but use the +.I jmkmf +script which is a wrapper and will invoke +.I jmake +with the correct options. +.PP +All the knowledge of +.I jmake +is held in two files: the template +.I Jmake.tmpl +and the macro definition file +.I Jmake.rules. +The first file includes the second, along with the +.I Jmakefile. +It is sometimes necessary to know how things works to be able to correctly +use all the features provided. For instance, you may have to write your +own rules for a specific project. Although you cannot overwrite the +predefined rules, you can extent the +.I Jmake.rules +file or simply add your macros in your +.I Jmakefile. +You may also use +.I #include +statements when you want to share these macros and do not want to duplicate +the code. +.PP +The syntax in Jmake.rules is not elegant at all, but: +.sp +.PD 0 +.IP - +It is easy to parse (like sendmail.cf or troff files). +.IP - +The rules are not supposed to change very often. +.IP - +It is simple enough to be mastered in five minutes. :-) +.sp +Here is a small description: +.sp +.IP 1) +To deal with various \fIcpp\fR implementations: +.sp +.RS +.IP \(bu +Final @!\\ means: end of line, next line starts at the left margin. +.IP \(bu +Final @@\\ means: end of line, next line is to be indented by one tab. +.sp +.PP +There should always be one of @!\\ or @@\\ at the end of each line. +The only exception is for macros that are to be used as part of a +rule body (e.g. \fIRemoveTargetProgram\fR). In that case, the first +line (which holds the \fI#define\fR) should end with a single backslash. +.RE +.sp +.IP 2) +Symbol definitions: +.sp +.RS +.IP \(bu +>SYMBOL: defines the symbol. +.IP \(bu +?SYMBOL:<text>: keeps <text> iff SYMBOL is defined. +.IP \(bu +%SYMBOL:<text>: keeps <text> iff SYMBOL is not defined. +.sp +.PP +The ?SYM can be nested (logical AND), as in: +.sp +.in +5 +?SYMBOL:%TOKEN:text +.in -5 +.sp +which will keep text if SYMBOL is defined and TOKEN undefined. +To implement a logical OR, see below. +.RE +.sp +.IP 3) +Commands: +.sp +.RS +Commands can be passed to \fIjmake\fR. They start with a leading '|'. +Available commands are: +.sp +.IP \(bu +|suffix <sx>: adds <sx> to the .SUFFIXES: list in the makefile. +.IP \(bu +|rule:<text>: adds <text> to the building rule section. +.IP \(bu +|rule: <text>: same as before, with a leading tab. +.IP \(bu +|skip: skips text until a line starting with '-skip' is found. +.IP \(bu +|expand <pattern>: expand lines until '-expand' with <pattern>. A +complete example is shown below. +.IP \(bu +|once <symbol>: text up to '-once' appears only the first time. +.sp +.PP +Here is a way to implement a logical OR: +.sp +.in +5 +.nf +/* Implements SYMBOL or not TOKEN */ +?SYMBOL:text /* Keeps text if SYMBOL */ +%SYMBOL:|skip + %TOKEN:text /* Keeps text if not TOKEN */ +-skip +.fi +.in -5 +.sp +Actually, this is ugly, because the text has to appear twice. +Fortunately, I did not use it. :-) +.sp +.PP +The '|' commands cannot be nested. In particular, due to the simple +implementation of \fI|skip\fR, it is impossible to put \fI|skip\fR inside +a skipped part. However, a \fI|once\fR section may have \fI|skip\fR sections. +.sp +But actually, as you have surely already guessed, the best way to +implement a logical OR is to use De Morgan's Law: +.sp +.in +5 +.nf +not (p or q) <=> not p and not q + +/* Implements SYMBOL or not TOKEN (attempt #2) */ +%SYMBOL:?TOKEN:|skip +text /* If SYMBOL or not TOKEN */ +-skip +.sp +.in -5 +.fi +Who said they don't care ? ;-) +.sp +.PP +Expansion is done with the \fIexpand\fR command. It has been provided to +avoid some cumbersome writings in makefiles when you have to repeat some +silly lines that only differ in file names, for instance. Let's look at +an example first: +.sp +.in +5 +.nf +|expand a!foo bar! b!yes no! +!a:: + echo !a, !b +-expand +.fi +.in -5 +.sp +.PP +Then two rules will be printed, and the values of (a,b) for the first +will be (foo, yes), for the second (bar, no). Substitution is controled +by the '!' character. If the word to be substituted is part of another +one, detach with the ^^ construct as in: !b^^c. It is possible to +use Makefile macros in the <pattern>, and they will be expanded by +jmake. If this is not what you want, escape the first '$' sign (this is +a Makefile escape, i.e. you must double the '$', not precede it with a +backslash). A // stands for the null substitution value. +.sp +.PP +Here is another example which shows how the macro Expand can be used. +It is defined in \fIJmake.rules\fR as: +.sp +.in +5 +.nf +#define Expand(rule, pattern) @!\\ +|expand pattern @!\\ +rule @!\\ +-expand +.sp +.in -5 +.fi +So we can write in the \fIJmakefile\fR: +.sp +.in +5 +.nf +|skip +A = foo bar +-skip + +#define Rule @!\\ +$(DIR)/!a^^.o: !a^^.o @@\\ + $(CC) -c !a^^.c @@\\ + $(MV) !a^^.o $(DIR) + +Expand(Rule, a!$(A)!) +.sp +.in -5 +.fi +which will generate in \fIMakefile.SH\fR: +.sp +.in +5 +.nf +$(DIR)/foo.o: foo.o + $(CC) -c foo.c + $(MV) foo.o $(DIR) + +$(DIR)/bar.o: bar.o + $(CC) -c bar.c + $(MV) bar.o $$(DIR) +.sp +.in -5 +.fi +.sp +.PP +The 'A' declaration has been surrounded by \fIskip\fR, so that it does +not appear in the generated Makefile.SH, but it will be taken into +account by \fIjmake\fR for the substitution in the pattern. +.sp +.PP +The number of expansions is determined by the number of possible +values for the \fBfirst\fR parameter. If other parameters have less +substitution values, they will get void ones. +.sp +.PP +It is possible to add a regular expression at the end of '-expand'. This +regular expression will be removed from the final set of expansion at the +end of each line. It is also possible to do substitutions in the expanded +item, by using the syntax (if 'f' is the expanded variable) +!f:\fI<p>\fR=\fI<q>\fR +where \fI<p>\fR and \fI<q>\fR are two regular expressions (without spaces). +The pattern \fI<p>\fR will be replaced by the pattern \fI<q>\fR (only the first +occurrence will be replaced). +.sp +.PP +Finally, you may refer in the expanded section to variables whose value is +computed via another expansion, which makes it easy to define generic +\fIJmakefiles\fR. +.sp +Example: +.sp +.in +5 +.nf +SRC = foo.c bar.c +OBJ = \\ +|expand f!$(SRC)! + !f:\\.c=\\.o \\ +-expand \\\\ +INC = \\ +|expand f!$(OBJ)! + !f:\\.o=\\.h \\ +-expand \\\\ +.fi +.in -5 +.sp +which will generate in \fIMakefile.SH\fR: +.sp +.in +5 +.nf +SRC = foo.c bar.c +OBJ = \\ + foo.o \\ + bar.o +INC = \\ + foo.h \\ + bar.h +.in -5 +.fi +.sp +Do not forget to protect special characters in your regular expressions such +as backslash, point, etc... +.sp +.PP +The \fIonce\fR command is tagged with a name. The first time the name +appears, the once construct is ignored and the text up to '-once' will +be copied in the generated Makefile.SH. However, future occurences of +the same name will be ignored (\fIonce\fR will behave like \fIskip\fR). +.sp +Example: +.sp +.in +5 +.nf +|once this_is_a_name +<text> +-once +.sp +.in -5 +.fi +.sp +.RE +.IP 4) +Initializations: +.sp +.RS +.IP \(bu ++<line>: Puts the whole line in the initialization section. +.IP \(bu +++SYMBOL <value>: Adds <value> to the SYMBOL macro. +.RE +.sp +.IP 5) +User-defined variables: +.sp +The user may define CFLAGS, LDFLAGS or DPFLAGS as additional flags to be used +in C compilation, linking phase or depend target. It is thus possible to add +some extra flags such as -I or libraries for Makefiles in specific +sub-directories. +.sp +.PD +.SH AUTHOR +Raphael Manfredi <ram@hptnos02.grenoble.hp.com> +.SH FILES +.PD 0 +.TP 20 +Jmakefile +High level description of Makefile.SH +.TP +Jmake.rules +File holding the macro definitions +.TP +Jmake.tmpl +Template used to mould Makefile.SH +.PD +.SH BUGS +On systems whose +.I cpp +reduces multiple tabs and spaces to a single space, +.I jmake +attempts to put back any necessary tabs (which +.I make +expects in front of rules) but does not properly formats the +body of the rule itself. +.PP +There is a bootstraping problem when creating the first Makefile.SH, because +you cannot run it through a shell until there is a decent Configure +script, but you can't run \fImetaconfig\fR before there is a Makefile.SH +or some needed symbols will not be defined. +.SH "SEE ALSO" +jmkmf(1), metaconfig(1). diff --git a/jmake/jmkmf.SH b/jmake/jmkmf.SH new file mode 100755 index 0000000..8648306 --- /dev/null +++ b/jmake/jmkmf.SH @@ -0,0 +1,71 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting jmake/jmkmf (with variable substitutions)" +$spitshell >jmkmf <<!GROK!THIS! +$startsh +!GROK!THIS! +$spitshell >>jmkmf <<'!NO!SUBS!' +# @(#) Generates a Makefile from a Jmakefile + +# $Id: jmkmf.SH,v 3.0.1.1 1993/08/19 06:42:14 ram Exp $ +# +# Copyright (c) 1991-1993, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 3.0. +# +# $Log: jmkmf.SH,v $ +# Revision 3.0.1.1 1993/08/19 06:42:14 ram +# patch1: leading config.sh searching was not aborting properly +# +# Revision 3.0 1993/08/18 12:04:19 ram +# Baseline for dist 3.0 netwide release. +# + +usage="usage: $0 [top_of_sources_pathname [current_directory]]" + +topdir=. +curdir=. + +case $# in + 0) ;; + 1) topdir=$1 ;; + 2) topdir=$1 curdir=$2 ;; + *) echo "$usage" 1>&2; exit 1 ;; +esac + +case "$topdir" in + -*) echo "$usage" 1>&2; exit 1 ;; +esac + +if test -f Makefile.SH; then + echo mv Makefile.SH Makefile.SH~ + mv Makefile.SH Makefile.SH~ +fi + +args="-DTOPDIR=$topdir -DCURDIR=$curdir" + +echo jmake $args +jmake $args +echo sh Makefile.SH +sh Makefile.SH +!NO!SUBS! +chmod 755 jmkmf +$eunicefix jmkmf diff --git a/jmake/jmkmf.man b/jmake/jmkmf.man new file mode 100644 index 0000000..d39b1f7 --- /dev/null +++ b/jmake/jmkmf.man @@ -0,0 +1,70 @@ +''' $Id: jmkmf.man,v 3.0.1.1 1995/05/12 11:58:03 ram Exp $ +''' +''' Copyright (c) 1991-1993, Raphael Manfredi +''' +''' You may redistribute only under the terms of the Artistic Licence, +''' as specified in the README file that comes with the distribution. +''' You may reuse parts of this distribution only within the terms of +''' that same Artistic Licence; a copy of which may be found at the root +''' of the source tree for dist 3.0. +''' +''' $Log: jmkmf.man,v $ +''' Revision 3.0.1.1 1995/05/12 11:58:03 ram +''' patch54: updated my e-mail address +''' +''' Revision 3.0 1993/08/18 12:04:20 ram +''' Baseline for dist 3.0 netwide release. +''' +.TH JMKMF 1 ram +.SH NAME +jmkmf \- runs jmake with the correct options +.SH SYNOPSIS +.B jmkmf +[ +.I top-level dir +[ +.I current dir +] +] +.SH DESCRIPTION +.I Jmkmf +is a wrapper which calls +.I jmake +with the correct options, defining the symbols +.SM TOPDIR +(location of the top-level directory) and +.SM CURDIR +(current directory). The generated +.I Makefile.SH +is then ran through +.I /bin/sh +to produce a +.I Makefile. +.PP +.I Jmkmf +is useful when you generate a makefile for the first time. +Once you have a +.I Makefile.SH +generated by +.I jmake, +you can use +.I make Makefile.SH +to build the Makefile.SH again and +.I make Makefile +to run the Makefile.SH through +.I /bin/sh. +To use the recursive commands, you have to append an 's' at the +end of the name as in +.I make Makefiles.SH +and +.I make Makefiles. +.SH AUTHOR +Raphael Manfredi <ram@hptnos02.grenoble.hp.com> +.SH FILES +.PD 0 +.TP 20 +Jmakefile +High level description of makefile +.PD +.SH "SEE ALSO" +jmake(1). |