2003-11-20 VI I just love smake. Mostly because I have tclsh across all the platforms I work on. I thought there was something called "Jam", but couldn't find it.
[ LV see http://freetype.sf.net/jam/index.html for an intro to jam, which appears to be a part of perforce. ]
In any case I like the simple smake to the more complex (and more capable) bras.
Some notes about smake follow. I have also emailed the author.
Hm, didn't see your email. Maybe it got mixed up in all the spam :P Will look at these issues when I have a bit of time. --Setok
When a target doesn't exist but all the dependencies are up-to-date, smake doesn't run the rule, which is counter-intuitive. e.g.
target a { depend {b.o c.o} { link a [list b.o c.o] } }
Here you would expect that if a doesn't exist, but b.o and c.o are up-to-date, then the link will run. That doesn't seem to happen for me (I could be just using it wrong). In any case, to fix this here's what I added:
Just before this:
if {$update} { uplevel 1 $op uplevel 1 {set targetUpdate 1} }
in the proc "depend", I added this:
if !$update { set thistarget [lindex $SmakeTargetPath end] if ![file exists $thistarget] { dputs 3 "Target $thistarget hasn't been made yet, update" set update 1 } }
Hope this helps someone!
2003-11-20 VI : A possible cleaner way to do the set this target is to do it like this:
if !$update { upvar target thistarget if ![file exists $thistarget] { dputs 3 "Target $thistarget hasn't been made yet, update" set update 1 } }
2003-11-20 VI : stdout and stderr redirection doesn't work. I often write a command like
exec grep -n Error $logfile > errors.log
smake nicely renames exec and prints the line before executing, but in this case the redirection doesn't work. To fix that, I change:
eval "exec_old $args >@ stdout 2>@ stderr"
to just
eval "exec_old $args"
I'm not sure why the >@ and 2>@ are there. When would it be needed?
2003-12-03 VI : I do know now why 2>@ is required. If you don't do that then the stuff printed to stderr causes the tcl exec to think that there's been an error. So like make if we want to be just return code based, then we need to add the 2>@. A naive implementation :
proc exec {args} { global TCL_ERROR if {![regexp {>&} $args] && ![regexp {[|][&]} $args] && ![regexp {2>} $args]} { append args " 2>@ stderr" } puts $args set rc [catch { eval "exec_old $args" } errmsg] if {$rc == $TCL_ERROR} { puts stderr "$::errorCode
$::errorInfo"
error $errmsg } }
I also found that sometimes I have stuff that I want to print the stuff I'm doing in Tcl to the stdout because many things that were external commands in make become internal. e.g. file mkdir. So I added another trivial proc:
proc tcl {args} { puts $args eval $args }
So I can mix exec and tcl calls in my commands and everything gets printed...
Should the eval above really be uplevel? And perhaps there's a better way of writing those three regexps in that expression..
2003-12-19 VI I also like the way make lets you set variables on the command line, so:
} elseif {[string equal $arg "--version"]} { # Show version puts $SmakeVersion exit } elseif {[regexp {^(.*)=(.*)$} $arg => name value]} { set ::$name $value } else { set parsed_args [lappend $parsed_args $arg] }
The two lines starting with the regexp are added to the parse_opt proc.
2003-12-26 VI Some bright guy added this line, saying this:
TMK [L1 ] is also very capable and easy to use.
in the middle of a paragraph which I wrote with MY name in the beginning. I have never used TMK and do not have any opinion on it. I rather resent somebody putting a statement like I wrote it. Feel free to add a paragraph, or a few paragraphs or a whole page anywhere, but please don't make it sound like it came from me!
2004-04-27 VI Two more features of make that I like. One is the ability to define variables on the command line the second is to have multiple targets. The original code uses a variable value as the first argument to lappend, which I think is not the intent:
In parse_opt, replace:
} else { set parsed_args [lappend $parsed_args $arg] }
with:
} elseif {[regexp {^(.*)=(.*)$} $arg => name value]} { set ::$name $value } else { lappend parsed_args $arg }
The first branch allows for VAR=value on the command line. For multiple targets you also need to change (towards the end of smake.tcl)
set target [lindex $argv 0]
to:
set target $argv
2004-08-04 VI another bug. If a name exists as a target, then any file depending on this target is not rebuilt, unless this is rebuilt. An example is clearer
target a { depend {b} { exec cp b a } } target b { depend {c} { exec cp c b } }
.
% touch c % smake cp c b cp b a % touch b % smake
Nothing happens here, I'd have expected a "cp b a" to happen, but
% touch c % smake cp c b cp b a
That is because c isn't a target, but b is. The fix is to add these in the proc depend. The first three lines below already exist. the next 7 are new
set update [expr $update || [execTargetCode [convertTargetToProc $target] $target]] if {!$update && [file exists $thistarget]} { upvar target thistarget if {[file mtime $thistarget] < [file mtime $target]} { dputs 2 "target $target wasn't rebuilt but is newer than $thistarget" set update 1 } }
OCZ (5 aout 2004) I suggere to look at another method of construction of make which I have program on the site: [L2 ]
2004-08-06 VI Thanks for the pointer. Nice. Even with my limited french. But I think smake is still cool. And the makefiles look so much like tcl. so much like tcl.
AM I have taken an interest in smake - for various reasons, mostly having to do with a wish to automate all manner of things in a project. I read the source code, wonderfully compact, and I came up with a bunch of ideas to enhance it:
I have the following facts:
We can now ask the following questions:
The processing of these questions looks a lot like the dependency tree of a program ...
(Oh, one more remark: the examples in the documentation are a trifle out of touch with the text)
Setok I just created a git repository of the stuff I had (doesn't include any of these patches yet). See the smake page for details.