#!/bin/sh -e
# rkbuild: a RISK comp script to build the Makefiles.
#
# $Id: rkbuild,v 1.54 2007/03/22 16:51:30 tlaronde Exp $
#
#  Copyright 2004-2007 Thierry LARONDE <tlaronde@polynum.com>
#  All rights reserved. 
#  
#  This work is under the KerGIS Public Licence v1.0
# 
#  See the COPYRIGHT file at the root of the source directory or see
#  http://www.kergis.org/licence.txt for complete information.
# 
# !!!THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES!!! 
#                      USE IT AT YOUR OWN RISK 


#========== INITIALIZATIONS
# Name by which this script was invoked.
#
program=`basename $0`

prog_version='$Id: rkbuild,v 1.54 2007/03/22 16:51:30 tlaronde Exp $'

TMPDIR=${TMPDIR:-/tmp}
tmpdir=$TMPDIR/$$
! [ -d $tmpdir ] && mkdir $tmpdir

# handle HUP, INT, QUIT, PIPE, TERM
#
trap "debug F 'Interrupted'; clean_tmp; exit 1;"  HUP INT QUIT PIPE TERM

usage="
$program [-d] [-h] [-V]  prog_subdir

Build Makefile in OBJDIR/prog_sub_dir using OBJDIR/.rkcomp/config.
Must be invoked in OBJDIR.

Options:
 -d	turn Debug information on
 -h	display this Help and exit
 -V	display Version information and exit

 prog_subdir
	Directory relative to PROJECTDIR-OBJDIR where Makefile.ker resides.

"
version="$prog_version
Written by Thierry Laronde.

Copyright (c) 2004 Thierry Laronde <tlaronde@polynum.org>

All rights reserved. KerGIS Public Licence v1.0. NO WARRANTIES!."

#========== SUBFUNCTIONS
clean_tmp()
{
	rm -fr $tmpdir
}

# debug writes info (L for LOG), warning (W for WARNING), error
# (E for ERROR) or fatal (F for FATAL) for a programming unrecoverable
# error followed by the message on stderr
#
debug()
{
	case $1 in
	  A) echo "  ->" | tr -d '\n' 1>&2;;
	  E) echo "$program ERROR: " | tr -d '\n' 1>&2;;
	  F) echo "$program FATAL: " | tr -d '\n' 1>&2;;
	  L) echo "	" | tr -d '\n' 1>&2;;
	  W) echo "$program WARNING: " | tr -d '\n' 1>&2;;
	  *) echo "$1: " | tr -d '\n' 1>&2;;
	esac
    echo "$2" 1>&2
    return
}

error ()
{
	case $1 in
	  no_prog_subdir) debug E "$PROJECTDIR/$prog does not exist!";;
	  makefile.ker) debug E "Makefile.ker unreadable or inexistant!";;
	  bad_makefile.ker) debug E "Makefile.ker line $badline - contains explicit .o action";
        debug E "Modify it to eliminate the action";;
	  missing_essentials) debug E "A Makefile.ker shall define one (and only one)";
		debug E "of PROG or LIB, and perhaps DATA. None was found!";;
	  missing_rklib) debug E "I can not find my stuff!";
		debug L "TOOLDIR is: ${TOOLDIR:-UNSET}";;
	  missing_lib) debug E "The library $2 is unknown to me!";
		debug L "Did the PROJECT not plan to use it?";;
	  option) debug E "This option is unknown!";
		debug USAGE "$usage";;
	  COBJ_not_set) debug E "No COBJ specified! Skipping...";;
	  LIB_not_set) debug E "LIB is not set! Skipping...";;
	  PROG_not_set) debug E "PROG is not set! Skipping...";;
	  prog_and_lib) debug E "A Makefile.ker shall define  PROG xor LIB, not both!";;
	  missing_parameters) debug E "I need at least 2 parameters!";
		debug USAGE "$usage";;
	  not_configured) debug E "$1/.rkcomp/config does not exist!";
		debug E "Whether OBJDIR is wrong or is not configured. Run config first!";;
	  root_notallowed) debug E "You are not allowed to run this as root!";
		debug USAGE "$usage";;
	  unable_to_mkdir) debug E "Unable to make dir $2!";;
	esac

	# don't suppress temp file if debugging
	#
	[ "x$debug_mode" = "xYES" ] || clean_tmp

	exit 1
}

#========== INITIALIZATION

allow_root=NO

# the following to hold the case handled
#
is_prog=
is_lib=

[ $# -ge 1 ] || error missing_parameters

while [ $# -gt 0 ]; do
	case "$1" in
	  -d) set -x; debug_mode=YES;;
	  -h|--help) echo "$usage"; exit 0;;
	  -V|--version) echo "$version"; exit 0;;
	  -*) error option ;;
	  *) # setting the variables
	    [ -f .rkcomp/rkbuild.cf ] || error not_configured
		. .rkcomp/rkbuild.cf
		[ -f "$TOOLDIR/lib/librkcompsh" ] || error missing_rklib
		. $TOOLDIR/lib/librkcompsh
	    [ -d "$PROJECTDIR/$1" ] || error no_prog_subdir
		OBJPROGDIR=$OBJDIR/$1
		SRCDIR=$PROJECTDIR/$1;;
	esac
shift	
done

#------ SAFETY

readonly PROJECTDIR
readonly SRCDIR
readonly TOOLDIR
readonly OBJDIR
readonly OBJPROGDIR

# We refuse to go if we are invoked as root. Period.
#
[ `id -u` -ne 0 ]  || error root_notallowed

#========== CHECKING INPUT FOR CONFORMANCE

mkf=$SRCDIR/Makefile.ker
[ -r $mkf ] || error makefile.ker

! grep -q '^PROG[ 	]*=' $mkf || is_prog=YES
! grep -q '^LIB[ 	]*=' $mkf || is_lib=YES

[  "x$is_lib" != "xYES" -o "x$is_prog" != "xYES" ] || error prog_and_lib

#========= PROCESSING

# Creating the dir if not existant
#
[ -d "$OBJPROGDIR" ] || mkdir -p $OBJPROGDIR \
  || error unable_to_mkdir $OBJPROGDIR

# To avoid some problems with CWEBINPUTS length limit, create a symlink
# to the sources
#
[ -L "$OBJPROGDIR/src" ] || ln -s $SRCDIR $OBJPROGDIR/src


#========= LIBES AND OBJ
# The only names rkbuild really needs to know are the ones in LIBES
# (because CPPFLAGS, LDFLAGS, LDFLAGS_SHARED depend on that) and OBJ
# (to generate the rules corresponding to their generation).
# Since I don't want to write another `make' program just to
# list the values of the variables (susV3 specifies a way to have them
# with POSIX make but this is not, at the moment, widely available), I
# will simply add some targets and invoke make to show them...
#
cat $OBJDIR/.rkcomp/config \
$TOOLDIR/libdata/Makefile.rkbuild $mkf >$tmpdir/makefile

#========= GENERATED OBJECTS aka PRODUCTS

# .o are built from .c and .h, but these .[ch] may not exist: there 
# may be generated from LEX, YACC or CTANGLE and may not exist in the 
# PROJECTDIR.
# Because we want the PROJECTDIR to be read-only and because some
# program may try to create a file on its current working and move this
# object to the target name, the compiling process will be handled in 
# _OBJPROGDIR_ (this is the most important to understand). So only the 
# SOURCES will be prepended so that there can be found.

# What are the SOURCES? All the files not being a target or an infered
# object (*.o, *.dso---rkcomp suffix for dynamically shared objects---
# and the main targets). Indeed, we do only need to find the targets.
#
# Some products are well known ones: files produced by LEX or YACC and
# that may not appear in the Makefile.ker. They will be read after
# (see below).
#
awk 'BEGIN { FS = " *: *";}
/:/ { print $1; }
' $mkf \
 | sed 's/ \{1,\}/ /'\
 | tr '\t' ' ' | tr ' ' '\n' | sort | uniq \
 > $tmpdir/products

# there may be some macros in there, so we will call make on these
#
TO_BE_EXPANDED=$(sed -n '/^\$/p' $tmpdir/products | tr '\n' ' ')

# .PRECIOUS target is used to indicate that it's prerequisites are...
# precious and shall be kept. For us this is of particular interest when
# an not final object (library or prog) is suffixed like an intermediate
# object that can be removed when using save_space option.
#
sed -n 's/^\.PRECIOUS[ 	]*:[ 	]*//p' $mkf \
	| sed -e 's/[ 	]\{1,\}/ /' \
	| tr ' ' '\n' | sed '/^$/d' > $tmpdir/precious

# if there are macros, expand them.
#
PRECIOUS_TO_BE_EXPANDED=$(sed -n '/^\$/p' $tmpdir/precious | tr '\n' ' ')
(
echo "TO_BE_EXPANDED = $TO_BE_EXPANDED"
echo "PRECIOUS_TO_BE_EXPANDED = $PRECIOUS_TO_BE_EXPANDED"
echo ""
echo "_show_expanded:"
echo '	@echo EXPANDED=\"$(TO_BE_EXPANDED)\"'
echo '	@echo PRECIOUS_EXPANDED=\"$(PRECIOUS_TO_BE_EXPANDED)\"'
echo ""
) >>$tmpdir/makefile

#========== DETERMINING THE VALUES

$MAKE -f $tmpdir/makefile _show_all 2>/dev/null \
  | sed -n '/^[A-Z_]*=/p' >$tmpdir/values

. $tmpdir/values

# if there are no COBJ but a PROG or LIB, there is a problem so skip.
#
if [ "x$is_prog" = "xYES" -o "x$is_lib" = "xYES" ]; then
 [ "x$COBJ" != "x" ] || error COBJ_not_set
fi

# if is_prog or is_lib but PROG or LIB unset, stop this build.
#
[ "x$is_prog" != "xYES" -o "x$PROG" != "x" ] \
  || error PROG_not_set

[ "x$is_lib" != "xYES" -o "x$LIB" != "x" ] \
  || error LIB_not_set

# if some COBJ are relatively dired, create the intermediate
# subdirectory (sources may be placed in subdirs without a dedicated
# makefile --- example is libproj4).
#
for subdir in $SUBDIRS; do
	[ -d "$OBJPROGDIR/$subdir" ] || mkdir -p $OBJPROGDIR/$subdir
done

# We can start the real Makefile.
#
makefile=$OBJPROGDIR/Makefile

( 
echo "# Automatically generated by the KerGIS Tools"
echo ".POSIX :"
echo ""
cat $OBJDIR/.rkcomp/config
echo ''
echo "# Generated by KerGIS Tools' rkbuild"
echo ""
echo "OBJPROGDIR=$OBJPROGDIR"
echo ""
) > $makefile

#========== ENSURE CORRECT PATHNAMES
# A source is not a target, whether explicit or implied. Implied
# target are not a problem since we will parse Makefile.ker where
# implicit targets are, by definition, not specified.
# So we need to prepend ./src (aka SRCDIR) to every file
# corresponding to a pattern matching the POSIX value of SUFFIXES plus
# the .data (for raw data that needs to be transformed that is KerGIS
# Tools addition---verbatim data do NOT need a Makefile since it can be
# copied as is by rkinstall).
# First, suppress from products all names that are not suffixed by one
# of the SUFFIXES + .h + .data. (we add XSI too). *.dso, *.o *.a don't 
# need to be taken into account.
#
# dired products (having a '/' are discarded).
#
echo $EXPANDED | tr ' ' '\n' >>$tmpdir/products

cat $tmpdir/products | sort | uniq \
 | sed -n -e '/^\//d' -e '/\.[cylhw]~\{0,1\}$/p' \
	-e '/\.sh~\{0,1\}$/p' \
	-e '/\.data~\{0,1\}$/p' \
	-e '/\.tex~\{0,1\}$/p' \
	>$tmpdir/prods


# In fact, for efficiency, we are going to convert all suffixed non
# absolute dired names to ./src prepended one, and revert the PRODUCTS.
# XXX We are assuming here that we are allowed to use pathnames as
# target names. We must explicitely list the characters to be found
# delimiting a pathname, since taking the complement of a class is not
# enough (because of locales). This is definitively fragile.
#
sed -n -e 's/\./\\./g' \
  -e 's@^\(.*\)$@s!^\\./src/\1\\([;:|\&) 	\\\\]\\)!\1\\1!g@p' \
  $tmpdir/prods > $tmpdir/sed

sed -n -e 's/\./\\./g' \
 -e 's@^\(.*\)@s!^\\./src/\1\\$!\1!g@p' $tmpdir/prods >> $tmpdir/sed

sed -n -e 's/\./\\./g' \
 -e 's@^\(.*\)$@s!\\([= 	]\\)\\./src/\1\\([:;|\&) 	\\\\]\\)!\\1\1\\2!g@p' \
  $tmpdir/prods >> $tmpdir/sed

sed -n -e 's/\./\\./g' \
 -e 's@^\(.*\)$@s!\\([= 	]\\)\\./src/\1$!\\1\1!g@p' \
 $tmpdir/prods >> $tmpdir/sed

# prepend all before reverting for PRODUCTS
# XXX to isolate the patterns, I need a space before and after. If there
# is only one, the pattern will match the first, but since the space is
# "used" before, it is not available after. So I double all...
#
sed -e 's/ /  /g' -e 's/	/	 /g' -e 's/^	 /	/' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\([cylhw][^a-zA-Z0-9_/.-]\)!\1./src/\2.\3!g' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\([cylhw]\)$!\1./src/\2.\3!g' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\(sh[^a-zA-Z0-9_/.-]\)!\1./src/\2.\3!g' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\(sh\)$!\1./src/\2.\3!g' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\(data[^a-zA-Z0-9_/.-]\)!\1./src/\2.\3!g' \
  -e 's!\([= 	]\)\([^/$; ][^; ]*\)\.\(data\)$!\1./src/\2.\3!g' \
  -e 's/  / /g' $mkf \
	| sed -f $tmpdir/sed >>$makefile

# XXX From now on, we will handle the pathnames directly with the rules
# we add. We will use a grep against a file to avoid handling of very 
# beginning against blank

#========== INTERMEDIATE PRODUCTS: LEXEES, YACCEES AND WEBEES

# First see if there are some just in order to add the libes if these
# were not included in Makefile.ker. We will treat them eventually at
# the end, after setting CPPFLAGS and so on

#----- LEXEES

sed 's/$/ /' $mkf \
  | sed -n '/^[^:]*: *[^ 	]*\.l[ 	].*$/p' > $tmpdir/lexees

#----- YACCEES

sed 's/$/ /' $mkf \
  | sed -n '/^[^:]*: *\([^ 	]*\.y\)[ 	].*$/p' > $tmpdir/yaccees

#----- CWEBEES

sed 's/$/ /' $mkf \
  | sed -n '/^[^:]*: *[^ 	]*\.w[ 	].*$/p' > $tmpdir/cwebees

#========== LINKAGE HANDLING
# The LDFLAGS and assimilated will only be needed when linking objects
# in an executable or alike that is a PROG or a DSH_LIB.
# We introduce a new macro LDFLAGS_LIBES that will hold in order the
# -l<libname> needed.
# All paths are taken through symlinking in $OBJDIR/.rkcomp/ld allowing:
#
#	- granularity for static linking since we can mask shared libes
#	- efficiency : one an only one path
#	- minimality of the command line argument
#	- flexibility of the libraries linking since we can also symlink to
#	one version of a lib.
#
# There are two distinct paths: the one needed on compile time to find 
# the library against which to compile, and the path where to find it
# at run time on the host. -L is for now, -rpath (-R) is for future
# reference.
#
# To allow the use of partial static linking and versioning static
# linking, the macro USE_STATIC_LIBES shall be defined in Makefile.ker
# and list, in order, the libes to link statically into the PROG.
# It shall be a subset of LIBES (LIBES _shall_ be set).
#
# The macro MAKE_STATIC means then link statically with all the LIBES
# including CLIB.
# If you want to link statically except for LIBC, just set
# USE_STATIC_LIBES = LIBES.
#
[ "x$MAKE_STATIC" != "xYES" ] || USE_STATIC_LIBES="$LIBES $CLIB"

# Ease the grepping in USE_STATIC_LIBES.
#
USE_STATIC_LIBES=$(echo $USE_STATIC_LIBES | sed -e 's/ \{1,\}/ /g' -e 's/ /|/g' -e 's/^\(.*\)$/|\1|/')

# All the libes will be found (via symlinks) here.
#
LDFLAGS="-L$OBJDIR/.rkcomp/ld"

LDFLAGS_LIBES=
LDFLAGS_DSHARED=$(echo $LDFLAGS_ELF_RPATH_LINK | sed 's@##LIBPATH##@'$OBJDIR/.rkcomp/ld@)
RPATHS=
rpath=
rpath_link=

# Adding the needed paths to headers
# by default add OBJPROGDIR (*.h may be created) and src.
#
CPPFLAGS="-I. -I./src"

for lib in $LIBES; do
	# The headers.
	#
	header=$(sed -n "s@^$lib \\([^ ]\\{1,\\}\\)\$@\\1@p" $OBJDIR/.rkcomp/libes.static)
	[ "x$header" != "x" ] \
	  || header=$(sed -n "s@^$lib \\([^ ]\\{1,\\}\\)\$@\\1@p" $OBJDIR/.rkcomp/libes.dshared)
	if [ "x$header" != "x" -a "x$header" != "xNULL" ]; then
	  CPPFLAGS=$(rk_add_once "$CPPFLAGS" -I$(dirname $header))
	fi

	# The libes.
	# verify so that there is no loop between rk_mk_link_*.
	#
	grep -qF "$lib" $OBJDIR/.rkcomp/libes.static \
	  || grep -qF "$lib" $OBJDIR/.rkcomp/libes.dshared \
	  || error missing_lib $lib

	# Even the dynamic shared will be called a la static.
	#
	if echo $USE_STATIC_LIBES | grep -qF "|$lib|" \
	  && grep -q "^$lib" $OBJDIR/.rkcomp/libes.static; then
	  rk_mk_link_ldaname $lib
	elif grep -q "^$lib" $OBJDIR/.rkcomp/libes.dshared; then
	  rk_mk_link_elf_ldsoname $lib
	    rpath=$(rk_find_lib_rpath $lib)
	  if [ "x$OBJECT_FORMAT" = "xELF" ]; then
	    if [ "x$rpath" != "x" ]; then
	    rpath=$(echo $LDFLAGS_ELF_RPATH | sed 's@##RPATH##@'$rpath@)
		RPATHS=$(rk_add_once "$RPATHS" "$rpath")
	    fi
	  fi
	else
	  rk_mk_link_ldaname $lib
	fi
	LDFLAGS_LIBES="$LDFLAGS_LIBES -l$(rk_mk_ldname $lib)"
done

# If we are generating a LIB, include its header path by default (LIB
# is not set if PROG is).
#
if [ "x$is_lib" = "xYES" ]; then
	header=$(sed -n "s@^$LIB \\([^ ]\\{1,\\}\\)\$@\\1@p" $OBJDIR/.rkcomp/libes.static)
	[ "x$header" != "x" ] \
      || header=$(sed -n "s@^$LIB \\([^ ]\\{1,\\}\\)\$@\\1@p" $OBJDIR/.rkcomp/libes.dshared)
	if [ "x$header" != "x" -a "x$header" != "xNULL" ]; then
	  CPPFLAGS=$(rk_add_once "$CPPFLAGS" -I$(dirname $header))
	fi
fi

(
echo 
echo CPPFLAGS += $CPPFLAGS
echo LDFLAGS += $LDFLAGS
echo LDFLAGS_LIBES = $LDFLAGS_LIBES 
echo LDFLAGS_SSHARED += $LDFLAGS_SSHARED
echo LDFLAGS_DSHARED += $LDFLAGS_DSHARED
echo RPATHS = $RPATHS
echo
) >>$makefile

#========== INTERMEDIATE PRODUCTS: LEXEES, YACCEES AND WEBEES

# Real generation.

# If prefixing needs to be done, a supplementary target has to be
# generated.
#
if [ "x$LEX_YACC_PREFIX" != "x" ]; then
	echo RK_LEX_YACC_PREFIXER = $TOOLDIR/libdata/lex_yacc_prefixer.data >> $makefile
	cat - >>$makefile <<'EOC'

rk_lex_yacc_prefixer.ed : $(RK_LEX_YACC_PREFIXER) 
	sed 's!^\([^ ]\{1,\}\)$$!g/\1/s/\\([^a-zA-Z0-9_]\\)\\(\1\\)\\([^a-zA-Z0-9_]\\)/\\1$(LEX_YACC_PREFIX)\\2\\3/g!' $(RK_LEX_YACC_PREFIXER) > $@
	sed 's!^\([^ ]\{1,\}\)$$!g/\1/s/^\\(\1\\)\\([^a-zA-Z0-9_]\\)/$(LEX_YACC_PREFIX)\\1\\2/g!' $(RK_LEX_YACC_PREFIXER) >> $@
	sed 's!^\([^ ]\{1,\}\)$$!g/\1/s/\\([^a-zA-Z0-9_]\\)\\(\1\\)$$/\\1$(LEX_YACC_PREFIX)\\2/g!' $(RK_LEX_YACC_PREFIXER) >> $@
	echo "w" >> $@
	echo "q" >> $@

EOC
fi

#----- LEXEES

if [ -s $tmpdir/lexees ]; then
	while read line; do
	  (
	  target=$(echo $line | sed -e 's/^ *\([^: ]*\) *:.*$/\1/')
	  src=$(echo $line | sed -e 's/$/ /' -e 's/^[^:]*: *\([^ 	]*.l\)[ 	].*$/\1/')
	  regex=$(echo $src | sed 's/\./\\./g')
	  grep -q "^$regex\$" $tmpdir/prods || src="./src/$src"
	  if [ "x$LEX_YACC_PREFIX" != "x" ]; then
		echo "$target : rk_lex_yacc_prefixer.ed $src"
	  else
	    echo "$target : $src"
	  fi
	  echo '	$(LEX) $(LFLAGS) '$src
	  echo '	[ "$@" = "lex.yy.c" ] || mv lex.yy.c $@'
	  if [ "x$LEX_YACC_PREFIX" != "x" ]; then
		echo '	ed -s $@ < rk_lex_yacc_prefixer.ed'
	  fi
	  echo
	  ) >> $makefile
	done < $tmpdir/lexees
fi

#----- YACCEES

if [ -s $tmpdir/yaccees ]; then
	while read line; do
	  (
	  target=$(echo $line | sed -e 's/\(^[^:]*\):.*$/\1/')
	  src=$(echo $line | sed -e 's/$/ /' -e 's/^[^:]*: *\([^ 	]*.y\)[ 	].*$/\1/')
	  regex=$(echo $src | sed 's/\./\\./g')
	  grep -q "^$regex\$" $tmpdir/prods || src="./src/$src"
	  if [ "x$LEX_YACC_PREFIX" != "x" ]; then
		echo "$target : rk_lex_yacc_prefixer.ed $src"
	  else
	    echo "$target : $src"
	  fi
	  genc=$(echo $line | sed -e 's/^\([^:]*\) *: .*/ \1 /' | sed -n -e 's/^.*[^a-zA-Z0-9_.-]\([^ ]\{1,\}\.c\)[^a-zA-Z0-9_-].*$/\1/p')
	  genh=$(echo $line | sed -e 's/^\([^:]*\) *: .*/ \1 /' | sed -n -e 's/^.*[^a-zA-Z0-9_.-]\([^ ]\{1,\}\.h\)[^a-zA-Z0-9_-].*$/\1/p')
	  echo '	$(YACC) $(YFLAGS) '$src
	  echo '	[ "'$genc'" = "y.tab.c" ] || mv y.tab.c '$genc
	  echo '	[ "'x$genh'" = "x" -o "'$genh'" = "y.tab.h" ] || mv y.tab.h '$genh
	  if [ "x$LEX_YACC_PREFIX" != "x" ]; then
		echo '	ed -s '$genc' < rk_lex_yacc_prefixer.ed'
		echo '	[ "x'$genh'" = "x" ] || ed -s '$genh' < rk_lex_yacc_prefixer.ed'
	  fi
	  echo
	  ) >> $makefile
	done < $tmpdir/yaccees
fi

#----- CWEBEES

if [ -s $tmpdir/cwebees ]; then
	i=0
	while read line; do
	  i=$(($i + 1))
	  (
	  target=$(echo $line | sed -e 's/\(^[^:]*\):.*$/\1/')
	  src=$(echo $line | sed -e 's/$/ /' -e 's/^[^:]*: *\([^ 	]*.w\)[ 	].*$/\1/')
	  regex=$(echo $src | sed 's/\./\\./g')
	  grep -q "^$regex\$" $tmpdir/prods || src="./src/$src"
	  echo "$target : $src"
	  echo '	CWEBINPUTS="$(CWEBINPUTS)" $(CTANGLE) '$src
	  echo
	  echo "doc$i : $src"
	  echo '	CWEBINPUTS="$(CWEBINPUTS)" $(CWEAVE) '$src
	  echo
	  ) >> $makefile
	done < $tmpdir/cwebees
	scratch="doc_all: "
	while [ $i -ne 0 ]; do
	  scratch="$scratch doc$i"
	  i=$(($i - 1))
	done
	echo "
$scratch" >> $makefile
fi

#========== GENERATING OBJECTS, PROG and LIB
# Optimization: fix the pathnames once for all the COBJ to avoid
# looking for every name individually and remaking everything for
# dshared generation.
#
echo $COBJ | tr ' ' '\n' \
  | sed -e 's!^\(.*\)\.o$!\1.o ./src/\1.c!' \
  | sed -f $tmpdir/sed \
  > $tmpdir/cobj

(
if [ "x$is_prog" = "xYES" ]; then
	echo
	echo '$(PROG): $(COBJ)'
	echo '	$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_DSHARED) '$RPATHS' -o $@ $(COBJ)  $(LDFLAGS_LIBES)'
	echo
	while read obj src; do
	  echo "$obj: $src"
	  echo '	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ '$src
	  echo
	done < $tmpdir/cobj
fi
) >>$makefile

(
if [ "x$is_lib" = "xYES" ]; then
	# Note that the target static library will always be followed.
	#
	STATIC_LIB=$(rk_mk_realaname $LIB)

	# Add the target names for static shared and dynamic shared even
	# if not generated.
	#
	DSH_LIB=$(rk_mk_elf_realsoname $LIB)
	echo "DSH_LIB = $DSH_LIB"

	# Add an indirection to avoid the rewriting of the makefile
	# (since the normalized libname as no sense for say AR).
	#
	echo '$(LIB): '$STATIC_LIB
	echo

	# Static lib.
	#
	if [ "x$MAKE_STATIC_LIB" = "xYES" ]; then
	  echo $STATIC_LIB: '$(COBJ)'
	  echo '	$(AR) $(ARFLAGS) $@ $(COBJ)'
	  echo '	[ "x$(SAVE_SPACE)" != "xYES" ] || rm -f $(COBJ)'
	else
	  echo
	  echo '$(LIB):' 
	  echo '	@echo "Static library not built'
	fi
	if [ "x$MAKE_DSHARED_LIB" = "xYES" -a "x$DSH_LIB" != "x" ]; then
	  echo '	$(MAKE) $(DSH_LIB)'
	fi
	echo
	if [ "x$MAKE_DSHARED_LIB" = "xYES" -a "x$DSH_LIB" != "x" ]; then
	  # Create the dsh_cobj list.
	  #
	  sed 's@\([^/]*\)\.o @\1.dso @' $tmpdir/cobj > $tmpdir/dsh_cobj
	  DSH_COBJ=$(sed 's!^\([^ ]*\).*$!\1!' $tmpdir/dsh_cobj | tr '\n' ' ')
	  SONAME=$(rk_mk_elf_soname $(basename $LIB))
	  LDFLAGS_ELF_SONAME=$(echo $LDFLAGS_ELF_SONAME | sed 's/##SONAME##/'$SONAME/)
	  LDSONAME=$(rk_mk_elf_ldsoname $(basename $LIB))
	  echo "DSH_COBJ = $DSH_COBJ"
	  echo
	  echo '$(DSH_LIB): $(DSH_COBJ)'
	  if [ "x$OBJECT_FORMAT" = "xELF" ]; then
	    echo '	$(LD_DSHARED) $(LDFLAGS) '$LDFLAGS_ELF_SONAME  $RPATHS' $(LDFLAGS_DSHARED) -o $@ $(DSH_COBJ) $(LDFLAGS_LIBES)'
	    else
	    echo '	@echo "No other format than ELF supported for dshared!"'
	  fi

	  echo '	[ "x$(SAVE_SPACE)" != "xYES" ] || rm -f $(DSH_COBJ)'
	  echo
	fi
	if [ "x$MAKE_STATIC_LIB" = "xYES" ]; then
	  while read obj src; do
	    echo "$obj: $src"
	    echo '	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ '$src
	    echo
	  done < $tmpdir/cobj
	fi
	if [ "x$MAKE_DSHARED_LIB" = "xYES" -a "x$DSH_LIB" != "x" ]; then
	  while read obj src; do
	    echo "$obj: $src"
	    echo '	$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_DSHARED) -c -o $@ '$src
	    echo
	  done < $tmpdir/dsh_cobj
	  fi
fi
) >>$makefile

#========== FINAL CLEAN TARGET
# Create a PRODUCTS variable to be used (after removing _.PRECIOUS_
# things) when cleaning.
#
cat /dev/null > $tmpdir/precious.sed
echo $PRECIOUS_EXPANDED | tr ' ' '\n' >> $tmpdir/precious

# Remove macros that have been expanded.
#
ed -s $tmpdir/precious <<EOT
g/^\\\$/d
w
q
EOT

for precious in `cat $tmpdir/precious`; do
	precious=$(echo $precious | sed 's!/!\\/!g')
	echo "/^$precious\$/d" >> $tmpdir/precious.sed
done
PRODUCTS=$(sed -f $tmpdir/precious.sed $tmpdir/prods | tr '\n' ' ')

# Read LEX and YACC generated well known names and add a space at the
# the beginning and at the end so that matching will be eased.
#
PRODUCTS="$PRODUCTS lex.yy.c y.tab.c y.tab.h y.output"

# If there are subdirs we need to clean their objects too.
#
for subdir in $SUBDIRS; do
	PRODUCTS="$PRODUCTS ${subdir%/}/*.o ${subdir%/}/*.dso"
done

(
echo
echo "PRODUCTS = $PRODUCTS" 
echo ""
echo 'clean:'
echo '	rm -f *.o *.dso $(PRODUCTS)' 
) >>$makefile

#------------------POST PROCESSING

[ "x$debug_mode" = "xYES" ] || clean_tmp

exit 0
