summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavygrvy <davygrvy@pobox.com>2007-10-14 07:04:29 (GMT)
committerdavygrvy <davygrvy@pobox.com>2007-10-14 07:04:29 (GMT)
commit8fe8aa25089849c90a9c4caf108f0fc54149121b (patch)
tree3a16b5b0ed6ad715fe2f3ada42dd85ee35ae7c15
parentf24f9c3837d137fb8cfd2db7c6db822e7a55dc9f (diff)
downloadtcl-8fe8aa25089849c90a9c4caf108f0fc54149121b.zip
tcl-8fe8aa25089849c90a9c4caf108f0fc54149121b.tar.gz
tcl-8fe8aa25089849c90a9c4caf108f0fc54149121b.tar.bz2
* tools/mkdepends.tcl (new): Initial stab at generating automatic
* win/makefile.vc: dependencies.
-rw-r--r--tools/mkdepend.tcl411
-rw-r--r--win/makefile.vc42
2 files changed, 434 insertions, 19 deletions
diff --git a/tools/mkdepend.tcl b/tools/mkdepend.tcl
new file mode 100644
index 0000000..018b368
--- /dev/null
+++ b/tools/mkdepend.tcl
@@ -0,0 +1,411 @@
+#==============================================================================
+#
+# mkdepend : generate dependency information from C/C++ files
+#
+# Copyright (c) 1998, Nat Pryce
+#
+# Permission is hereby granted, without written agreement and without
+# license or royalty fees, to use, copy, modify, and distribute this
+# software and its documentation for any purpose, provided that the
+# above copyright notice and the following two paragraphs appear in
+# all copies of this software.
+#
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+# SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THE AUTHOR HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+# UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#==============================================================================
+#
+# Modified heavily by David Gravereaux <davygrvy@pobox.com> about 9/17/2006.
+# Original can be found @ http://www.doc.ic.ac.uk/~np2/software/mkdepend.html
+#
+#==============================================================================
+# RCS: @(#) $Id: mkdepend.tcl,v 1.1 2007/10/14 07:05:06 davygrvy Exp $
+#==============================================================================
+
+array set mode_data {}
+set mode_data(vc32) {cl -nologo -E}
+
+set cpp_args ""
+set source_extensions [list .c .cpp .cxx]
+set target_extension ".obj"
+set target_prefix ""
+set remove_prefix ""
+set verbose 1
+
+set excludes [list]
+if [info exists env(INCLUDE)] {
+ set rawExcludes [split [string trim $env(INCLUDE) ";"] ";"]
+ foreach exclude $rawExcludes {
+ lappend excludes [file normalize $exclude]
+ }
+}
+
+
+# openOutput --
+#
+# Opens the output file.
+#
+# Arguments:
+# file The file to open
+#
+# Results:
+# None.
+
+proc openOutput {file} {
+ global output
+ set output [open $file w]
+ puts $output "# Automatically generated at [clock format [clock seconds]] by [info script]"
+}
+
+# closeOutput --
+#
+# Closes output file.
+#
+# Arguments:
+# none
+#
+# Results:
+# None.
+
+proc closeOutput {} {
+ global output
+ if {[string match stdout $output]} {
+ close $output
+ }
+}
+
+# readDepends --
+#
+# Read off CCP pipe for #include references. pipe channel
+# is closed when done.
+#
+# Arguments:
+# chan The pipe channel we are reading in.
+#
+# Results:
+# Raw dependency list pairs.
+
+proc readDepends {chan} {
+ global source_extensions target_extension verbose
+
+ array set depends {}
+ set line ""
+
+ while {[gets $chan line] != -1} {
+ if {[regexp {^#line [0-9]+ \"(.*)\"$} $line tmp fname] != 0} {
+ if {[lsearch $source_extensions [file extension $fname]] != -1} {
+ set target2 "[file rootname $fname]$target_extension"
+
+ if {![info exists target] ||
+ [string compare $target $target2] != 0} \
+ {
+ set target $target2
+ set depends($target|[file normalize $fname]) ""
+
+ if $verbose {
+ puts stderr "processing [file tail $fname]"
+ }
+ }
+ } else {
+ set depends($target|[file normalize $fname]) ""
+ }
+ }
+ }
+ catch {close $chan}
+
+ set result {}
+ foreach n [array names depends] {
+ set pair [split $n "|"]
+ lappend result [list [lindex $pair 0] [lindex $pair 1]]
+ }
+
+ return $result
+}
+
+# genStubs::interface --
+#
+# This function is used in the declarations file to set the name
+# of the interface currently being defined.
+#
+# Arguments:
+# name The name of the interface.
+#
+# Results:
+# None.
+proc writeDepends {out depends} {
+ foreach pair $depends {
+ puts $out "[lindex $pair 0] : \\\n\t[join [lindex $pair 1] " \\\n\t"]"
+ }
+}
+
+# genStubs::interface --
+#
+# This function is used in the declarations file to set the name
+# of the interface currently being defined.
+#
+# Arguments:
+# name The name of the interface.
+#
+# Results:
+# None.
+proc stringStartsWith {str prefix} {
+ set front [string range $str 0 [expr {[string length $prefix] - 1}]]
+ return [expr {[string compare [string tolower $prefix] \
+ [string tolower $front]] == 0}]
+}
+
+# genStubs::interface --
+#
+# This function is used in the declarations file to set the name
+# of the interface currently being defined.
+#
+# Arguments:
+# name The name of the interface.
+#
+# Results:
+# None.
+proc filterExcludes {depends excludes} {
+ set filtered {}
+
+ foreach pair $depends {
+ set excluded 0
+ set file [lindex $pair 1]
+
+ foreach dir $excludes {
+ if [stringStartsWith $file $dir] {
+ set excluded 1
+ break;
+ }
+ }
+
+ if {!$excluded} {
+ lappend filtered $pair
+ }
+ }
+
+ return $filtered
+}
+
+# genStubs::interface --
+#
+# This function is used in the declarations file to set the name
+# of the interface currently being defined.
+#
+# Arguments:
+# name The name of the interface.
+#
+# Results:
+# None.
+proc replacePrefix {file} {
+ global srcPathList srcPathReplaceList
+
+ foreach was $srcPathList is $srcPathReplaceList {
+ regsub $was $file $is file
+ }
+ return $file
+}
+
+# rebaseFiles --
+#
+# Replaces normalized paths with original macro names.
+#
+# Arguments:
+# depends Dependency pair list.
+#
+# Results:
+# None.
+
+proc rebaseFiles {depends} {
+ set rebased {}
+ foreach pair $depends {
+ lappend rebased [list \
+ [replacePrefix [lindex $pair 0]] \
+ [replacePrefix [lindex $pair 1]]]
+
+ }
+ return $rebased
+}
+
+# compressDeps --
+#
+# Compresses same named tragets into one pair with
+# multiple deps.
+#
+# Arguments:
+# depends Dependency pair list.
+#
+# Results:
+# The processed list.
+
+proc compressDeps {depends} {
+ array set compressed [list]
+
+ foreach pair $depends {
+ lappend compressed([lindex $pair 0]) [lindex $pair 1]
+ }
+
+ foreach n [array names compressed] {
+ lappend result [list $n $compressed($n)]
+ }
+
+ return $result
+}
+
+# addSearchPath --
+#
+# Adds a new set of path and replacement string to the global list.
+#
+# Arguments:
+# newPathInfo comma seperated path and replacement string
+#
+# Results:
+# None.
+
+proc addSearchPath {newPathInfo} {
+ global srcPathList srcPathReplaceList
+
+ set infoList [split $newPathInfo ,]
+ lappend srcPathList [file normalize [lindex $infoList 0]]
+ lappend srcPathReplaceList [lindex $infoList 1]
+}
+
+
+# displayUsage --
+#
+# Displays usage to stderr
+#
+# Arguments:
+# none.
+#
+# Results:
+# None.
+
+proc displayUsage {} {
+ puts stderr "mkdepend.tcl \[options\] genericDir,macroName compatDir,macroName platformDir,macroName"
+}
+
+# readInputListFile --
+#
+# Open and read the object file list.
+#
+# Arguments:
+# objectListFile - name of the file to open.
+#
+# Results:
+# None.
+
+proc readInputListFile {objectListFile} {
+ global srcFileList srcPathList
+ set f [open $objectListFile r]
+
+ # this probably isn't bullet-proof.
+ set fl [split [read $f]]
+ close $f
+
+ foreach fname $fl {
+ # compiled .res resource files should be ignored.
+ if {[file extension $fname] ne ".obj"} {continue}
+
+ # just filename without path or extension.
+ set baseName [file rootname [file tail $fname]]
+
+ foreach path $srcPathList {
+ if {[file exist [file join $path ${baseName}.c]]} {
+ lappend srcFileList [file join $path ${baseName}.c]
+ } elseif {[file exist [file join $path ${baseName}.cpp]]} {
+ lappend srcFileList [file join $path ${baseName}.cpp]
+ } else {
+ # ignore it
+ }
+ }
+ }
+}
+
+# main --
+#
+# The main procedure of this script.
+#
+# Arguments:
+# none.
+#
+# Results:
+# None.
+
+proc main {} {
+ global argc argv mode mode_data srcFileList srcPathList excludes
+ global remove_prefix target_prefix output env
+
+ set srcPathList [list]
+ set srcFileList [list]
+
+ if {$argc == 1} {displayUsage}
+
+ # Parse mkdepend input
+ for {set i 0} {$i < [llength $argv]} {incr i} {
+ switch -glob -- [set arg [lindex $argv $i]] {
+ -vc32 {
+ set mode vc32
+ }
+ -bc32 {
+ set mode bc32
+ }
+ -wc32 {
+ set mode wc32
+ }
+ -lc32 {
+ set mode lc32
+ }
+ -mgw32 {
+ set mode mgw32
+ }
+ -passthru:* {
+ puts stderr [set passthru [string range $arg 10 end]]
+ }
+ -out:* {
+ openOutput [string range $arg 5 end]
+ }
+ @* {
+ readInputListFile [string range $arg 1 end]
+ }
+ -? -
+ -help -
+ --help {
+ displayUsage
+ exit 1
+ }
+ default {
+ if {![info exist mode]} {
+ puts stderr "mode not set"
+ displayUsage
+ }
+ addSearchPath $arg
+ }
+ }
+ }
+
+ # Execute the CPP command and parse output
+
+ foreach srcFile $srcFileList {
+ set command "$mode_data($mode) $passthru \"$srcFile\""
+ set input [open |$command r]
+
+ set depends [readDepends $input]
+ set depends [filterExcludes $depends $excludes]
+ set depends [rebaseFiles $depends]
+ set depends [compressDeps $depends]
+ set depends [lsort -index 0 $depends]
+ writeDepends $output $depends
+ }
+
+ closeOutput
+}
+
+# kick it up.
+main
diff --git a/win/makefile.vc b/win/makefile.vc
index ebfdd24..e729b6a 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -12,7 +12,7 @@
# Copyright (c) 2001-2004 David Gravereaux.
#
#------------------------------------------------------------------------------
-# RCS: @(#) $Id: makefile.vc,v 1.169 2007/10/12 14:09:46 patthoyts Exp $
+# RCS: @(#) $Id: makefile.vc,v 1.170 2007/10/14 07:04:29 davygrvy Exp $
#------------------------------------------------------------------------------
# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
@@ -627,23 +627,6 @@ gentommath_h:
!endif
#---------------------------------------------------------------------
-# Generate the makefile dependencies.
-#---------------------------------------------------------------------
-
-depend:
-!if !exist($(TCLSH))
- @echo Build tclsh first!
-!else
- $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
- -passthru:"-DBUILD_tcl $(TCL_INCLUDES:"="")" $(GENERICDIR) \
- $(COMPATDIR) $(WINDIR) @<<
-$(TCLOBJS)
-<<
-!endif
-
-#" for emacs font-locking.
-
-#---------------------------------------------------------------------
# Build the windows help file.
#---------------------------------------------------------------------
@@ -773,11 +756,13 @@ $(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in
<<
+#---------------------------------------------------------------------
# The following target generates the file generic/tclDate.c
# from the yacc grammar found in generic/tclGetDate.y. This is
# only run by hand as yacc is not available in all environments.
# The name of the .c file is different than the name of the .y file
# so that make doesn't try to automatically regenerate the .c file.
+#---------------------------------------------------------------------
gendate:
bison --output-file=$(GENERICDIR)/tclDate.c \
@@ -841,12 +826,31 @@ $(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c
### The following objects are part of the stub library and should not
-### be built as DLL objects. -Zl is used to avoid a dependancy on any
+### be built as DLL objects. -Zl is used to avoid a dependency on any
### specific C run-time.
$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c
$(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $?
+#---------------------------------------------------------------------
+# Generate the source dependencies. Having dependency rules will
+# improve incrimental build accuracy without having to resort to a
+# full rebuild just because some non-global header file like tclCompile.h
+# was changed. These rules aren't needed when building from scratch.
+#---------------------------------------------------------------------
+
+depend:
+!if !exist($(TCLSH))
+ @echo Build tclsh first!
+!else
+ $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
+ -passthru:"-DBUILD_tcl $(TCL_INCLUDES:"=""")" $(GENERICDIR),$$(GENERICDIR) \
+ $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<<
+$(TCLOBJS)
+<<
+!endif
+
+#" emacs fix
#---------------------------------------------------------------------
# Dependency rules