[Distutils] patch to pybsddb's setup.py for more cmd-line options

Zooko Zooko <zooko@zooko.com>
Thu Jan 10 12:05:02 2002


Folks:

Here is appended a patch against pybsddb's setup.py so that you can pass in 
cmd-line options such as "--extra_link_args=-nodefaultlibs" and they will get 
passed to distutils's `setup()' function.

I tried to make it backwards compatible, but I only tested it on Linux, in my 
particular application.  The application is Mojo Nation [1].  The patch is in 
Mojo Nation cvs, here: [2].  The makefile which applies the patch and then 
passes some extra cmd-line arguments is here: [3].  (Search in the makefile 
text for the string "pybsddb".)

Regards,

Zooko

[1] http://mojonation.net/
[2] http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mojonation/extsrc/bsddb3-3.3.0-moreargs.patch?rev=HEAD&content-type=text/vnd.viewcvs-markup
[3] http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mojonation/evil/GNUmakefile?rev=HEAD&content-type=text/vnd.viewcvs-markup

---
                 zooko.com
Security and Distributed Systems Engineering
---

------- begin appended patch
--- setup.py-orig	Wed Jan  9 11:30:05 2002
+++ setup.py	Wed Jan  9 11:30:54 2002
@@ -2,7 +2,10 @@
 #----------------------------------------------------------------------
 # Setup script for the bsddb3 package
 
-import sys, os, string, glob, re
+# hacked by Zooko to accept cmdline args and use them.  For details see:
+# http://mail.python.org/pipermail/distutils-sig/2001-October/002626.html
+
+import sys, os, string, glob, re, getopt
 from distutils.core     import setup, Extension
 from distutils.dep_util import newer
 
@@ -12,33 +15,91 @@
 
 debug = '--debug' in sys.argv or '-g' in sys.argv
 
-lflags_arg = []
+global include_dirs, library_dirs, libraries, define_macros, extra_compile_args, extra_link_args, extra_objects
+
+include_dirs = []
+library_dirs = []
+libraries = []
+define_macros = []
+extra_compile_args = []
+extra_link_args = []
+extra_objects = []
+
+def snarf_opts():
+    global include_dirs, library_dirs, libraries, define_macros, extra_compile_args, extra_link_args, extra_objects
+    def usage(le):
+        print "Hey -- this setup.py script accepts opts like this: getopt.getopt(sys.argv[1:], \"l:a:\", [\"libraries=\", \"extra_link_args=\"]); libraries and args are space-separated (but need to be passed in as one bash word, i.e. the entire space separated list of libraries e.g. --libraries=\"foo bar spam\")"
+        print "got error: %s: %s" % (le.__class__, `le.args`,)
+
+    # See if there are some special library flags passed in as arguments.
+    shortopts="l:a:I:c:L:o:"
+    longopts=['libraries=', 'extra_link_args=', 'include_dirs=', 'extra_compile_args=', 'library_dirs=', 'extra_objects=', 'berkeley-db=', 'lflags=', 'libs=',]
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
+    except getopt.GetoptError, le:
+        # print help information and exit:
+        usage(le)
+        sys.exit(2)
+
+    # Any options that we don't process get added to `newargv' to be passed on.
+    newargv = []
+
+    for o, a in opts:
+        if o in ('-l', '--libraries',):
+            libraries.extend(string.split(a))
+        elif o in ('-a', '--extra_link_args',):
+            extra_link_args.extend(string.split(a))
+        elif o in ('-I', '--include_dirs',):
+            include_dirs.extend(string.split(a))
+        elif o in ('-c', '--extra_compile_args',):
+            extra_compile_args.extend(string.split(a))
+        elif o in ('-L', '--library_dirs',):
+            library_dirs.extend(string.split(a))
+        elif o in ('-o', '--extra_objects',):
+            extra_objects.extend(string.split(a))
+
+        ### begin options defined by `bsddb3-3.3.0/setup.py' before Zooko touched it.  Zooko changed the code to parse these with getopt instead of with string.find.
+        elif o == '--berkeley-db':
+            global BERKELEYDB_DIR
+            BERKELEYDB_DIR = a
+        elif o == '--lflags':
+            global LFLAGS
+            LFLAGS = a
+        elif o == '--libs':
+            global LIBS
+            LIBS = a
+        ### end options defined by `bsddb3-3.3.0/setup.py' before Zooko touched it.  Zooko changed the code to parse these with getopt instead of with string.find.
+
+        else:
+            assert o[0] == '-'
+            if o[1] == '-':
+                if a:
+                    newargv.append(o + ' ' + a)
+                else:
+                    newargv.append(o)
+            else:
+                if a:
+                    newargv.append(o+a)
+                else:
+                    newargv.append(o)
 
+    sys.argv[1:] = newargv
+    sys.argv.extend(args)
 
 if os.name == 'posix':
     # Allow setting the DB dir and additional link flags either in
     # the environment or on the command line.
     # First check the environment...
+    global BERKELEYDB_DIR, LFLAGS, LIBS
     BERKELEYDB_DIR = os.environ.get('BERKELEYDB_DIR', '')
     LFLAGS = os.environ.get('LFLAGS', [])
     LIBS = os.environ.get('LIBS', [])
 
     # ...then the command line.
-    # Handle --berkeley-db=[PATH] and --lflags=[FLAGS]
-    args = sys.argv[:]
-    for arg in args:
-        if string.find(arg, '--berkeley-db=') == 0:
-            BERKELEYDB_DIR = string.split(arg, '=')[1]
-            sys.argv.remove(arg)
-        elif string.find(arg, '--lflags=') == 0:
-            LFLAGS = string.split(string.split(arg, '=')[1])
-            sys.argv.remove(arg)
-        elif string.find(arg, '--libs=') == 0:
-            LIBS = string.split(string.split(arg, '=')[1])
-            sys.argv.remove(arg)
+    snarf_opts()
 
     if LFLAGS or LIBS:
-        lflags_arg = LFLAGS + LIBS
+        extra_links_args.extend((LFLAGS, LIBS,))
 
     # If we were not told where it is, go looking for it.
     incdir = libdir = None
@@ -60,7 +121,6 @@
             else:
                 incdir = None
 
-
     if not BERKELEYDB_DIR and not incdir and not libdir:
         print "Can't find a local db3 installation."
         sys.exit(1)
@@ -69,9 +129,7 @@
     if not incdir: incdir = os.path.join(BERKELEYDB_DIR, 'include')
     if not libdir: libdir = os.path.join(BERKELEYDB_DIR, 'lib')
     if not '-ldb' in LIBS:
-        libname = ['db']
-    else:
-        libname = []
+        libraries.append('db')
     utils = []
 
 
@@ -108,6 +166,7 @@
 
 
 elif os.name == 'nt':
+    snarf_opts()
 
     # The default build of Berkeley DB for windows just leaves
     # everything in the build dirs in the db source tree.  That means
@@ -142,9 +201,9 @@
     print 'Detected BerkeleyDB version', ver, 'from db.h'
 
     if debug:
-        libname = ['libdb%ssd' % ver]     # Debug, static
+        libraries.append('libdb%ssd' % ver)     # Debug, static
     else:
-        libname = ['libdb%ss' % ver]      # Release, static
+        libraries.append('libdb%ss' % ver)      # Release, static
     utils = [("bsddb3/utils",
               ["db/bin/db_archive.exe",
                "db/bin/db_checkpoint.exe",
@@ -168,6 +227,9 @@
     open('src/version.h', 'w').write('#define PY_BSDDB_VERSION "%s"\n' % VERSION)
 
 
+include_dirs.append(incdir)
+library_dirs.append(libdir)
+
 # do the actual build, install, whatever...
 setup(name = 'bsddb3',
       version = VERSION,
@@ -192,10 +254,13 @@
       packages = ['bsddb3'],
       ext_modules = [Extension('bsddb3._db',
                                sources = ['src/_db.c'],
-                               include_dirs = [ incdir ],
-                               library_dirs = [ libdir ],
-                               libraries = libname,
-                               extra_link_args = lflags_arg,
+                               include_dirs = include_dirs,
+                               define_macros = define_macros,
+                               extra_compile_args = extra_compile_args,
+                               extra_link_args = extra_link_args,
+                               extra_objects = extra_objects,
+                               library_dirs = library_dirs,
+                               libraries = libraries,
                                )],
       data_files = utils,
       )