/*
 *	aegis - project change supervisor
 *	Copyright (C) 1991-2004 Peter Miller;
 *	All rights reserved.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 *
 * MANIFEST: instructions to cook(1), how to build project
 */

/*
 * Turn on updating to ensure mod-time
 * consistency on fast machines.
 */
set time-adjust;

/*
 * make sure targets are removed before the recipe body is run,
 * and make sure that directories are created then too.
 */
set unlink mkdir;

/*
 * You may want to change some of these options.
 * ([debug] must be defined, even if empty, use comments.)
 *
 * Change ``main.h'' to add the DEBUG define.
 * All files reference this file, so this will cause recompilation
 * of all files, both in the change and in the baseline.
 */
debug = -g /* -pg */ ;

/*
 * Make sure the [project], [change], [version] and [arch] variables are set.
 */
#ifndef project
echo "The [project] variable was not set from the command line." set silent;
echo "If you want to do a build which is not a development build" set silent;
echo "or an integration build, use the make command, not cook." set silent;
fail;
#endif
#ifndef change
echo "The [change] variable was not set from the command line." set silent;
echo "If you want to do a build which is not a development build" set silent;
echo "or an integration build, use the make command, not cook." set silent;
fail;
#endif
#ifndef version
echo "The [version] variable was not set from the command line." set silent;
echo "If you want to do a build which is not a development build" set silent;
echo "or an integration build, use the make command, not cook." set silent;
fail;
#endif
#ifndef arch
echo "The [arch] variable was not set from the command line." set silent;
echo "If you want to do a build which is not a development build" set silent;
echo "or an integration build, use the make command, not cook." set silent;
fail;
#endif
#ifndef search_path
echo "The [search_path] variable was not set from the command line." set silent;
echo "If you want to do a build which is not a development build" set silent;
echo "or an integration build, use the make command, not cook." set silent;
fail;
#endif

/*
 * The first item in search list should be the absolute path of the
 * current directory.  Assume that it is.
 */
search_list = .;
search_tmp = [tail [split ':' [search_path]]];

/*
 * Try to shorten the search path in command lines, too.
 *
 * This takes a little getting used to....
 * 1. For development builds, the search path is dev dir, then branch bl,
 *    then ... project bl.  Thus, bl in a dev dir winds up pointing to
 *    the branch reporitory.
 * 2. For integration builds, aegis deliberately omits the branch
 *    baseline from the path, but include's the branch's parents and
 *    ancestors.  Thus, bl in an int dir winds up pointing to the
 *    branch's parent's reporitory.
 * The idea is that integration builds in a branch are like a
 * development build of the branch's dev dir.
 */
search_name = bl;
loop
{
	search_dir = [head [search_tmp]];
	if [not [search_dir]] then
		loopstop;
	search_tmp = [tail [search_tmp]];

	if [not [exists [search_name]]] then
		ln -s [search_dir] [search_name]
			set clearstat;
	search_list = [search_list] [search_name];
	search_name = [search_name]bl;
}

/*
 * If this is a development build, the version will be x.y.Czzz,
 * so look to see if there is a C in the version string.
 */
if [match_mask %1C%2 [version]] then
{
	/*
	 * The develop_begin_command in the config file
	 * always creates the "bl" symbolic link.
	 */
	baseline = bl;

	/*
	 * Supplement file modification times with fingerprints.
	 * Only do this for development builds.
	 */
	set fingerprint;
}

if [not [defined baseline]] then
{
	/*
	 * Turn on aggressive updating to ensure the smallest possible
	 * range of mod times at aeipass.  This also ensures mod time
	 * consistency on fast machines.
	 */
	set time-adjust-back;
}

/*
 * determine the short version:
 * no change or delta number
 */
version_short = [fromto %1.C%2 %1 [subst D C [version]]];

version_shorter = [split "." [version_short]] _ _;
version_shorter = [unsplit "." [word 1 [version_shorter]]
	[word 2 [version_shorter]]];
project_short = [fromto %.[version_short] % [project]];
project_minus = [project_short]-[version_short];

/*
 * use GNU awk
 */
awk = gawk;

/*
 * This file is generated by autoconf.
 * It is architecture specific.
 * If it is not found (not cooked yet) the following
 * symbols will be undefined.
 *
 *	Must be included *after* the search_list is defined.
 */
#include-cooked-nowarn [arch]/etc/Howto.conf
if [not [defined prefix]] then
	prefix = /usr/local;
if [not [defined exec_prefix]] then
	exec_prefix = [prefix];
if [not [defined yacc]] then
	yacc = yacc;
if [not [defined libs]] then
	libs = ;

if [defined [arch]_cc] then
    cc = [[arch]_cc];

if [not [defined cc]] then
	cc = ['if' [find_command gcc] 'then' gcc 'else' cc];

if [not [defined primary_arch]] then
    primary_arch = linux-i486;

/*
 * The default recipe
 */
all =
	configured_files
	;

/*
 * Integration builds also make the shar files for distribution,
 * but only on the primary architecture.
 */
if [defined change] then
if [not [defined baseline]] then
if [in [arch] [primary_arch]] then
	all += integration-build-targets ;

all: [all]
    set default
{
    if [not [defined baseline]] then
    {
	if [in [resolve etc/set-uid-root] etc/set-uid-root] then
	    chmod a+rx etc/set-uid-root;
       	set silent;
	echo\;ls -l [arch]/bin/aegis [arch]/bin/aeimport;
       	echo "Integrator: please do the following:";
	echo "\"  sudo" [pathname [resolve etc/set-uid-root]] [arch]
	    "aegis aeimport\"";
	echo "\"if they aren't already.  See etc/set-uid-root for\"";
	echo "\"instructions for how to set-up your /etc/sudoers file.\"";
    }
}

/*
 * The source files.
 * This is given to us by aegis.
 */
vs_file = common/patchlevel.h;
change_files_removed = ;
change_files = ;
change_files_build = ;
#include-cooked-nowarn etc/cook/change_files.[version]
etc/cook/change_files.[version]: : etc/chan_files.awk
	set shallow nodefault
{
	aegis -l cf -p [project] -c [change] -unf
		| [awk] -f [resolve etc/chan_files.awk]
		> [target]
			set meter;
}
project_files = ;
project_files_build = ;
#include-cooked-nowarn etc/cook/project_files.[version]
etc/cook/project_files.[version]: : etc/proj_files.awk
	set shallow nodefault
{
	aegis -l pf -p [project] -c [change] -unf
		| [awk] -f [resolve etc/proj_files.awk]
		> [target]
			set meter;
}

/*
 * Speed up graph building by stating the leaves explictly.
 * This also gives more useful error messages.
 */
if [not [change_files_removed]] then
if [count [project_files]] then
if [count [change_files]] then
{
	graph_leaf_file = [project_files] [change_files];
	graph_leaf_pattern = /%0%;
}

source_files =
	[sort [stringset [project_files] [change_files]]]
	;


version_obj = [arch]/common/version_stmp.o;
common_obj = [arch]/common/common.a [version_obj];
common_lib =
	[stringset
		[fromto
			common/%0%.y
			[arch]/common/%0%.gen.o
			[match_mask common/%0%.y [source_files]]
		]
		[fromto
			common/%0%.c
			[arch]/common/%0%.o
			[match_mask common/%0%.c [source_files]]
		]
		[fromto
			common/%0%.c.in
			[arch]/common/%0%.o
			[match_mask common/%0%.c.in [source_files]]
		]
	-
		[version_obj]
	];

libaegis_obj = [arch]/libaegis/libaegis.a [version_obj];
libaegis_lib =
	[fromto
		libaegis/%0%.y
		[arch]/libaegis/%0%.gen.o
		[match_mask libaegis/%0%.y [source_files]]
	]
	[fromto
		libaegis/%0%.c
		[arch]/libaegis/%0%.o
		[match_mask libaegis/%0%.c [source_files]]
	]
	[fromto
		libaegis/%0%.def
		[arch]/libaegis/%0%.o
		[match_mask libaegis/%0%.def [source_files]]
	]
	[common_lib]
	;

/*
 * There is a special list of files you must use, in preference to the
 * standard C files.  This ensures appropriate operating system insulation
 * is always in place.
 */
c_incl_excludes =
	[fromto common/ac/%0%.h -ex\=%0%.h
		[match_mask common/ac/%0%.h [source_files]]
	];

/*
 * determine the list of commands
 */

commands =
	[stringset
		[fromto %1/%0%2 %1 [match_mask %/main.c [source_files]]]
	-
		fmtgen
		find_sizes
		aefp
		cklinlen
	];

/*
 * Add the commands to the list of top-level targets.
 */
all_commands:
	[arch]/bin/aefp
	[addprefix [arch]/bin/ [commands]]
	[arch]/bin/xaegis
	;
all = [all]
	all_commands
	;

/*
 * determine the object files for each command
 */
cmd_list = [commands];
loop
{
	cmd = [head [cmd_list]];
	if [not [cmd]] then
		loopstop;
	cmd_list = [tail [cmd_list]];

	[cmd]_obj =
		[fromto [cmd]/%0%.y [arch]/[cmd]/%0%.gen.o
			[match_mask [cmd]/%0%.y [source_files]]
		]
		[fromto [cmd]/%0%.def [arch]/[cmd]/%0%.o
			[match_mask [cmd]/%0%.def [source_files]]
		]
		[fromto [cmd]/%0%.c [arch]/[cmd]/%0%.o
			[match_mask [cmd]/%0%.c [source_files]]
		]
		[libaegis_obj]
		;
	[cmd],I =
		[fromto [cmd]/%0%.y [cmd]/%0%.gen.c,I
			[match_mask [cmd]/%0%.y [source_files]]
		]
		[fromto [cmd]/%0%.def [arch]/[cmd]/%0%.c,I
			[match_mask [cmd]/%0%.def [source_files]]
		]
		[fromto [cmd]/%0%.c [cmd]/%0%.c,I
			[match_mask [cmd]/%0%.c [source_files]]
		]
		;
}

aefp_obj =
	[arch]/aefp/main.o
	[common_obj]
	;

aemeasure_obj =
	[fromto %0%.c [arch]/%0%.o
	    [match_mask aemeasure/%0%.c [source_files]]
	]
	[arch]/common/common.a
	;

fmtgen_obj =
	[fromto
		fmtgen/%0%.y
		[arch]/fmtgen/%0%.gen.o
		[match_mask fmtgen/%0%.y [source_files]]
	]
	[fromto
		fmtgen/%0%.c
		[arch]/fmtgen/%0%.o
		[match_mask fmtgen/%0%.c [source_files]]
	]
	[arch]/common/ac/string.o
	[arch]/common/arglex.o
	[arch]/common/error.o
	[arch]/common/exeext.o
	[arch]/common/fstrcmp.o
	[arch]/common/libdir.o
	[arch]/common/mem.o
	[arch]/common/mprintf.o
	[arch]/common/progname.o
	[arch]/common/str.o
	[arch]/common/str/format.o
	[arch]/common/str_list/append.o
	[arch]/common/str_list/constructor.o
	[arch]/common/str_list/append_uniqu.o
	[arch]/common/symtab.o
	[arch]/common/trace.o
	;

find_sizes_obj =
	[fromto
		find_sizes/%.c
		[arch]/find_sizes/%.o
		[match_mask find_sizes/%.c [source_files]]
	]
	[arch]/common/ac/string.o
	[arch]/common/arglex.o
	[arch]/common/error.o
	[arch]/common/exeext.o
	[arch]/common/libdir.o
	[arch]/common/mem.o
	[arch]/common/mprintf.o
	[arch]/common/progname.o
	[arch]/common/str.o
	[arch]/common/str/format.o
	[arch]/common/trace.o
	;

source_files_build =
	[change_files_build] [project_files_build];
source_files_non_build =
	[stringset [source_files] - [source_files_build]];

/*
 * how to compile C sources
 */
if [defined [arch]_cc_flags] then
    cc_flags = [[arch]_cc_flags];

if [not [defined cc_flags]] then
    cc_flags = -O2 [debug];

if [defined [arch]_cc_include_flags] then
    cc_include_flags = [[arch]_cc_include_flags];

if [not [defined cc_include_flags]] then
    cc_include_flags = ;


if [defined [arch]_ld_flags] then
    ld_flags = [[arch]_ld_flags];

if [not [defined ld_flags]] then
    ld_flags = [debug];

/*
 * this next section is for gcc
 *	comment it out if you don't have gcc
 *
 * The gcc include files MUST be first.
 */
if [in [cc] gcc] then
cc_flags = [cc_flags] -ansi -Wall -Wstrict-prototypes -Wmissing-prototypes
	-Wshadow -Wmissing-declarations -Wpointer-arith -Wwrite-strings;

/*
 * For development builds, on the primary architecture, all warnings are
 * to be treated as errors; this ensures the cleanest possible code.
 * Make sure we are dealing with gcc and _not_ v3.x at that
 */
if [defined baseline] then
  if [in [arch] [primary_arch]] then
    if [in [cc] gcc] then
	cc_flags = [cc_flags] -Werror;

/*
 * include files from common
 */
cc_include_flags =
	[cc_include_flags]
	[prepost "-I" "/"[arch]"/common" [search_list]]
	[prepost "-I" "/common" [search_list]]
	[prepost "-I" "/"[arch]"/libaegis" [search_list]]
	[prepost "-I" "/libaegis" [search_list]]
	;

/*
 * Build %1/%2.o from %1/%2.c
 */

[arch]/%1/%0%2.o: %1/%0%2.c
{
	extra = [cc_flags];
	if [defined %2_flags] then
		extra = [extra] [%2_flags];

	if [match %%.gen %2] then
	{
		/*
		 * Generated files may have warnings, because we have no
		 * control over the quality of generated code (usually
		 * warnings about missing prototypes or unreferenced
		 * labels).
		 */
		extra = [stringset [extra] - -Werror];
	}

	[cc] [extra]
		[stringset
			[prepost "-I" "/%1" [search_list]]
			[cc_include_flags]
		]
		-c [resolve %1/%0%2.c]
		['if' [in gcc [cc]] 'then' -o [target]];
	if [not [in gcc [cc]]] then
		mv %2.o [target];
}

[arch]/%1/%0%2.o: [arch]/%1/%0%2.c
{
	extra = [cc_flags];
	if [defined %2_flags] then
		extra = [extra] [%2_flags];

	if [match %%.gen %2] then
	{
		/*
		 * Generated files may have warnings, because we have no
		 * control over the quality of generated code (usually
		 * warnings about missing prototypes or unreferenced
		 * labels).
		 */
		extra = [stringset [extra] - -Werror];
	}

	[cc] [extra]
		[stringset
			[prepost "-I" "/%1" [search_list]]
			[cc_include_flags]
		]
		-c [resolve [arch]/%1/%0%2.c]
		['if' [in gcc [cc]] 'then' -o [target]];
	if [not [in gcc [cc]]] then
		mv %2.o [target];
}

%1/%0%2.c.d: %1/%0%2.c
	set no-cascade
{
	c_incl -nc -ns -eia -nrec
	    [stringset
		[prepost "-I" "/%1" [search_list]]
		[cc_include_flags]
	    ]
	    -prefix "'cascade %1/%0%2.c ='"
	    -suffix "';'"
	    [resolve %1/%0%2.c]
	    [addprefix -rlp\= [search_list]]
	    -slp [arch] "'[arch]'"
	    -nsri
	    ['if' [not [filter common/ac/%%0%% %1/%0%2.c]]
	    	'then' [c_incl_excludes]]
	    -o [target];
}

%1/%0%2.h.d: %1/%0%2.h
	set no-cascade
{
	c_incl -nc -ns -eia -nrec
	    [stringset
		[prepost "-I" "/%1" [search_list]]
		[cc_include_flags]
	    ]
	    -prefix "'cascade %1/%0%2.h ='"
	    -suffix "';'"
	    [resolve %1/%0%2.h]
	    [addprefix -rlp\= [search_list]]
	    -slp [arch] "'[arch]'"
	    -nsri
	    ['if' [not [filter common/ac/%%0%% %1/%0%2.h]]
	    	'then' [c_incl_excludes]]
	    -o [target];
}

%1/%0%2.c.d: [arch]/%1/%0%2.c
	set no-cascade
{
	c_incl -nc -ns -eia -nrec
	    [stringset
		[prepost "-I" "/%1" [search_list]]
		[cc_include_flags]
	    ]
	    -prefix "'cascade [arch]/%1/%0%2.c ='"
	    -suffix "';'"
	    [resolve [arch]/%1/%0%2.c]
	    [addprefix -rlp\= [search_list]]
	    -slp [arch] "'[arch]'"
	    -nsri
	    ['if' [not [filter common/ac/%%0%% %1/%0%2.h]]
	    	'then' [c_incl_excludes]]
	    -o [target];
}

%0%.c,M:: %0%.c,Md;

%1/%0%2.c,Md: %1/%0%2.c
{
	c_incl
		-nc /* no cache */
		-ns /* no system */
		-eia /* empty if absent */
		[stringset
			[prepost "-I" "/%1" [search_list]]
			[cc_include_flags]
		]
		[resolve %1/%0%2.c]
		-nsri /* no source relative includes */
		[prepost "-rlp=" "" [search_list]] /* remove leading path */
		-rlp [arch] /* remove leading architecture */
		-o [target];
}

c-dep-files =
	[fromto %1/%0%2.c %1/%0%2.c.d [match_mask %1/%0%2.c [source_files]]]
	[fromto %1/%0%2.h %1/%0%2.h.d [match_mask %1/%0%2.h [source_files]]]
	[fromto %1/%0%2.y %1/%0%2.gen.c.d [match_mask %1/%0%2.y [source_files]]]
	[fromto %1/%0%2.y %1/%0%2.gen.h.d [match_mask %1/%0%2.y [source_files]]]
	[fromto %1/%0%2.def %1/%0%2.c.d [match_mask %1/%0%2.def [source_files]]]
	[fromto %1/%0%2.def %1/%0%2.h.d [match_mask %1/%0%2.def [source_files]]]
	;

#if [count [c-dep-files]]
#include-cooked-nowarn [c-dep-files]
#endif

/*
 * Catch 22: you need the include files to be there, to work out that
 * you need to construct them.  This is the minimum set of dependencies
 * to bootstrap the dependency process.  Sigh.
 */

cascade aeannotate/annotate.c = libaegis/fstate.h;
cascade aecomplete/command/ae_c.c = libaegis/cstate.h;
cascade aecomplete/command/aechown.c = libaegis/cstate.h;
cascade aecomplete/command/aecpu.c = libaegis/cstate.h;
cascade aecomplete/command/aedb.c = libaegis/cstate.h;
cascade aecomplete/command/aedbu.c = libaegis/cstate.h;
cascade aecomplete/command/aede.c = libaegis/cstate.h;
cascade aecomplete/command/aedeu.c = libaegis/cstate.h;
cascade aecomplete/command/aeib.c = libaegis/cstate.h;
cascade aecomplete/command/aeibu.c = libaegis/cstate.h;
cascade aecomplete/command/aeifail.c = libaegis/cstate.h;
cascade aecomplete/command/aeipass.c = libaegis/cstate.h;
cascade aecomplete/command/aemtu.c = libaegis/cstate.h;
cascade aecomplete/command/aencu.c = libaegis/cstate.h;
cascade aecomplete/command/aenfu.c = libaegis/cstate.h;
cascade aecomplete/command/aentu.c = libaegis/cstate.h;
cascade aecomplete/command/aerb.c = libaegis/cstate.h;
cascade aecomplete/command/aerbu.c = libaegis/cstate.h;
cascade aecomplete/command/aerfail.c = libaegis/cstate.h;
cascade aecomplete/command/aerm.c = libaegis/cstate.h;
cascade aecomplete/command/aermu.c = libaegis/cstate.h;
cascade aecomplete/command/aerpass.c = libaegis/cstate.h;
cascade aecomplete/command/aerpu.c = libaegis/cstate.h;
cascade aecomplete/command/aet.c = libaegis/cstate.h;
cascade aecomplete/complete/change/number.c = libaegis/cstate.h;
cascade aedist/list.c = libaegis/cstate.h;
cascade aedist/receive.c = libaegis/cattr.h;
cascade aefind/lex.c = aefind/cmdline.gen.h;
cascade aeget/get/change/aetar.c = libaegis/cstate.h;
cascade aeget/get/change/download.c = libaegis/cstate.h;
cascade aeget/get/change/list.c = libaegis/cstate.h;
cascade aeget/get/change/menu.c = libaegis/cstate.h;
cascade aeget/get/file/activity.c = libaegis/cstate.h;
cascade aeget/get/file/history.c = libaegis/cstate.h;
cascade aeget/get/file/menu.c = libaegis/fstate.h;
cascade aeget/get/project/menu.c = libaegis/cstate.h;
cascade aeget/get/project/statistics.c = libaegis/cstate.h;
cascade aeget/get/project/statistics.c = libaegis/fstate.h;
cascade aegis/aeca.c = libaegis/cattr.h;
cascade aegis/aeca.h = libaegis/cattr.h;
cascade aegis/aechown.c = libaegis/cstate.h;
cascade aegis/aechown.c = libaegis/pstate.h;
cascade aegis/aedb.c = libaegis/common.h;
cascade aegis/aedbu.c = libaegis/common.h;
cascade aegis/aede.c = libaegis/common.h;
cascade aegis/aedeu.c = libaegis/common.h;
cascade aegis/aedn.c = libaegis/pconf.h;
cascade aegis/aeib.c = libaegis/common.h;
cascade aegis/aeibu.c = libaegis/common.h;
cascade aegis/aeip.c = libaegis/metrics.h;
cascade aegis/ael.c = libaegis/fstate.h;
cascade aegis/aemvu.c = libaegis/pconf.h;
cascade aegis/aenc.c = libaegis/cattr.h;
cascade aegis/aenc.c = libaegis/common.h;
cascade aegis/aencu.c = libaegis/cattr.h;
cascade aegis/aencu.c = libaegis/common.h;
cascade aegis/aenf.c = libaegis/pconf.h;
cascade aegis/aepa.c = libaegis/pattr.h;
cascade aegis/aerb.c = libaegis/pattr.h;
cascade aegis/aerf.c = libaegis/pattr.h;
cascade aegis/aerp.c = libaegis/pattr.h;
cascade aeimport/config_file.c = libaegis/cstate.h;
cascade aeimport/config_file.c = libaegis/pconf.h;
cascade aeimport/format/rcs/lex.c = aeimport/format/rcs/gram.gen.h;
cascade aeimport/format/sccs/lex.c = aeimport/format/sccs/gram.gen.h;
cascade aeimport/reconstruct.c = libaegis/fstate.h;
cascade aeimport/synthesize.c = libaegis/cstate.h;
cascade aeimport/synthesize.c = libaegis/fstate.h;
cascade aels/list.c = libaegis/fstate.h;
cascade aels/stack.c = libaegis/cstate.h;
cascade aepatch/receive.c = libaegis/cattr.h;
cascade aepatch/receive.c = libaegis/pconf.h;
cascade aexml/xml/change/cstate.c = libaegis/cstate.h;
cascade aexml/xml/change/fstate.c = libaegis/fstate.h;
cascade aexml/xml/change/pconf.c = libaegis/cstate.h;
cascade aexml/xml/project/cstate.c = libaegis/cstate.h;
cascade aexml/xml/project/fstate.c = libaegis/fstate.h;
cascade common/ac/ctype.h = [arch]/common/config.h;
cascade common/ac/errno.h = [arch]/common/config.h;
cascade common/ac/fcntl.h = [arch]/common/config.h;
cascade common/ac/libintl.h = [arch]/common/config.h;
cascade common/ac/mntent.h = [arch]/common/config.h;
cascade common/ac/stdarg.h = [arch]/common/config.h;
cascade common/ac/stddef.h = [arch]/common/config.h;
cascade common/ac/stdio.h = [arch]/common/config.h;
cascade common/ac/stdlib.h = [arch]/common/config.h;
cascade common/ac/string.h = [arch]/common/config.h;
cascade common/ac/time.h = [arch]/common/config.h;
cascade common/ac/unistd.h = [arch]/common/config.h;
cascade common/ac/wchar.h = [arch]/common/config.h;
cascade common/fp/md5.c = [arch]/common/find_sizes.h;
cascade common/fp/snefru.c = [arch]/common/find_sizes.h;
cascade common/version_stmp.c = common/patchlevel.h;
cascade etc/aegis.html = etc/version.so;
cascade fmtgen/lex.c = fmtgen/parse.gen.h;
cascade libaegis/ael/change/incomplete.c = libaegis/cstate.h;
cascade libaegis/ael/change/outstanding.c = libaegis/cstate.h;
cascade libaegis/ael/formeditnum.c = libaegis/fstate.h;
cascade libaegis/ael/formeditnum.h = libaegis/fstate.h;
cascade libaegis/ael/project/history.c = libaegis/cstate.h;
cascade libaegis/aer/expr/name.c = libaegis/aer/value/gstate.h;
cascade libaegis/aer/expr/name.c = libaegis/cattr.h;
cascade libaegis/aer/expr/name.c = libaegis/common.h;
cascade libaegis/aer/expr/name.c = libaegis/cstate.h;
cascade libaegis/aer/expr/name.c = libaegis/fstate.h;
cascade libaegis/aer/expr/name.c = libaegis/pattr.h;
cascade libaegis/aer/expr/name.c = libaegis/pconf.h;
cascade libaegis/aer/expr/name.c = libaegis/pstate.h;
cascade libaegis/aer/expr/name.c = libaegis/uconf.h;
cascade libaegis/aer/expr/name.c = libaegis/ustate.h;
cascade libaegis/aer/lex.c = libaegis/aer/report.gen.h;
cascade libaegis/aer/list.c = libaegis/rptidx.h;
cascade libaegis/aer/parse.c = libaegis/rptidx.h;
cascade libaegis/aer/value/cstate.c = libaegis/aer/value/cstate.h;
cascade libaegis/aer/value/cstate.c = libaegis/aer/value/fstate.h;
cascade libaegis/aer/value/fstate.c = libaegis/aer/value/fstate.h;
cascade libaegis/aer/value/gstate.c = libaegis/aer/value/gstate.h;
cascade libaegis/aer/value/gstate.c = libaegis/aer/value/pstate.h;
cascade libaegis/aer/value/pstate.c = libaegis/aer/value/cstate.h;
cascade libaegis/aer/value/pstate.c = libaegis/aer/value/fstate.h;
cascade libaegis/aer/value/pstate.c = libaegis/aer/value/pstate.h;
cascade libaegis/change/architecture/check.c = libaegis/cstate.h;
cascade libaegis/change/architecture/check.c = libaegis/pconf.h;
cascade libaegis/change/architecture/find_variant.h = libaegis/cstate.h;
cascade libaegis/change/architecture/run_disc_cmd.c = libaegis/pconf.h;
cascade libaegis/change/attributes/copy.c = libaegis/cattr.h;
cascade libaegis/change/attributes/copy.c = libaegis/cstate.h;
cascade libaegis/change/attributes/default.c = libaegis/cattr.h;
cascade libaegis/change/attributes/default.c = libaegis/pconf.h;
cascade libaegis/change/attributes/edit.c = libaegis/cattr.h;
cascade libaegis/change/attributes/verify.c = libaegis/cattr.h;
cascade libaegis/change/build/run_int_com.c = libaegis/pconf.h;
cascade libaegis/change/cstate/improve.c = libaegis/cstate.h;
cascade libaegis/change/cstate/improve.h = libaegis/cstate.h;
cascade libaegis/change/develop_direct/read_write.c = libaegis/cstate.h;
cascade libaegis/change/file/is_config.c = libaegis/pconf.h;
cascade libaegis/change/file/metrics/get.c = libaegis/metrics.h;
cascade libaegis/change.h = libaegis/cstate.h;
cascade libaegis/change.h = libaegis/fstate.h;
cascade libaegis/change.h = libaegis/pconf.h;
cascade libaegis/change/is_completed.c = libaegis/cstate.h;
cascade libaegis/change/pconf/get.c = libaegis/fstate.h;
cascade libaegis/change/test/batch.c = libaegis/fstate.h;
cascade libaegis/change/test/batch.c = libaegis/pconf.h;
cascade libaegis/change/test/batch.c = libaegis/tstrslt.h;
cascade libaegis/change/test/batch_fake.c = libaegis/fstate.h;
cascade libaegis/change/test/batch_fake.c = libaegis/tstrslt.h;
cascade libaegis/change/test/run_list.c = libaegis/pconf.h;
cascade libaegis/common.c = libaegis/common.h;
cascade libaegis/gonzo.c = libaegis/gstate.h;
cascade libaegis/gonzo.c = libaegis/ustate.h;
cascade libaegis/gonzo.h = libaegis/gstate.h;
cascade libaegis/lex.c = libaegis/gram.gen.h;
cascade libaegis/metrics.c = libaegis/metrics.h;
cascade libaegis/patch/read.c = libaegis/common.h;
cascade libaegis/project.c = libaegis/pstate.h;
cascade libaegis/project/delta2change.c = libaegis/cstate.h;
cascade libaegis/project/file/directory/conflict.c = libaegis/fstate.h;
cascade libaegis/project/file/find_fuzzy.c = libaegis/fstate.h;
cascade libaegis/project/file.h = libaegis/fstate.h;
cascade libaegis/project/file/nth.c = libaegis/fstate.h;
cascade libaegis/project/file/roll_forward.c = libaegis/cstate.h;
cascade libaegis/project/file/roll_forward.h = libaegis/fstate.h;
cascade libaegis/project/file/trojan.c = libaegis/pconf.h;
cascade libaegis/project/file/version_path.c = libaegis/fstate.h;
cascade libaegis/project.h = libaegis/pattr.h;
cascade libaegis/project.h = libaegis/pstate.h;
cascade libaegis/project/new_branch.c = libaegis/cstate.h;
cascade libaegis/project/new_branch.c = libaegis/pconf.h;
cascade libaegis/project/pattr/edit.c = libaegis/pattr.h;
cascade libaegis/project/pattr/get.c = libaegis/pattr.h;
cascade libaegis/project/pattr/set.c = libaegis/pattr.h;
cascade libaegis/project/pconf/get.c = libaegis/pconf.h;
cascade libaegis/project/sch_path_get.c = libaegis/cstate.h;
cascade libaegis/project/sch_path_get.c = libaegis/fstate.h;
cascade libaegis/sub/base_relativ.c = libaegis/cstate.h;
cascade libaegis/sub/change/delta.c = libaegis/cstate.h;
cascade libaegis/sub/change/number.c = libaegis/cstate.h;
cascade libaegis/sub/change/state.c = libaegis/sub/change/state.h;
cascade libaegis/sub.c = libaegis/sub/change/state.h;
cascade libaegis/sub/delta.c = libaegis/cstate.h;
cascade libaegis/sub/expr_lex.c = libaegis/sub/expr_gram.gen.h;
cascade libaegis/sub/plural_lex.c = libaegis/sub/plural_gram.gen.h;
cascade libaegis/sub/project/specific.c = libaegis/pconf.h;
cascade libaegis/sub/source.c = libaegis/cstate.h;
cascade libaegis/tstrslt.c = libaegis/tstrslt.h;
cascade libaegis/user.h = libaegis/uconf.h;
cascade libaegis/user.h = libaegis/ustate.h;
cascade lib/en/aoss4/main.mm = etc/version.so(exists);
cascade lib/en/auug93/main.mm = etc/version.so(exists);
cascade lib/en/building/main.man = etc/version.so(exists);
cascade lib/en/cvs-comparison/main.ms = [arch]/etc/libdir.so;
cascade lib/en/cvs-comparison/main.ms = etc/version.so(exists);
cascade lib/en/faq/main.roff = etc/version.so(exists) lib/en/faq/toc.so;
cascade lib/en/howto/introductio.so = [arch]/etc/libdir.so;
cascade lib/en/howto/introductio.so = etc/version.so(exists);
cascade lib/en/lsm/main.roff = etc/version.so;
cascade lib/en/man1/aegis.cgi.1 = [arch]/etc/libdir.so;
cascade lib/en/man1/aeintegratq.1 = [arch]/etc/libdir.so etc/version.so(exists);
cascade lib/en/man1/aenpr.1 = [arch]/etc/libdir.so;
cascade lib/en/man1/aenrls.1 = [arch]/etc/libdir.so;
cascade lib/en/man1/aer.1 = [arch]/etc/libdir.so;
cascade lib/en/man1/tkaegis.1 = etc/version.so(exists);
cascade lib/en/man1/z_cr.so = etc/version.so(exists);
cascade lib/en/man5/aegstate.5 = [arch]/etc/libdir.so;
cascade lib/en/man5/aer.5 = [arch]/etc/libdir.so;
cascade lib/en/man5/aerptidx.5 = [arch]/etc/libdir.so;
cascade lib/en/man5/aeustate.5 = [arch]/etc/libdir.so;
/* cascade lib/en/readme/main.man = etc/proj_metric.so; */
cascade lib/en/readme/main.man = etc/version.so(exists);
cascade lib/en/readme/main.man = lib/en/readme/new.so;
cascade lib/en/refman/main.man = lib/en/refman/index.so;
cascade lib/en/refman/main.man = lib/en/refman/parts.so;
cascade lib/en/user-guide/c1.0.so = [arch]/etc/libdir.so;
cascade lib/en/user-guide/c1.0.so = etc/version.so(exists);

[fmtgen_obj]: [arch]/common/config.h;

/*
 * How to use yacc sources.
 */

yacc_flags = -v;

%1/%0%2.gen.c %1/%0%2.gen.h: %1/%0%2.y
	single-thread y.tab.c y.tab.h
{
	rm -f %1/%0%2.list y.output
		set silent;
	[yacc] -d [yacc_flags] [resolve %1/%0%2.y];
	yy = [collect echo %0%2 | sed -e "'s|[^a-zA-Z0-9]|_|g'"];
	sed	-e "'s/[yY][yY]/"[yy]"_/g'"
		-e "'/<stdio.h>/d'"
		-e "'/<stdlib.h>/d'"
		-e "'/<stddef.h>/d'"
		< y.tab.c > %1/%0%2.gen.c;
	rm y.tab.c;
	sed -e "'s/[yY][yY]/"[yy]"_/g'" -e "'s/Y_TAB_H/"[yy]"_TAB_H/g'"
		< y.tab.h > %1/%0%2.gen.h;
	rm y.tab.h;
	if [exists y.output] then
		mv y.output %1/%0%2.list
			set clearstat;
}

[arch]/bin/%: script/%.tcl
{
	cp [resolve [need]] [target];
	chmod 755 [target];
}

/*
 * How to automatically configure things to cope with the environment
 * we find ourselves in.
 */
#include-cooked etc/autoconf.cook


ranlib = [find_command ranlib];

[arch]/%/%.a: [%_lib]
	set meter
{
	ar qc [target] [resolve [%_lib]];
	if [ranlib] then
		[ranlib] [target];
}


/*
 * build the programs from their objects
 */

[arch]/bin/%: [%_obj]
{
	[cc] [debug] -o [target] [resolve [%_obj]] [libs]
		set meter;

	chmod 755 [target];

	/*
	 * aegis itself must be set-uid-root
	 */
	if [in [target] [arch]/bin/aegis [arch]/bin/aeimport] then
	{
		if [in [resolve etc/set-uid-root] etc/set-uid-root] then
		    chmod a+rx etc/set-uid-root;
		sudo [pathname [resolve etc/set-uid-root]]
		    [arch] [entryname [target]]
			set errok;
	}
}


/*
 * building things which require fmtgen to build
 *
 * Build %.c and %.h from %.def
 *
 * A host binding here can help a great deal; oterwise you need to
 * construct exactly the same files for each architecture.
 */

%1/%0%2.c %1/%0%2.h: %1/%0%2.def: [arch]/bin/fmtgen
	/* host-binding [[generate-arch]-hosts] */
{
	/*
	 * We don't resolve the path of the .def file, because fmtgen can
	 * do it itself, and because this allows the unresolved source
	 * file name to be inserted into the comment at the top of the
	 * output files.
	 *
	 * We insert the unresolved file name because (a) it's less
	 * confusing, and (b) it doesn't needlessly change the fingerprint
	 * just because of the search path.  This, in turn, means that
	 * cook doesn't rebuild a couple of hundred file which don't
	 * need to be recompiled.
	 */
	[resolve [arch]/bin/fmtgen]
		[prepost "-I" "/%1" [search_list]]
		[addprefix "-I" [search_list]]
		%1/%0%2.def %1/%0%2.c %1/%0%2.h;
}

%1/%0%2.def.d: %1/%0%2.def
	set no-cascade
{
	c_incl -nc -ns -eia -nrec
	    [stringset [cc_include_flags] [prepost "-I" "/%1" [search_list]]]
	    -prefix "'cascade %1/%0%2.def ='"
	    -suffix "';'"
	    [resolve %1/%0%2.def]
	    [addprefix -rlp\= [search_list]]
	    -slp [arch] "'[arch]'"
	    -nsri
	    -o [target];
}

%1/%0%2.def,M:: %1/%0%2.def,Md;

%1/%0%2.def,Md: %1/%0%2.def
{
	c_incl -nc -ns -eia
	    [stringset [cc_include_flags] [prepost "-I" "/%1" [search_list]]]
	    [resolve %1/%0%2.def]
	    [addprefix -rlp\= [search_list]]
	    -slp [arch] "'[arch]'"
	    -nsri
	    -o [target];
}

def-dep-files =
	[fromto %1/%0%2.def %1/%0%2.def.d
		[match_mask %1/%0%2.def [source_files]]
	];

#if [count [def-dep-files]]
#include-cooked-nowarn [def-dep-files]
#endif

/*
 * The version stamp is to be updated for every
 * integration and development build.
 */

[vs_file]:
	set shallow
{
	echo "'#define PATCHLEVEL \""[version]"\"'" > [target];
	aegis -list version -p [project] -c [change]
	| [awk] "-F'[[\\\\]]'"
"'/^copyright_years/{print \"#define COPYRIGHT_YEARS \\\"\" $2 \"\\\"\" }'"
	>> [target];
}


etc/version.so:
	set ['if' [or [not [defined baseline] ] [not [exists bl/etc/version.so
		] ] ] 'then' shallow]
{
	echo \".ds v) [version_short]\" > [target];
	/*
	 * This used to be the long version, but it makes the build
	 * change too often, and provides little information.
	 *
	echo \".ds V) [version]\" >> [target];
	 */
	echo "'.ds V) \\*(v)'" >> [target];
	echo [version]
		| [awk] -F. "'{print \".ds u) \"$1\".\"$2}'"
		>> [target];
	aegis -list version -p [project] -c [change]
		| [awk] -F'\'"\'' "'/previous/{print $2}'"
		| [awk] -F. "'{print \".ds w) \"$1\".\"$2}'"
		>> [target];
	aegis -list version -p [project] -c [change]
	| [awk] "-F'[[\\\\]]'" "'/^copyright_years/{print \".ds Y) \" $2}'"
	>> [target];
}


/*
 * These recipes build a Makefile for a user.  They do not build a
 * Makefile useful for a development build, because no arch
 * information is included in the Makefile.
 */

makefile-per-file =
	[addsuffix ",M"
		[stringset [source_files] - [source_files_build]]
		[fromto %0%.y %0%.gen.c [match_mask %0%.y [source_files]]]
		[fromto %0%.def %0%.c [match_mask %0%.def [source_files]]]
	];

Makefile.in: etc/Makefile.head etc/Makefile.sh etc/Makefile.awk [vs_file]
	[makefile-per-file]
{
	if [exists [target]] then
		rm [target]
			set clearstat;
	cat [resolve etc/Makefile.head [sort [makefile-per-file]]] > [target];
	sh [resolve etc/Makefile.sh] [source_files]
		| [awk] -f [resolve etc/Makefile.awk]
		>> [target];
}

%0%,M: etc/Makefi.file.sh etc/Makefile.awk
{
	depfile = [match_mask %%0%%,Md [need]];
	sh [resolve etc/Makefi.file.sh] %0% [resolve %0%]
			[resolve [depfile]]
		| [awk] -f [resolve etc/Makefile.awk]
		> [target];
}


etc/CHANGES: [arch]/bin/aereport lib/report/proj_detai.rpt [vs_file]
{
	[resolve [arch]/bin/aereport]
		-f [resolve lib/report/proj_detai.rpt]
		-o [target]
		-p [project_short]
		-pw\=80 -pl\=66
								      set meter;
}

[arch]/common/find_sizes.h: [arch]/bin/find_sizes
{
	[resolve [arch]/bin/find_sizes] > [target];
}

/*
 * How to cook documents.
 */
#include-cooked etc/documents.cook

/*
 * Basic file format validations.
 */
#include-cooked cklinlen/module.cook

/*
 * Internationalization recipes
 */
#include-cooked etc/i18n.cook

/*
 * Archive directory for integration builds
 */
#include-cooked etc/archive.cook

/*
 * Source file metrics
 */
#include-cooked etc/metrics.cook

/*
 * Lint checking.
 */
#include-cooked etc/lint.cook

/*
 * C formatting checking.
 */
#include-cooked etc/cfmt.cook

/*
 * Symbols cross references for editing.
 */
#include-cooked etc/tags.cook

/*
 * Generate documentation out of the header files.
 */
#include-cooked etc/doxygen.cook
