#!/usr/bin/tclsh
global existing_files
global known_files
global known_dep
global memory_file
global header_file
global GARBAGE
global target_name
global target_dir
global output_file
global MOTIF
global MMCMD
##################################################
### User variable
set GARBAGE "./garbage"
set header_file "Make.header"
set output_file "Makefile"
set target_name "itinR"
set target_dir "."
set memory_file "make.mem"
set MOTIF {"*.c" "*.cpp"}
set SRCDIRS [list "sources"]
set INCLUDES [list "-I./sources"]
set MMCMD [concat [list gcc -MM ] $INCLUDES]
####################################################
puts "finding all files..."
proc fullname { file } {
set olddir [exec pwd]
set dir [file dirname $file]
cd $dir
set result "[exec pwd]/[file tail $file]"
cd $olddir
return $result
}
proc build_existing_tbl { motif } {
global existing_files SRCDIRS
global known_files
foreach dir $SRCDIRS {
set oldir [exec pwd]
cd $dir
foreach type $motif {
set liste [exec ls ]
set liste [split $liste "\n"]
foreach file $liste {
if { [string match "$type" $file] && \
[file type $file] == "file" } {
#set file [fullname $file]
set cfile "$dir/$file"
set existing_files($cfile) [file mtime $file]
set known_files($cfile) 0
}
}
}
cd $oldir
}
}
proc build_known_tbl { file } {
global known_files known_dep
if {![file exist $file]} {return}
set fid [open $file]
while {[gets $fid line] >= 0} {
set line [split $line "@"]
set known_files([lindex $line 0]) [lindex $line 1]
set known_dep([lindex $line 0]) [lindex $line 2]
}
close $fid
}
proc save_known_tbl { } {
global memory_file existing_files
global known_files known_dep
set fid [open $memory_file "w"]
foreach file [array names existing_files] {
puts $fid [join \
[list "$file" "[file mtime $file]" "$known_dep($file)"]\
"@" ]
}
close $fid
}
proc print_bilan { } {
global existing_files known_files
foreach file [array name existing_files] {
if {$known_files($file) == 0 } {
puts "[format "%-60s : New" $file]"
} else {
if {$existing_files($file) > $known_files($file) } {
puts "[format "%-60s : Modified" $file]"
} else {
puts "[format "%-60s : Unchanged" $file]"
}}
}
}
proc eval_dep { file } {
global MMCMD
set res [eval [concat exec $MMCMD $file]]
set res [join [split $res "\\\n "] " "]
return $res
}
proc build_dependencies { } {
global existing_files known_files known_dep
foreach file [array name existing_files] {
if {$known_files($file) == 0 } {
set known_dep($file) [eval_dep $file]
puts -nonewline "*"
} else {
if {$existing_files($file) > $known_files($file) } {
set known_dep($file) [eval_dep $file]
puts -nonewline "+"
} else {
puts -nonewline "."
}}
flush stdout
}
puts "OK"
}
proc oname { file } {
global GARBAGE
return "$GARBAGE/[file rootname [file tail $file]].o"
}
proc build_makefile { } {
global GARBAGE target_dir
global header_file output_file target_name
global existing_files known_files known_dep
if {[file exists $header_file]} {
exec cat $header_file > $output_file
}
set fid [open $output_file "a"]
puts $fid "\n\n\n#Autogenerated part\n\n\n"
set liste [lsort -ascii [array names existing_files]]
puts -nonewline $fid "$target_dir/$target_name : "
foreach file $liste {
puts -nonewline $fid "[oname $file] "
}
puts -nonewline $fid "\n\t(cd $GARBAGE ; $(LD) -o $target_name "
foreach file $liste {
puts -nonewline $fid "[file rootname [file tail $file]].o "
}
puts $fid ")"
puts $fid "\tcp $GARBAGE/$target_name $target_dir/\n"
foreach file $liste {
puts $fid "$GARBAGE/$known_dep($file)"
puts $fid "\t$(CC) -c -o [oname $file] $file\n"
}
close $fid
}
puts "Preparing tables"
build_existing_tbl $MOTIF
build_known_tbl $memory_file
print_bilan
puts "Building the dependencies"
build_dependencies
puts "Writing Makefile"
build_makefile
puts "Saving dependencies"
save_known_tbl
puts "Warning : CC and LD must be defined in $header_file"