# This tcl script generates the makefile.
#
# This script begins life as "makemake.tcl.in".  A "configure"
# shell script will read "makemake.tcl.in" and generate
# "makemake.tcl".  The makemake.tcl script then runs to
# produce the makefile.
#
# This script needs to know the following information about
# the build environment:
#
#   *   The location of the source code.  
#
#       This is the name of the directory that contains 
#       makemake.tcl.in and configure.  The build products 
#       (the *.o and *.exe files) and makemake.tcl will
#       be written into the working directory.  The working
#       directory can and should be distinct and separate from
#       the source directory.  The source directory can be
#       on a read-only filesystem.  The name of the source 
#       directory is stored in the $TOP variable.
#
#   *   How to compile and link C code into command-line programs to
#       run on the build platform.
#
#       The compiler command name is stored in $BCC.  If any
#       libraries are required, they are stored in $BLIBS
#
#   *   The suffix to give to command-line programs that run
#       on the build platform.
#
#       This is stored in $BEXE
#
#   *   How to compile C modules into *.o files for the target
#       platform.
#
#       This is the $TCC variable.
#
#   *   The suffix to give to programs that run on the target
#       platform.
#
#       This is the $TEXE variable.
#
#   *   How to link *.o files produced by $TCC command into
#       an executable that runs on the target platform.
#
#       The $TLINK command does the linking.  It requires
#       arguments stored in $TLIBS
#
#   *   The names of directories containing Tcl script libraries
#       that are compatible with the Tcl C libraries on the
#       target platform.
#
#       These are the $TCLSCRIPTDIR and $TKSCRIPTDIR variables.
#
#   *   The name of a tclsh that works on the build platform.
#
#       This is the $BTCLSH variable.
#
# All of the above information is discovered by the configure
# shell script.  The configure shell script then inserts the 
# information here:
#
set TOP           [list @srcdir@]
set BCC           [list @BUILD_CC@ @BUILD_CFLAGS@]
set BLIBS         [list @BUILD_LIBS@]
set BEXE          [list @BUILD_EXEEXT@]
set BTCLSH        [list @BUILD_TCLSH@]
set TCC           [list @TARGET_CC@ @TARGET_CFLAGS@ -I. @TARGET_TK_INC@ \
                    @TARGET_X_INC@ @TARGET_TCL_INC@ @TARGET_BLT_INC@]
set TEXE          [list @TARGET_EXEEXT@]
set TLINK         [list @TARGET_LINK@ @TARGET_LFLAGS@]
set TLIBS         [list @TARGET_BLT_LIBS@ @TARGET_TK_LIBS@ @TARGET_X_LIBS@ \
                    @TARGET_TCL_LIBS@ @TARGET_LIBS@]
set TCLSCRIPTDIR  [list @TARGET_TCL_SCRIPT_DIR@]
set TKSCRIPTDIR   [list @TARGET_TK_SCRIPT_DIR@]
#
# The "configure" script makes no changes beyond this point.
#############################################################################

# To customize the makefile, begin by adding or removing
# files from the following four lists.

# Put the basename of each C source code modules
# here.  Omit the ".c" suffix.
#
set srcc {
  src/cell
  src/psdgui
}

# Put the names of all TCL source files here.  Include the ".tcl"
# suffix.
#
set srctcl {
  src/balloon.tcl
  src/build.tcl
  src/calibrate.tcl
  src/cell.tcl
  src/console.tcl
  src/enable.tcl
  src/labelframe.tcl
  src/notebook.tcl
  src/psdgui.tcl
}

# Put here the basenames of all C code modules that are
# generated by helper programs or/and automated scripts.  These
# files are C code but they are not source code.  The output
# of mktclapp goes on this list, as does any other C file that
# gets automatically generated.  Omit the ".c" suffix.
#
set autoc {
  xrayinit
}

# Put here the names of all TCL code modules that are
# generated by helper programs and/or scripts.  Include the
# ".tcl" suffix.
#
set autotcl {
  help.tcl
}

# Remove surplus white-space from the named
# variable.
#
proc Strip varname {
  upvar 1 $varname v
  regsub -all "\[ \t\n\r\]\[ \t\n\r\]*" $v { } v
}

# Remove surplus whitespace from the lists of files defined above.
#
Strip srcc
Strip srctcl
Strip autoc
Strip autotcl

# Remove surplus ".." and "." elements from a pathname.
#
proc CleanPath path {
  regsub -all {/\./} $path / path
  while {[regsub -all {[^/]*[^/.]/\.\./} $path {} path]} {}
  return $path
}

# Convert a pathname to an absolute pathname.
#
proc AbsPath path {
  switch [file pathtype $path] {
    absolute {
      set path [CleanPath $path]
    }
    relative {
      set path [CleanPath [pwd]/$path]
    }
    default {
    }
  }
  return $path
}


# Prefix on all executable names
#
set PFX       {}

# The cleanable variable collects the names of all
# build products so they can be deleted by "make clean"
#
set cleanable {}

# The exelist variable collects the names of all executables
#
set exelist {}

# Write an introduction to the generated makefile.  Include the
# "all" target here.
# 
puts "# Automatically generated by makemake.tcl"
puts "# Do Not Edit!"
puts ""
if {$TEXE==""} {
  puts "tests:	${PFX}psdgui-dev ${PFX}psdhost"
}  
puts "all:	${PFX}psdgui$TEXE"
puts ""
puts "${PFX}psdhost$TEXE:	${PFX}psdsim$TEXE"
puts "	cp ${PFX}psdsim$TEXE ${PFX}psdhost$TEXE"
puts ""

# Call this routine to generate code that will build a
# utility that will run on the host.
#
proc MakeUtil {name src} {
  global cleanable BCC BEXE BLIBS
  puts "$name$BEXE:	$src"
  puts "	$BCC -o $name$BEXE $src $BLIBS" 
  puts ""
  lappend cleanable $name$BEXE
}

# Call this routine to generate code that will link a program
# to run on the target.
#
proc MakeProg {name obj} {
  global exelist TEXE TLINK TLIBS
  puts "$name$TEXE:	$obj"
  puts "	$TLINK -o $name$TEXE $obj $TLIBS"
  puts ""
  lappend exelist $name$TEXE
}

# Call this routine to generate code that will convert C code
# into a *.o file that will ultimately run on the target.
#
proc MakeObj {name src dep} {
  global cleanable TCC TOP
  puts "$name:	$src $dep"
  set inc "-DSRCDIR='\"[AbsPath $TOP/src]\"' -DBUILDDIR='\"[pwd]\"'"
  puts "	$TCC $inc -o $name -c $src"
  puts ""
  lappend cleanable $name
}

# Compile host-side utilities
#
MakeUtil makeheaders [CleanPath $TOP/tools/makeheaders.c]
MakeUtil mktclapp [CleanPath $TOP/tools/mktclapp.c]
MakeUtil help2tk [CleanPath $TOP/tools/help2tk.c]

# The main program
#
set obj {}
foreach f [concat $srcc $autoc] {
  set m [file tail $f]
  lappend obj $m.o
}
set obj [lsort $obj]
MakeProg ${PFX}psdgui $obj
regsub xrayinit.o $obj xrayinit-dev.o obj
MakeProg ${PFX}psdgui-dev $obj

# Generate code to prepare all the *.o files.  We'll collect
# information about headers at the same time.
#
set hdr {}
set mharg {}
foreach f $srcc {
  set m [file tail $f]
  MakeObj $m.o [CleanPath $TOP/$f.c] $m.h
  lappend hdr $m.h
  lappend cleanable $m.h
  lappend mharg [CleanPath $TOP/$f.c]:$m.h
}
foreach f $autoc {
  MakeObj $f.o $f.c $f.h
  # lappend hdr $f.h
  lappend cleanable $f.h
}
MakeObj xrayinit-dev.o xrayinit-dev.c {}

# Generate code to make the header files.
#
foreach h $hdr {
  puts "$h:	headers"
}
puts ""
puts "headers:	makeheaders$BEXE xrayinit.h"
puts "	./makeheaders$BEXE $mharg"
puts "	touch headers"
puts ""
lappend cleanable headers
puts "xrayinit.h:	mktclapp$BEXE"
puts "	./mktclapp$BEXE -header >xrayinit.h"
puts ""
lappend cleanable xrayinit.h

# Generate the application initializtion file using mktclapp.
#
set allsrc {}
foreach f $srcc {
  lappend allsrc [CleanPath $TOP/$f.c]
}
puts "xrayinit-dev.c:	mktclapp$BEXE $allsrc xrayinit-dev.mta"
puts "	./mktclapp$BEXE -f xrayinit-dev.mta >xrayinit-dev.c"
puts ""
lappend cleanable xrayinit-dev.c
foreach f $srctcl {
  lappend allsrc [CleanPath $TOP/$f]
}
foreach f $autotcl {
  lappend allsrc $f
}
puts "xrayinit.c:	mktclapp$BEXE $allsrc xrayinit.mta"
puts "	./mktclapp$BEXE -f xrayinit.mta >xrayinit.c"
puts ""
lappend cleanable xrayinit.c

# Generate the *.mta file that mktclapp requires.  The *.mta
# file tells mktclapp what components go into the application
# initializatio file.  See the documentation on mkclapp for
# details.
#
set mtasrc {}
foreach f $srcc {
  lappend mtasrc $TOP/$f.c
}
foreach f $srctcl {
  lappend mtasrc [AbsPath $TOP/$f]
}
foreach f $autotcl {
  lappend mtasrc [pwd]/$f
}
set n xrayinit-dev.mta
puts "$n:	"
puts "	echo -main-script [AbsPath $TOP/src/psdgui.tcl] >$n"
puts "	echo -tcl-library $TCLSCRIPTDIR >>$n"
puts "	echo -tk-library $TKSCRIPTDIR >>$n"
puts "	echo $TCLSCRIPTDIR/*.tcl >>$n"
puts "	echo $TCLSCRIPTDIR/tclIndex >>$n"
puts "	echo $TKSCRIPTDIR/*.tcl >>$n"
puts "	echo $TKSCRIPTDIR/tclIndex >>$n"
puts ""
lappend cleanable $n
set n xrayinit.mta
puts "$n:	xrayinit-dev.mta"
puts "	cat xrayinit-dev.mta >$n"
puts "	echo $mtasrc >>$n"
puts ""
lappend cleanable $n

# Generate the help screens.
#
puts "help.tcl:	help2tk$BEXE $TOP/src/psdgui.help"
puts "	./help2tk$BEXE $TOP/src/psdgui.help >help.tcl"
puts ""

##############################################################################
# The rest is for the psdhost simulator.
#

# Put the basename of each C source code modules
# here.  Omit the ".c" suffix.
#
set srcc {
  src/psdsim
}

# Put the names of all TCL modules here.  Include the ".tcl"
# suffix.
#
set srctcl {
  src/notebook.tcl
  src/psdsim.tcl
}

# Put here the basenames of all C code modules that are
# generated by helper programs or/and automated scripts.  These
# files are C code but they are not source code.  Omit the ".c"
# suffix.
#
set autoc {
  siminit
}

# Put here the names of all TCL code modules that are
# generated by helper programs and/or scripts.  Include the
# ".tcl" suffix.
#
set autotcl {
}

# Remove surplus whitespace from the lists of files.
#
Strip srcc
Strip srctcl
Strip autoc
Strip autotcl

# The main program
#
set obj {}
foreach f [concat $srcc $autoc] {
  set m [file tail $f]
  lappend obj $m.o
}
set obj [lsort $obj]
MakeProg ${PFX}psdsim $obj

# Generate code to prepare all the *.o files.  We'll collect
# information about headers at the same time.
#
set hdr {}
set mharg {}
foreach f $srcc {
  set m [file tail $f]
  MakeObj $m.o [CleanPath $TOP/$f.c] $m.h
  lappend hdr $m.h
  lappend cleanable $m.h
  lappend mharg [CleanPath $TOP/$f.c]:$m.h
}
foreach f $autoc {
  MakeObj $f.o $f.c $f.h
  lappend hdr $f.h
  lappend cleanable $f.h
}

# Generate code to make the header files.
#
foreach h $hdr {
  puts "$h:	headers2"
}
puts ""
puts "headers2:	makeheaders$BEXE"
puts "	./makeheaders$BEXE $mharg"
puts "	touch headers2"
puts ""
lappend cleanable headers2

# Generate the application initializtion file using mktclapp.
#
set allsrc {}
foreach f $srcc {
  lappend allsrc [CleanPath $TOP/$f.c]
}
foreach f $srctcl {
  lappend allsrc [CleanPath $TOP/$f]
}
foreach f $autotcl {
  lappend allsrc $f
}
puts "siminit.c:	mktclapp$BEXE $allsrc siminit.mta"
puts "	./mktclapp$BEXE -f siminit.mta >siminit.c"
puts ""
lappend cleanable siminit.c

# Generate the *.mta file that mktclapp requires.  The *.mta
# file tells mktclapp what components go into the application
# initializatio file.  See the documentation on mkclapp for
# details.
#
set mtasrc {}
foreach f $srcc {
  lappend mtasrc $TOP/$f.c
}
foreach f $srctcl {
  lappend mtasrc [AbsPath $TOP/$f]
}
foreach f $autotcl {
  lappend mtasrc [pwd]/$f
}
set n siminit.mta
puts "$n:	"
puts "	echo $mtasrc >$n"
puts "	echo -main-script [AbsPath $TOP/src/psdgui.tcl] >>$n"
puts "	echo -tcl-library $TCLSCRIPTDIR >>$n"
puts "	echo -tk-library $TKSCRIPTDIR >>$n"
puts "	echo $TCLSCRIPTDIR/*.tcl >>$n"
puts "	echo $TCLSCRIPTDIR/tclIndex >>$n"
puts "	echo $TKSCRIPTDIR/*.tcl >>$n"
puts "	echo $TKSCRIPTDIR/tclIndex >>$n"
puts ""
lappend cleanable $n

# The usual makefile target...
#
puts "clean:	"
puts "	rm -f $cleanable"
puts ""
puts "distclean:	"
puts "	rm -f $cleanable $exelist config.cache config.log config.status all.mk"
puts ""
puts "install:	all"
puts "	if test ! -d ../bin; then mkdir ../bin; fi"
puts "	mv $exelist ../bin"
puts ""
