diff -u build.conf build.conf
--- build.conf	(working copy)
+++ build.conf	(working copy)
@@ -113,7 +113,7 @@
 path = subversion/libsvn_client
 libs = libsvn_wc libsvn_ra libsvn_delta libsvn_diff libsvn_subr aprutil apriconv apr
 install = lib
-msvc-static = yes
+msvc-export = svn_client.h
 
 # Routines for binary diffing and tree-deltas
 [libsvn_delta]
@@ -129,7 +129,7 @@
 path = subversion/libsvn_diff
 libs = libsvn_subr aprutil apriconv apr
 install = lib
-msvc-static = yes
+msvc-export = svn_diff.h
 
 # The repository filesystem library
 [libsvn_fs]
@@ -138,7 +138,7 @@
 sources = *.c bdb/*.c util/*.c
 install = fs-lib
 libs = libsvn_delta libsvn_subr aprutil apriconv bdb apr
-msvc-static = yes
+msvc-export = svn_fs.h
 
 # General API for accessing repositories
 [libsvn_ra]
@@ -148,7 +148,7 @@
 # conditionally add more dependencies
 add-deps = $(SVN_RA_LIB_DEPS)
 install = lib
-msvc-static = yes
+msvc-export = svn_ra.h
 
 # Accessing repositories via DAV
 [libsvn_ra_dav]
@@ -180,7 +180,7 @@
 path = subversion/libsvn_repos
 install = fs-lib
 libs = libsvn_fs libsvn_delta libsvn_subr aprutil apriconv apr
-msvc-static = yes
+msvc-export = svn_repos.h
 
 # Low-level grab bag of utilities
 [libsvn_subr]
@@ -189,7 +189,7 @@
 path = subversion/libsvn_subr
 libs =  aprutil apriconv apr xml
 msvc-libs = advapi32.lib shfolder.lib
-msvc-static = yes
+msvc-export = svn_auth.h svn_base64.h svn_cmdline.h svn_config.h svn_error.h svn_hash.h svn_io.h svn_md5.h svn_opt.h svn_path.h svn_pools.h svn_props.h svn_quoprint.h svn_sorts.h svn_string.h svn_subst.h svn_time.h svn_types.h svn_utf.h svn_xml.h
 
 # Working copy management lib
 [libsvn_wc]
@@ -197,7 +197,7 @@
 path = subversion/libsvn_wc
 libs = libsvn_delta libsvn_subr libsvn_diff aprutil apriconv apr
 install = lib
-msvc-static = yes
+msvc-export = svn_wc.h
 
 # Subversion plugin for Apache's mod_dav
 [mod_dav_svn]
diff -u build/generator/gen_base.py build/generator/gen_base.py
--- build/generator/gen_base.py	(working copy)
+++ build/generator/gen_base.py	(working copy)
@@ -429,6 +429,7 @@
 
     self.msvc_static = options.get('msvc-static') == 'yes' # is a static lib
     self.msvc_fake = options.get('msvc-fake') == 'yes' # has fake target
+    self.msvc_export = string.split(options.get('msvc-export', ''))
 
 class TargetApacheMod(TargetLib):
 
diff -u build/generator/gen_win.py build/generator/gen_win.py
--- build/generator/gen_win.py	(working copy)
+++ build/generator/gen_win.py	(working copy)
@@ -266,7 +266,20 @@
         if quote_path and '-' in rsrc:
           rsrc = '"%s"' % rsrc
         sources.append(ProjectItem(path=rsrc, reldir=reldir, user_deps=[],
-                                   swig_language=None))
+                                   custom_build=None))
+    
+    if isinstance(target, gen_base.TargetLib) and target.msvc_export:
+      dsrc = rootpath + "\\" + target.path + "\\" + target.name + ".def"
+      gsrc = rootpath + "\\build\\generator\\extractor.py"
+      deps = []
+      for header in target.msvc_export:
+        deps.append(rootpath + "\\subversion\\include\\" + header)
+        
+      sources.append(ProjectItem(path=dsrc, reldir=None, custom_build=None,
+                                 user_deps=[]))
+
+      sources.append(ProjectItem(path=gsrc, reldir=None, custom_build="defgen",
+                                 user_deps=deps, custom_target=dsrc))
 
     if isinstance(target, gen_base.TargetSWIG):
       for obj in self.graph.get_sources(gen_base.DT_LINK, target.name):
@@ -277,9 +290,12 @@
 
               if isinstance(target, gen_base.TargetSWIGRuntime):
                 bsrc = rootpath + "\\build\\win32\\gen_swig_runtime.py"
-                sources.append(ProjectItem(path=bsrc, reldir=None, user_deps=[],
-                                           swig_language=target.lang,
-                                           swig_target=csrc, swig_output=None))
+                sources.append(ProjectItem(path=bsrc, reldir=None, 
+                                           custom_build="swigrun", 
+                                           custom_target=csrc,
+                                           user_deps=[],
+                                           swig_language=target.lang, 
+                                           swig_output=None))
                 continue
 
               # output path passed to swig has to use forward slashes,
@@ -299,10 +315,12 @@
                   continue
 
                 sources.append(ProjectItem(path=isrc, reldir=None,
+                                           custom_build="swiglib",
+                                           custom_target=csrc,
                                            user_deps=user_deps,
                                            swig_language=target.lang,
-                                           swig_target=csrc, swig_output=cout))
-        
+                                           swig_output=cout))
+
     sources.sort(lambda x, y: cmp(x.path, y.path))
     return sources
   
only in patch2:
unchanged:
--- build/generator/msvc_dsp.ezt	(revision 7386)
+++ build/generator/msvc_dsp.ezt	(working copy)
@@ -63,16 +63,17 @@
 [end][end]
 !ENDIF
 [end][for sources.user_deps][if-index sources.user_deps first]
-USERDEP__=[else] [end]"[sources.user_deps]"[end][if-any sources.swig_language]
+USERDEP__=[else] [end]"[sources.user_deps]"[end][if-any sources.custom_build]
 
 # Begin Custom Build
 
 InputPath=[sources.path]
 
-[sources.swig_target] : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-[if-any sources.swig_output]	swig -c -[sources.swig_language][for includes] -I"[includes]"[end] -o [sources.swig_output] $(InputPath)
-[else]	python $(InputPath) [sources.swig_language] [sources.swig_target]
-[end]
+[sources.custom_target] : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+[is sources.custom_build "swiglib"]	swig -c -[sources.swig_language][for includes] -I"[includes]"[end] -o [sources.swig_output] $(InputPath)
+[else][is sources.custom_build "swigrun"]	python $(InputPath) [sources.swig_language] [sources.custom_target]
+[else][is sources.custom_build "defgen"]	python $(InputPath)[for sources.user_deps] [sources.user_deps][end] > [sources.custom_target]
+[end][end][end]
 # End Custom Build
 
 [end]
only in patch2:
unchanged:
--- build/generator/extractor.py	(revision 7386)
+++ build/generator/extractor.py	(working copy)
@@ -29,21 +29,13 @@
 # or
 #    void svn_foo_bar (args)
 #
-# The space is optional, as some of our headers (currently) omit the
-# space before the open parenthesis.
-#
-_funcs = re.compile('^(?:(svn_[a-z_0-9]+)|[a-z].*?(svn_[a-z_0-9]+)) ?\(')
+_funcs = re.compile(r'^(?:(?:(?:\w+|\*) )+\*?)?((?:svn|apr)_[a-z_0-9]+)\s*\(', re.M)
 
 def extract_funcs(fname):
   funcs = [ ]
-  for line in open(fname).readlines():
-    match = _funcs.match(line)
-    if match:
-      name = match.group(1) or match.group(2)
-      if not name:
-        print 'WTF?', match.groups()
-      elif name not in _filter_names:
-        funcs.append(name)
+  for name in _funcs.findall(open(fname).read()):
+    if name not in _filter_names:
+      funcs.append(name)
   return funcs
 
 _filter_names = [
@@ -51,85 +43,10 @@
                     # function declaration for svn_boolean_t
   ]
 
-def scan_headers(include_dir):
-  "Return a dictionary mapping library basenames to a list of func names."
-
-  libs = { }
-
-  for header, lib in headers_to_libraries.items():
-    if not lib:
-      continue
-
-    fname = os.path.join(include_dir, 'svn_%s.h' % header)
-    funcs = extract_funcs(fname)
-
-    libname = 'libsvn_%s' % lib
-    if libs.has_key(libname):
-      libs[libname].extend(funcs)
-    else:
-      libs[libname] = funcs
-
-  ### do some cleanup tweaks
-
-  return libs
-
-#
-# Map header names to the libraries which contain the named functions
-#
-# Note: we could also use the secondary prefix (e.g. FOO in svn_FOO_), but
-# there are more of those than headers.
-#
-headers_to_libraries = {
-  'auth' : 'subr',
-  'base64' : 'subr',
-  'client' : 'client',
-  'config' : 'subr',
-  'dav' : None,
-  'delta' : 'delta',
-  'diff' : 'diff',
-  'error' : 'subr',
-  'error_codes' : None,
-  'fs' : 'fs',
-  'hash' : 'subr',
-  'io' : 'subr',
-  'md5' : 'subr',
-  'opt' : 'subr',
-  'path' : 'subr',
-  'pools' : 'subr',
-  'props' : 'subr',
-  'quoprint' : 'subr',
-  'ra' : 'ra',
-  'ra_svn' : 'ra_svn',
-  'repos' : 'repos',
-  'sorts' : 'subr',
-  'string' : 'subr',
-  'subst' : 'subr',
-  'test' : 'test',  # do we need symbols here? or just always build static?
-  'time' : 'subr',
-  'types' : 'subr',
-  'utf' : 'subr',
-  'version' : None,
-  'wc' : 'wc',
-  'xml' : 'subr',
-  }
-
-
 if __name__ == '__main__':
   # run the extractor over each file mentioned
   import sys
-  if len(sys.argv) == 1:
-    # no header files provided. assume we're in the include dir and extract
-    # all the function names
-    libs = scan_headers('.')
-    for lib, funcs in libs.items():
-      for f in funcs:
-        print lib, f
-
-    # compare the above output to the actual libraries using:
-    # for f in libsvn_*-1.so ; do b="`echo $f | sed 's/-.*//'`" ; nm $f | sed -n -e '/__/d' -e "/T svn_/s/.* T/$b/p" ; done
-
-  else:
-    for fname in sys.argv[1:]:
-      funcs = extract_funcs(fname)
-      if funcs:
-        print string.join(funcs, '\n')
+  print "EXPORTS"
+  for fname in sys.argv[1:]:
+    for func in extract_funcs(fname):
+      print func
only in patch2:
unchanged:
--- build/generator/vcnet_vcproj.ezt	(revision 7386)
+++ build/generator/vcnet_vcproj.ezt	(working copy)
@@ -90,15 +90,16 @@
 		</File>[end]
 [for sources]		<File
 			RelativePath="[sources.path]">
-[if-any sources.swig_language][for configs]
+[if-any sources.custom_build][for configs]
 			<FileConfiguration
 				Name="[configs.name]|Win32">
 				<Tool
 					Name="VCCustomBuildTool"
-					[if-any sources.swig_output]CommandLine="swig -c -[sources.swig_language][for includes] -I&quot;[includes]&quot;[end] -o &quot;[sources.swig_output]&quot; $(InputPath)"
-					[else]CommandLine="python $(InputPath) [sources.swig_language] [sources.swig_target]"
-					[end]AdditionalDependencies="[for sources.user_deps]&quot;[sources.user_deps]&quot;;[end]"
-					Outputs="&quot;[sources.swig_target]&quot;"/>
+					[is sources.custom_build "swiglib"]CommandLine="swig -c -[sources.swig_language][for includes] -I&quot;[includes]&quot;[end] -o &quot;[sources.swig_output]&quot; $(InputPath)"
+					[else][is sources.custom_build "swigrun"]CommandLine="python $(InputPath) [sources.swig_language] [sources.custom_target]"
+					[else][is sources.custom_build "defgen"]CommandLine="python $(InputPath)[for sources.user_deps] [sources.user_deps][end] &gt; [sources.custom_target]"
+					[end][end][end]AdditionalDependencies="[for sources.user_deps]&quot;[sources.user_deps]&quot;;[end]"
+					Outputs="&quot;[sources.custom_target]&quot;"/>
 			</FileConfiguration>
 [end][end]
 [if-any sources.reldir][for configs]
only in patch2:
unchanged:
--- subversion/include/svn_md5.h	(revision 7386)
+++ subversion/include/svn_md5.h	(working copy)
@@ -34,7 +34,7 @@
 
 
 /** The MD5 digest for the empty string. */
-extern const unsigned char svn_md5_empty_string_digest[];
+const unsigned char *svn_md5_empty_string_digest();
 
 
 /** Return the hex representation of @a digest, which must be
only in patch2:
unchanged:
--- subversion/libsvn_fs/reps-strings.c	(revision 7386)
+++ subversion/libsvn_fs/reps-strings.c	(working copy)
@@ -524,7 +524,7 @@
      we were provided was not mutable.  So, let's make a new
      representation and return its key to the caller. */
   SVN_ERR (svn_fs__bdb_string_append (fs, &new_str, 0, NULL, trail));
-  rep = make_fulltext_rep (new_str, txn_id, svn_md5_empty_string_digest,
+  rep = make_fulltext_rep (new_str, txn_id, svn_md5_empty_string_digest (),
                            trail->pool);
   SVN_ERR (svn_fs__bdb_write_new_rep (new_rep_key, fs, rep, trail));
 
@@ -1164,7 +1164,7 @@
   if (str_key && *str_key)
     {
       SVN_ERR (svn_fs__bdb_string_clear (fs, str_key, trail));
-      memcpy (rep->checksum, svn_md5_empty_string_digest, MD5_DIGESTSIZE);
+      memcpy (rep->checksum, svn_md5_empty_string_digest (), MD5_DIGESTSIZE);
       SVN_ERR (svn_fs__bdb_write_rep (fs, rep_key, rep, trail));
     }
   return SVN_NO_ERROR;
only in patch2:
unchanged:
--- subversion/libsvn_subr/md5.c	(revision 7386)
+++ subversion/libsvn_subr/md5.c	(working copy)
@@ -22,12 +22,15 @@
 
 
 /* The MD5 digest for the empty string. */
-const unsigned char svn_md5_empty_string_digest[] = {
+static const unsigned char svn_md5__empty_string_digest[] = {
   212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126
 };
 
+const unsigned char * svn_md5_empty_string_digest()
+{
+  return svn_md5__empty_string_digest;
+}
 
-
 const char *
 svn_md5_digest_to_cstring (const unsigned char digest[], apr_pool_t *pool)
 {

