This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

producing dependencies for make and cl.exe


Hi,

i develop an application under w2k.  as i usually prefer commandline
tools over gui i use cygwin and gnu make with the ms commandline tools
( i couldn't get sourcenavigator to produce suitable makefiles
although i wrote a new toolchain ).  the only difficulty was to
produce the dependencies.  since i saw several people asking for a way
to produce dependcies for use with make and cl.exe but no suitable
answers i decided to send in a patch against mkdepend.tsh, a
tcl-script from Nat Pryce.  it can be found under

http://www.doc.ic.ac.uk/~np2/software/download/mkdepend.tar.gz

but isn't usable by make as is.  you find my patch at the end of
this mail ( use option -y ). in my makefiles i add the following
macros and pattern rule:

DEP		= cygtclsh80.exe mkdepend.tcl
DEPFLAGS	= -y -- $(CPPDEFINES) $(CPPINCLUDES)

%.d: %.cpp
	set -e; $(DEP) -n $(DEPFLAGS) $< \
	| sed -e 's/\($*\)\.obj[ :]*/\1.obj $@ : /g' > $@; \
        [ -s $@ ] || rm -f $@

and include the dependencies with

include $(sources:.cpp=.d)

( Obviously you have to have a makefile variable "sources" for this to
work.  the procedure is described in the info node for gcc or make,
esp. the explanation of the the gcc commandline swith -MD )


Beware:

- it works for me.  i have no idea what happens within different
  environments. 

- the performance of the make process is a catastrophy if dependencies
  have to be built.

- i would be glad if it's useful for somebody; otherwise sorry for the
  bandwidth used by this offtopic mail.

if you have improvments please drop me a patch.



the patch:
----------------------------------------------------------
*** mkdepend.tsh	Mon Sep  7 16:04:04 1998
--- mkdepend.tcl	Fri Apr 20 14:36:50 2001
***************
*** 32,39 ****
  set output stdout
  set verbose 0
! if [info exists env(INCLUDE)] {
!     set excludes [split [string trim $env(INCLUDE) ";"] ";"]
  } else {
!     set excludes {}
  }
  
--- 32,47 ----
  set output stdout
  set verbose 0
! set cygwin 0
! # don't know about macintosh platform; not even if the following filename is valid
! set dumpbin "./dumpbin.mkdepend"
! set nodfltx 0
! set excludes {}
! 
! if { $tcl_platform(platform) == "windows" } {
!     set dumpbin "./NUL"
  } else {
!     if { $tcl_platform(platform) == "unix" } {
!         set dumpbin "/dev/null"
!     }
  }
  
***************
*** 99,102 ****
--- 107,143 ----
  }
  
+ proc writeDependsCygwin {out depends} {
+     array set deps {}
+     set limit 50
+ 
+ # construct dependency list
+     foreach pair $depends {
+         set index [lindex $pair 0]
+         set str [exec cygpath -u [lindex $pair 1]]
+         regsub -all -- { } "$str" {\ } str
+ #          puts $out "Dependency after cygpath and regsub: $str"
+         if [llength [array get deps $index]] {
+             lappend deps($index) "$str"
+         } else {
+             set deps($index) [list "$str"]
+         }
+ #          puts $out "[lindex $pair 0]: \"[lindex $pair 1]\""
+ #          puts $out "Array deps($index) => $deps($index)"
+     }
+     foreach el [array names deps] {
+         set len 0
+         puts -nonewline $out "$el : "
+         foreach d $deps($el) {
+             if [expr $len > $limit] {
+                 puts -nonewline $out "\\\n\t"
+                 set len 0
+             }
+             set len [expr $len + [string length $d]]
+             puts -nonewline $out "$d "
+         }
+         puts $out ""
+     }
+ }
+ 
  proc stringStartsWith {str prefix} {
      set front [string range $str 0 [expr {[string length $prefix] - 1}]]
***************
*** 168,171 ****
--- 209,216 ----
      puts stdout "\t\tSpecifies the command used to run the C preprocessor"
      puts stdout "\t\t(default = \"cl /nologo /E\")."
+ 
+     puts stdout "\t\[-n | --no-default-excludes\]"
+     puts stdout "\t\tDo NOT use INCLUDE environment variable as default exclude prefix"
+     puts stdout "\t\tsee -x below."
      
      puts stdout "\t\[-o | --output\] <filename>"
***************
*** 194,197 ****
--- 239,246 ----
      puts stdout "\t\t(default = the contents of the INCLUDE environment variable)."
      
+     puts stdout "\t\[-y | --cygwin\]"
+     puts stdout "\t\tOutput is being formatted as expected by GNU make and cygwin."
+     puts stdout "\t\tUse only with M$ preprocessor ( see -c above )!"
+     
      puts stdout "\t\[-? | --help\]"
      puts stdout "\t\tShows this message and performs no further processing."
***************
*** 215,218 ****
--- 264,270 ----
                  set cpp_cmd [getArg $argv [incr i]]
              }
+             -n - --no-default-excludes {
+                 set nodfltx 1
+             }
              -s - --target-suffix {
                  set target_suffix [getArg $argv [incr i]]
***************
*** 230,233 ****
--- 282,288 ----
                  lappend excludes [getArg $argv [incr i]]
              }
+             -y - --cygwin {
+                 set cygwin 1
+             }
              -v - --verbose {
                  set verbose 1
***************
*** 235,238 ****
--- 290,294 ----
              -? - --help {
                  showHelp
+                 exit 0
              }
              default {
***************
*** 241,244 ****
--- 297,308 ----
          }
      }
+ 
+     if !$nodfltx {
+         if [info exists env(INCLUDE)] {
+             set excludes [split [string trim $env(INCLUDE) ";"] ";"]
+         }
+     }
+ 
+ 
      
      # Collect CPP options and source files
***************
*** 250,256 ****
      # Execute CPP command and parse output
  
! 	regsub -all -- {\\} "${cpp_cmd}${cpp_args}" {/} command
      if [catch {
!         set input [open "| ${command}" r]
      } error_msg] {
          puts stderr "failed to run C preprocessor: $error_msg"
--- 314,320 ----
      # Execute CPP command and parse output
  
!     regsub -all -- {\\} "${cpp_cmd}${cpp_args}" {/} command
      if [catch {
!         set input [open "| ${command} 2>$dumpbin" r]
      } error_msg] {
          puts stderr "failed to run C preprocessor: $error_msg"
***************
*** 258,266 ****
      }
      set depends [readDepends $input]
      set depends [filterExcludes $depends $excludes]
      set depends [rebaseTargets $depends $remove_prefix $target_prefix]
!     set depends [lsort -index 0 $depends]
!     writeDepends $output $depends
!     #close $input
      
      closeOutput
--- 322,337 ----
      }
      set depends [readDepends $input]
+ 
+     close $input
+     
      set depends [filterExcludes $depends $excludes]
      set depends [rebaseTargets $depends $remove_prefix $target_prefix]
!     
!     if $cygwin {
!         writeDependsCygwin $output $depends
!     } else {
!         set depends [lsort -index 0 $depends]
!         writeDepends $output $depends
!     }
      
      closeOutput


--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]