/[thuban]/branches/WIP-pyshapelib-bramz/setup.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/setup.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 671 by bh, Tue Apr 15 18:09:47 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  #  #
# Line 16  __version__ = "$Revision$" Line 16  __version__ = "$Revision$"
16  #  #
17    
18  import os  import os
19    from types import TupleType
20    import glob
21  from distutils.core import setup, Extension, Command  from distutils.core import setup, Extension, Command
22  from distutils.command.install import install  from distutils.command.install import install, INSTALL_SCHEMES, subst_vars
23  from distutils.command.build_py import build_py  from distutils.command.build_py import build_py
24    from distutils.command.bdist_rpm import bdist_rpm
25    from distutils.file_util import write_file
26    from distutils.filelist import FileList
27    from distutils.util import convert_path, change_root
28    
29    from distutils import archive_util, dir_util
30  import distutils  import distutils
 print distutils.__file__  
31    
32  from string import split  from string import split
33  import string  import string
# Line 38  if os.name == "posix": Line 44  if os.name == "posix":
44      proj4_lib = "proj"      proj4_lib = "proj"
45    
46    
47      # You shpuldn't have to modify anything below here      # You shouldn't have to modify anything below here
48      ###################################################################      ###################################################################
49            
50      # The installation prefix (similar to autoconf's --prefix). This is      # The installation prefix (similar to autoconf's --prefix). This is
51      # only the default value, you can override it on the command line      # only the default value, you can override it on the command line
52      # with the install command's --prefix option      # with the install command's --prefix option.
53        #
54        # Note that there's a separate prefix option for the bdist_rpm
55        # command completely independend of this one.
56      prefix = "/usr/local/"      prefix = "/usr/local/"
57    
58        # Whether to create the thubaninit module. You can override this
59        # value on the commandline with the --create-init-module to the
60        # install command.
61        create_init_module = 1
62    
63      # On POSIX-systems we run wxgtk-config to determine the C++-compiler      # On POSIX-systems we run wxgtk-config to determine the C++-compiler
64      # flags      # flags
65      wx_config_script = "wxgtk-config"      wx_config_script = "wx-config"
66      # These lists will be filled automatically below      # These lists will be filled automatically below
67      wx_defs = []      wx_defs = []
68      wx_incdirs = []      wx_incdirs = []
# Line 66  elif os.name == "nt": Line 80  elif os.name == "nt":
80      proj4_libdir =  proj4_prefix      proj4_libdir =  proj4_prefix
81      proj4_lib = "proj_i"      proj4_lib = "proj_i"
82    
83        # Define include and lib directories for wxWindows and
84        wx_prefix = r"D:\wx240"
85        wx_inc = [os.path.join(wx_prefix, 'lib', 'mswdllh'),
86                  os.path.join(wx_prefix, "include")]
87        wx_lib = [os.path.join(wx_prefix, "lib")]
88    
89    
90      #      #
91      # Unless you use a wxPython version other than 2.3.1, you probably      # Unless you use a wxPython version other than 2.4.0, you probably
92      # shouldn't have to modify anything below here      # shouldn't have to modify anything below here
93      ##################################################################      ##################################################################
94            
# Line 76  elif os.name == "nt": Line 97  elif os.name == "nt":
97      # the command line with the install command's --prefix option      # the command line with the install command's --prefix option
98      prefix = r"install"      prefix = r"install"
99    
100        # Whether to create the thubaninit module. You can override this
101        # value on the commandline with the --create-init-module to the
102        # install command. By default we don't create it under NT because we
103        # most often run install only as part of bdist_inno where we can't
104        # really create because it needs information only known at install
105        # time.
106        create_init_module = 0
107    
108      # There doesn't seem to be an easy way to get at the wx compiler      # There doesn't seem to be an easy way to get at the wx compiler
109      # flags, so we define them here. These flags work for us with      # flags, so we define them here. These flags work for us with
110      # wxPython 2.3.1. They may have to be modified for other versions.      # wxPython 2.3.1. They may have to be modified for other versions.
# Line 83  elif os.name == "nt": Line 112  elif os.name == "nt":
112      # there's no config script.      # there's no config script.
113      wx_config_script = ""      wx_config_script = ""
114            
     # so we just define the flags manually  
     wx_prefix = r"D:\wx230"  
     wx_inc =  os.path.join(wx_prefix, "include")  
     wx_lib =  os.path.join(wx_prefix, "lib")  
115      # the values of wx_defs and wx_libs. copied from the wxPython      # the values of wx_defs and wx_libs. copied from the wxPython
116      # setup.py      # setup.py
117      wx_defs = [ ('WIN32', None),        # Some of these are no longer      wx_defs = [ ('WIN32', None),        # Some of these are no longer
# Line 105  elif os.name == "nt": Line 130  elif os.name == "nt":
130                  ('WXP_USE_THREAD', '1'),                  ('WXP_USE_THREAD', '1'),
131                  ]                  ]
132            
133      wx_incdirs = [wx_inc]      wx_incdirs = wx_inc
134      wx_libdirs = [wx_lib]      wx_libdirs = wx_lib
135      wx_libs = ["wx23_1h"]      wx_libs = ["wxmsw24h"]
136    
137      wx_libs = wx_libs + ['kernel32', 'user32', 'gdi32', 'comdlg32',      wx_libs = wx_libs + ['kernel32', 'user32', 'gdi32', 'comdlg32',
138                           'winspool', 'winmm', 'shell32', 'oldnames',                           'winspool', 'winmm', 'shell32', 'oldnames',
139                           'comctl32', 'ctl3d32', 'odbc32', 'ole32', 'oleaut32',                           'comctl32', 'ctl3d32', 'odbc32', 'ole32', 'oleaut32',
# Line 139  def run_script(cmdline): Line 165  def run_script(cmdline):
165    
166    
167  def run_wx_script(command):  def run_wx_script(command):
168      # first, determine the C++ preprocessor flags      # first, determine the C++ preprocessor flags Use --cflags here
169      flags = run_script(command + ' --cxxflags ')      # because it seems that older version don't have --cxxflags and
170        # newer ones return the same result for both
171        flags = run_script(command + ' --cflags ')
172      if flags is None:      if flags is None:
173          return 0          return 0
174      for flag in split(flags):      for flag in split(flags):
# Line 192  py_modules = [] Line 220  py_modules = []
220  #  #
221    
222  extensions.append(Extension("Lib.wxproj",  extensions.append(Extension("Lib.wxproj",
223                              [ext_dir + "/thuban/wxproj.cpp",                              [ext_dir + "/thuban/wxproj.cpp"],
224                               shp_dir + "/shpopen.c"],                              include_dirs = ([shp_dir, proj4_incdir,
225                              include_dirs = [shp_dir, proj4_incdir] +wx_incdirs,                                               ext_dir + "/pyshapelib/"]
226                                                + wx_incdirs),
227                              define_macros = wx_defs,                              define_macros = wx_defs,
228                              library_dirs = [proj4_libdir] + wx_libdirs,                              library_dirs = [proj4_libdir] + wx_libdirs,
229                              libraries = [proj4_lib] + wx_libs))                              libraries = [proj4_lib] + wx_libs))
# Line 205  extensions.append(Extension("Lib.wxproj" Line 234  extensions.append(Extension("Lib.wxproj"
234    
235  extensions.append(Extension("Lib.shapelibc",  extensions.append(Extension("Lib.shapelibc",
236                              [ext_dir + "/pyshapelib/shapelib_wrap.c",                              [ext_dir + "/pyshapelib/shapelib_wrap.c",
237                               shp_dir + "/shpopen.c"],                               shp_dir + "/shpopen.c",
238                                 shp_dir + "/shptree.c"],
239                                include_dirs = [shp_dir]))
240    extensions.append(Extension("Lib.shptree",
241                                [ext_dir + "/pyshapelib/shptreemodule.c"],
242                              include_dirs = [shp_dir]))                              include_dirs = [shp_dir]))
243  extensions.append(Extension("Lib.dbflibc",  extensions.append(Extension("Lib.dbflibc",
244                              [ext_dir + "/pyshapelib/dbflib_wrap.c",                              [ext_dir + "/pyshapelib/dbflib_wrap.c",
# Line 232  py_modules.append(ext_dir + "/pyprojecti Line 265  py_modules.append(ext_dir + "/pyprojecti
265  data_files = []  data_files = []
266    
267  # bitmaps  # bitmaps
268  dir = "Resources/Bitmaps/"  for d, pattern in [("Resources/Bitmaps", "Resources/Bitmaps/*.xpm"),
269  bitmaps = []                     ("Resources/Locale", "Resources/Locale/*/LC_MESSAGES/*.mo")
270  for file in os.listdir(os.path.join("Resources", "Bitmaps")):                     ]:
271      if string.lower(file[-4:]) == ".xpm":      data_files.append((d, glob.glob(pattern)))
         bitmaps.append(dir + file)  
 data_files.append((dir, bitmaps))  
272    
273  #  #
274  #       Command definitions  #       Command definitions
275  #  #
276  # So far distutils are only meant to distribute python extensions, not  # So far distutils are only meant to distribute python extensions, not
277  # complete applications, so we have to redefine a few commands  # complete applications, so we have to redefine a few commands
278    #
279    
280    
281    # Much of the data_dist command is directly copied from the distutils'
282    # sdist command
283    class data_dist(Command):
284    
285        description = "create a data distribution (tarball, zip file, etc.)"
286    
287        user_options = [
288            ('formats=', None,
289             "formats for source distribution (comma-separated list)"),
290            ('keep-temp', 'k',
291             "keep the distribution tree around after creating " +
292             "archive file(s)"),
293            ('dist-dir=', 'd',
294             "directory to put the source distribution archive(s) in "
295             "[default: dist]"),
296            ]
297    
298        boolean_options = ['keep-temp']
299    
300        def initialize_options (self):
301            self.formats = None
302            self.keep_temp = 0
303            self.dist_dir = None
304    
305        def finalize_options (self):
306            self.ensure_string_list('formats')
307            if self.formats is None:
308                self.formats = ["zip"]
309            bad_format = archive_util.check_archive_formats(self.formats)
310            if bad_format:
311                raise DistutilsOptionError, \
312                      "unknown archive format '%s'" % bad_format
313    
314            if self.dist_dir is None:
315                self.dist_dir = "dist"
316    
317    
318        def run(self):
319            # 'filelist' contains the list of files that will make up the
320            # manifest
321            self.filelist = FileList()
322            
323            # Do whatever it takes to get the list of files to process.
324            # File list is accumulated in 'self.filelist'.
325            self.get_file_list()
326    
327            # Otherwise, go ahead and create the source distribution tarball,
328            # or zipfile, or whatever.
329            self.make_distribution()
330    
331        def get_file_list(self):
332            """Figure out the list of files to include in the data
333            distribution, and put it in 'self.filelist'.
334            """
335            self.filelist.findall("Data")
336            self.filelist.include_pattern("*", anchor = 0)
337            self.filelist.exclude_pattern(r'/(RCS|CVS)/.*', is_regex=1)
338            self.filelist.sort()
339            self.filelist.remove_duplicates()
340    
341        def make_release_tree(self, base_dir, files):
342            """Create the directory tree that will become the source
343            distribution archive.  All directories implied by the filenames in
344            'files' are created under 'base_dir', and then we hard link or copy
345            (if hard linking is unavailable) those files into place.
346            Essentially, this duplicates the developer's source tree, but in a
347            directory named after the distribution, containing only the files
348            to be distributed.
349            """
350            # Create all the directories under 'base_dir' necessary to
351            # put 'files' there; the 'mkpath()' is just so we don't die
352            # if the manifest happens to be empty.
353            self.mkpath(base_dir)
354            dir_util.create_tree(base_dir, files,
355                                 verbose=self.verbose, dry_run=self.dry_run)
356    
357            # And walk over the list of files, either making a hard link (if
358            # os.link exists) to each one that doesn't already exist in its
359            # corresponding location under 'base_dir', or copying each file
360            # that's out-of-date in 'base_dir'.  (Usually, all files will be
361            # out-of-date, because by default we blow away 'base_dir' when
362            # we're done making the distribution archives.)
363        
364            if hasattr(os, 'link'):        # can make hard links on this system
365                link = 'hard'
366                msg = "making hard links in %s..." % base_dir
367            else:                           # nope, have to copy
368                link = None
369                msg = "copying files to %s..." % base_dir
370    
371            if not files:
372                self.warn("no files to distribute -- empty manifest?")
373            else:
374                self.announce(msg)
375            for file in files:
376                if not os.path.isfile(file):
377                    self.warn("'%s' not a regular file -- skipping" % file)
378                else:
379                    dest = os.path.join(base_dir, file)
380                    self.copy_file(file, dest, link=link)
381    
382    
383        def make_distribution (self):
384            """Create the source distribution(s).  First, we create the release
385            tree with 'make_release_tree()'; then, we create all required
386            archive files (according to 'self.formats') from the release tree.
387            Finally, we clean up by blowing away the release tree (unless
388            'self.keep_temp' is true).  The list of archive files created is
389            stored so it can be retrieved later by 'get_archive_files()'.
390            """
391            # Don't warn about missing meta-data here -- should be (and is!)
392            # done elsewhere.
393            base_dir = "Thuban-data-" + self.distribution.get_version()
394            base_name = os.path.join(self.dist_dir, base_dir)
395    
396            self.make_release_tree(base_dir, self.filelist.files)
397            archive_files = []              # remember names of files we create
398            for fmt in self.formats:
399                file = self.make_archive(base_name, fmt, base_dir=base_dir)
400                archive_files.append(file)
401    
402            self.archive_files = archive_files
403    
404            if not self.keep_temp:
405                dir_util.remove_tree(base_dir, self.verbose, self.dry_run)
406    
407    
408    
# Line 256  class InstallLocal(Command): Line 415  class InstallLocal(Command):
415      """      """
416    
417      description =\      description =\
418          "Create some symlink so you can run thubanfrom the source directory"          "Create some symlinks so you can run thuban from the source directory"
419    
420      user_options = [      user_options = [
         ('debug', 'g', "compile/link with debugging information"),  
421          ('skip-build', None, "skip the build steps"),          ('skip-build', None, "skip the build steps"),
422            ('create-init-module', None,
423             "Create the thubaninit.py module to ease use of Thuban as a library"),
424            ('dont-create-init-module', None,
425             "Do not create the thubaninit.py module"),
426          ]          ]
427    
428        boolean_options = ["create-init-module"]
429        negative_opt = {'dont-create-init-module' : 'create-init-module'}
430    
431    
432      def initialize_options (self):      def initialize_options (self):
433          self.extensions = None          self.extensions = None
434          self.build_dir = None          self.build_dir = None
435          self.skip_build = None          self.skip_build = None
436          self.debug = None          self.create_init_module = None
437    
438      def finalize_options (self):      def finalize_options (self):
439          self.set_undefined_options("install",          self.set_undefined_options("install",
440                                     ("build_lib", "build_dir"),                                     ("build_lib", "build_dir"),
441                                     ('skip_build', 'skip_build'))                                     ('skip_build', 'skip_build'))
442          self.extensions = self.distribution.ext_modules          self.extensions = self.distribution.ext_modules
443            if self.create_init_module is None:
444                # by default we create the init module
445                self.create_init_module = 1
446    
447      def run(self):      def run(self):
448          # Make sure we have built everything we need first          # Make sure we have built everything we need first
# Line 282  class InstallLocal(Command): Line 451  class InstallLocal(Command):
451          # now do the work. Simply link or copy the Lib dir          # now do the work. Simply link or copy the Lib dir
452          libdir = os.path.join(self.build_dir, "Lib")          libdir = os.path.join(self.build_dir, "Lib")
453          if os.name == "posix":          if os.name == "posix":
454              # on posix, just lilnk the Lib dir              # on posix, just link the Lib dir
455              self.link_dir(libdir, "Lib")              self.link_dir(libdir, "Lib")
456          else:          else:
457              self.copy_tree(libdir, "Lib")              self.copy_tree(libdir, "Lib")
458    
459            # create the init module if desired
460            if self.create_init_module:
461                # create the init module
462                initfilename = "thubaninit.py"
463                contents = thubaninit_contents("")
464                self.execute(write_file, (initfilename, contents),
465                             "Create %s" % initfilename)
466    
467      def link_dir(self, src, dest):      def link_dir(self, src, dest):
468          """Create a symbolic link dest pointing to src"""          """Create a symbolic link dest pointing to src"""
469          if self.verbose:          if self.verbose:
470              print "symlinking %s -> %s" % (src, dest)              self.announce("symlinking %s -> %s" % (src, dest))
471          if self.dry_run:          if self.dry_run:
472              return              return
473    
# Line 309  class InstallLocal(Command): Line 486  class InstallLocal(Command):
486  class thuban_build_py(build_py):  class thuban_build_py(build_py):
487    
488      """      """
489      A new build_py that can deal with both packages and modules in      A new build_py that can deal with both packages and modules in one
490      one distribution.      distribution.
491      """      """
492    
493        # FIXME: When Thuban can rely on Python 2.3 as the oldest supported
494        # Python release we don't need to override the run and
495        # find_all_modules methods anymore. distutils will allow both python
496        # modules and packages starting with 2.3.
497    
498      def run(self):      def run(self):
499          """The same the as teh original in build_py revision 1.33 except          """The same the as the original in build_py revision 1.33 except
500          that this allows both packages and modules to be in one          that this allows both packages and modules to be in one
501          distribution          distribution
502          """          """
# Line 348  class thuban_build_py(build_py): Line 530  class thuban_build_py(build_py):
530              modules.append(("Lib", module_base, module_file))              modules.append(("Lib", module_base, module_file))
531          return modules          return modules
532    
533  #      def find_all_modules (self):
534  # Extend the standard install command to symlink the installed script to          # same as find_all_modules of the original build_py command
535  # $prefix/bin/          # (rev. 1.33) but handle installations with both modules and
536  #          # packages. Needed here so tha the get_outputs works correctly
537            modules = []
538            if self.py_modules:
539                modules.extend(self.find_modules())
540            if self.packages:
541                for package in self.packages:
542                    package_dir = self.get_package_dir(package)
543                    m = self.find_package_modules(package, package_dir)
544                    modules.extend(m)
545    
546            return modules
547    
548    
549    thubaninit_contents_start = """
550    # This module was automatically generated by Thuban's install script
551    '''Import this module once per program (best place is probably the file
552    that ends up as your __main__ module) to be able to import Thuban
553    afterwards.
554    
555    Usage:
556    
557    import thubaninit
558    import Thuban
559    '''
560    import sys, os
561    """
562    
563    thubaninit_contents_thubaninitdir = """
564    sys.path.insert(0, %(thubandir)s)
565    """
566    thubaninit_contents_otherdirs = """
567    # Put the Lib dir into the path. The Lib dir contains some extra Python
568    # modules
569    import Thuban
570    thubandir = os.path.join(Thuban.__path__[0], '..')
571    dir = os.path.join(thubandir, "Lib")
572    if os.path.isdir(dir):
573        sys.path.insert(0, dir)
574    """
575    
576    def thubaninit_contents(thubandir):
577        """Return the contents of the the thubaninit file as a list of lines.
578    
579        The parameter thubandir is the parent directory where the Thuban/
580        package or the empty string if the thubaninit file itself will be
581        located in that direcory as well.
582        """
583        contents = thubaninit_contents_start
584        if thubandir:
585            thubandir = repr(thubandir)
586            contents += thubaninit_contents_thubaninitdir % locals()
587        contents += thubaninit_contents_otherdirs
588        return contents.split("\n")
589    
590    
591  class ThubanInstall(install):  class ThubanInstall(install):
592    
593        """
594        Thuban specific install command.
595    
596        Extend the standard install command to symlink the installed script
597        to $prefix/bin/
598        """
599    
600        user_options = install.user_options[:]
601        user_options.extend([("do-symlink", None,
602                              "Create a symlink to the script in <prefix>/bin."
603                            "(default on posix systems and only relevant there)"),
604    
605                             ("extra-files", None,
606                              "List of filenames or (src, dest) pairs describing"
607                              " extra files to install "
608                              "(can only be set from witin setup.py"),
609    
610                             ("create-init-module=", None,
611                              "If true, create a module in the site-packages"
612                              " directory that tweaks sys.path to let you easily"
613                              " import thuban modules from outside of thuban."),
614                             ("init-module-dir=", None,
615                              "Directory in which to create the init module."
616                              " Defaults to Python's site-packages directory."),
617                             ])
618    
619        boolean_options = install.boolean_options[:]
620        boolean_options.append("do-symlink")
621        boolean_options.append("create-init-module")
622    
623        def initialize_options(self):
624            self.do_symlink = None
625            self.extra_files = []
626    
627            # initialize the create_init_module flag from the global
628            # determined at runtime
629            self.create_init_module = create_init_module
630            self.init_module_dir = None
631            install.initialize_options(self)
632    
633        def finalize_options(self):
634            if self.do_symlink is None:
635                if os.name == "posix":
636                    self.do_symlink = 1
637                else:
638                    self.do_symlink = 0
639            install.finalize_options(self)
640            self.expand_with_pure_python_dirs(["init_module_dir"])
641    
642        def expand_with_pure_python_dirs(self, attrs):
643            """Expand the attributes with default values of base and platbase"""
644            # it seems that the values for "prefix" and "exec_prefix" in
645            # self.config_vars are the corresponding values used by the
646            # python interpreter, so we just assign these to "base" and
647            # "platbase".
648            config_vars = self.config_vars.copy()
649            config_vars["base"] = self.config_vars["prefix"]
650            config_vars["platbase"] = self.config_vars["exec_prefix"]
651            for attr in attrs:
652                val = getattr(self, attr)
653                if val is not None:
654                    if os.name == 'posix':
655                        val = os.path.expanduser(val)
656                    val = subst_vars(val, config_vars)
657                    setattr(self, attr, val)
658    
659        def select_scheme(self, scheme):
660            """Extend the inherited method to set init_module_dir"""
661            install.select_scheme(self, scheme)
662            # only set init_module_dir if it wasn't set by the user
663            if self.init_module_dir is None:
664                self.init_module_dir = INSTALL_SCHEMES[scheme]['purelib']
665    
666        def convert_paths(self, *args):
667            """Extend the inherited method so that we can remember some filename
668            """
669            # remember the installation directory before its root gets
670            # changed
671            self.install_lib_orig = self.install_lib
672            apply(install.convert_paths, (self,) + args)
673    
674      def run(self):      def run(self):
675          install.run(self)          install.run(self)
676          if os.name == "posix":          for item in self.extra_files:
677              scriptfile = os.path.join(self.install_scripts, "thuban.py")              if type(item) == TupleType:
678                    src, dest = item
679                else:
680                    src = dest = item
681                self.copy_file(convert_path(src),
682                               os.path.join(self.root, convert_path(dest)))
683    
684            if os.name == "posix" and self.do_symlink:
685                install_scripts = self.install_scripts
686                if self.root:
687                    install_scripts = install_scripts[len(self.root):]
688                scriptfile = os.path.join(install_scripts, "thuban.py")
689              bindir = os.path.join(self.prefix, "bin")              bindir = os.path.join(self.prefix, "bin")
690                if self.root:
691                    bindir = change_root(self.root, bindir)
692              binfile = os.path.join(bindir, "thuban")              binfile = os.path.join(bindir, "thuban")
693              self.mkpath(bindir)              self.mkpath(bindir)
694              self.copy_file(scriptfile, binfile, link="sym")              self.link_file(scriptfile, binfile)
695    
696            if self.create_init_module:
697                # create the init module
698                initfilename = self.thuban_init_filename()
699                if self.root:
700                    initfilename = change_root(self.root, initfilename)
701                contents = thubaninit_contents(self.install_lib_orig)
702                self.mkpath(os.path.dirname(initfilename))
703                self.execute(write_file, (initfilename, contents),
704                             "Create %s" % initfilename)
705    
706        def link_file(self, src, dest):
707            """Create a symbolic link dest pointing to src.
708    
709            Unlike the symlink variant of the command object's copy_file
710            method, this method even performs the link if src doesn't exist.
711            This is useful when installing with an alternat root directory"""
712            if self.verbose:
713                self.announce("symlinking %s -> %s" % (src, dest))
714            if self.dry_run:
715                return
716    
717            if not os.path.exists(dest):
718                os.symlink(src, dest)
719    
720        def thuban_init_filename(self):
721            """Return the filename for the init-module"""
722            # Since we override the normal install dirs to point to our own
723            # prefix we have to reach into installed
724            return self.init_module_dir + "/thubaninit.py"
725    
726        def get_outputs (self):
727            outputs = install.get_outputs(self)
728            for item in self.extra_files:
729                if type(item) == TupleType:
730                    src, dest = item
731                else:
732                    src = dest = item
733                outputs.append(os.path.join(self.root, convert_path(dest)))
734            if os.name == "posix" and self.do_symlink:
735                bindir = os.path.join(self.prefix, "bin")
736                if self.root:
737                    bindir = change_root(self.root, bindir)
738                binfile = os.path.join(bindir, "thuban")
739                outputs.append(binfile)
740            if self.create_init_module:
741                initfilename = self.thuban_init_filename()
742                if self.root:
743                    initfilename = change_root(self.root, initfilename)
744                outputs.append(initfilename)
745            return outputs
746    
747    
748    # scripts to override some of the commands put into the spec-file by the
749    # bdist_rpm command.
750    
751    bdist_rpm_prep_script = '''
752    %setup
753    cp extensions/pyshapelib/{README,README.pyshapelib}
754    cp extensions/pyshapelib/{COPYING,COPYING.pyshapelib}
755    cp extensions/pyprojection/{LICENSE,LICENSE.pyprojection}
756    '''
757    
758    bdist_rpm_build_script = '''
759    env PATH="$PATH:%(prefix)s/lib/wxPython/bin:/usr/lib/wxPython/bin" CFLAGS="$RPM_OPT_FLAGS" %(python)s setup.py build
760    '''
761    
762    bdist_rpm_install_script = '''
763    %(python)s setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES \
764       --prefix=%(prefix)s
765    '''
766    
767    
768    class thuban_bdist_rpm(bdist_rpm):
769    
770        """Thuban specific RPM distribution command"""
771    
772        user_options = bdist_rpm.user_options[:]
773        user_options.extend([("prefix=", None, "Install prefix for the RPM"),
774                             ])
775    
776        def initialize_options(self):
777            # per default, RPMs are installed in /usr
778            self.prefix = "/usr/"
779    
780            # create the scripts we want to override. We actually fill them
781            # with contents later because some values we put into those
782            # scripts such as the python interpreter to use are only known
783            # then.
784            open("bdist_rpm_prep", "w").close()
785            open("bdist_rpm_build", "w").close()
786            open("bdist_rpm_install", "w").close()
787            bdist_rpm.initialize_options(self)
788    
789        def _make_spec_file(self):
790            # create the scripts for the spec-file. Now we know the python
791            # interpreter to use.
792            open("bdist_rpm_prep", "w").write(bdist_rpm_prep_script)
793    
794            build = bdist_rpm_build_script % {"python": self.python,
795                                              "prefix": self.prefix}
796            open("bdist_rpm_build", "w").write(build)
797    
798            install = bdist_rpm_install_script % {"python": self.python,
799                                                  "prefix": self.prefix}
800            open("bdist_rpm_install", "w").write(install)
801    
802            #
803            return bdist_rpm._make_spec_file(self)
804    
805    
806    class bdist_inno(Command):
807    
808        """Command to create a windows installer with Inno Setup"""
809    
810        description = "Create a windows installer with Inno Setup"
811    
812        user_options = [
813            ('skip-build', None, "skip the build steps"),
814            ('bdist-dir=', None,
815             "temporary directory for creating the distribution"),
816            ('run-inno', None,
817             "Run inno-setup to create the installer. On by default on nt"),
818            ('iss-name', None,
819             "The name of the iss file to generate. "
820             "Shouldn't contain directories"),
821    
822            # Parameters for the Inno Setup script
823            ('copyright', None, "Copyright notice for the Inno Setup file"),
824            ('default-dir-name', None,
825             "Default installation directory. Defaults to '{pf}\\<name>'"),
826            ('default-group-name', None,
827             "Default program group name. Defaults to <name>'"),
828            ("license-file", None, "File containing the license."),
829            ("output-basename", None,
830             "Base filename for the Inno Setup output "
831             "(defaults to <name>-<version>-<issrevision>)."),
832            ("iss-revision", None,
833             "revision of the generated installer of the package version"),
834    
835            ("icons-entries", None,
836             "List if InnoIconItems "
837             "(this can only be set from inside the setup.py script)"),
838            ]
839    
840        boolean_options = ["do-symlink"]
841    
842        def initialize_options(self):
843            self.skip_build = 0
844            self.bdist_dir = None
845            self.run_inno = None
846            self.iss_name = None
847            self.copyright = ""
848            self.default_dir_name = None
849            self.default_group_name = None
850            self.license_file = None
851            self.output_basename = None
852            self.iss_revision = None
853            self.icons_entries = []
854    
855        def finalize_options(self):
856            self.set_undefined_options("install",
857                                       ('skip_build', 'skip_build'))
858            if self.bdist_dir is None:
859                bdist_base = self.get_finalized_command('bdist').bdist_base
860                self.bdist_dir = os.path.join(bdist_base, 'inno')
861    
862            if self.run_inno is None:
863                self.run_inno = os.name == "nt"
864    
865            name = self.distribution.get_name()
866            if self.iss_name is None:
867                self.iss_name = name + '.iss'
868    
869            if self.default_dir_name is None:
870                self.default_dir_name = "{pf}\\" + name
871            if self.default_group_name is None:
872                self.default_group_name = name
873    
874            if self.iss_revision is None:
875                self.iss_revision = 0
876            if self.output_basename is None:
877                self.output_basename = "%s-%s-%d" \
878                                       % (name, self.distribution.get_version(),
879                                          self.iss_revision)
880    
881        def run(self, install_options = None):
882            """Execute the command. install_options if given, should be a
883            directory of additional options to set in the install step"""
884            # Obviously have to build before we can install
885    
886            if not self.skip_build:
887                self.run_command('build')
888    
889            # Install in a temporary directory
890            install = self.reinitialize_command('install')
891            install.root = self.bdist_dir
892            if install_options is not None:
893                for key, value in install_options.items():
894                    setattr(install, key, value)
895            if os.name != 'nt':
896                # Must force install to use the 'nt' scheme;
897                install.select_scheme('nt')
898    
899            self.announce("installing to %s" % self.bdist_dir)
900            install.ensure_finalized()
901            install.run()
902    
903            # Create the iss file
904            iss_file = os.path.join(self.bdist_dir, self.iss_name)
905            self.execute(write_file, (iss_file, self.generate_iss()),
906                         "Create Inno Setup script file %s" % iss_file)
907    
908            # and invoke
909            if self.run_inno:
910                self.spawn(["iscc", iss_file])
911    
912        def generate_iss(self):
913            """Return the contents of the iss file as list of strings, one
914            string per line"""
915    
916            # first, turn the icons entries into a more usable form
917            icons = {}
918            for item in self.icons_entries:
919                icons[item.filename] = item
920    
921            iss = []
922    
923            name = self.distribution.get_name()
924            iss.extend(["[Setup]",
925                        "AppName=" + name,
926                        "AppVerName=" + name + " "+self.distribution.get_version(),
927                        "DefaultDirName=" + self.default_dir_name,
928                        "DefaultGroupName=" + self.default_group_name,
929                        ])
930            if self.copyright:
931                iss.append("AppCopyright=" + self.copyright)
932            if self.license_file:
933                iss.append("LicenseFile=" + self.license_file)
934    
935            iss.append("OutputBasefilename=" + self.output_basename)
936    
937            iss.append("")
938            iss.append("[Files]")
939    
940            install = self.get_finalized_command("install")
941            install_scripts = self.get_finalized_command("install_scripts")
942            script_files = install_scripts.get_outputs()
943            prefixlen = len(self.bdist_dir) + len(os.sep)
944            for filename in install.get_outputs():
945                filename = filename[prefixlen:]
946                icon = icons.get(filename)
947                dirname = os.path.dirname(filename)
948                if os.name != "nt":
949                    # change the separators to \ on non-windos systems
950                    filename = string.join(string.split(filename, os.sep), "\\")
951                    dirname =  string.join(string.split(dirname, os.sep), "\\")
952                line = 'Source: "%s"' % filename
953                if icon is not None:
954                    # install it as defined in the icon object
955                    backslash = string.rfind(icon.install_name, "\\")
956                    if backslash >= 0:
957                        dirname = icon.install_name[:backslash]
958                        basename = icon.install_name[backslash + 1:]
959                    else:
960                        dirname = ""
961                        basename = icon.install_name
962                    line = '%s; DestDir: "%s"; DestName: "%s"' % (line, dirname,
963                                                                  basename)
964                else:
965                    line = line + '; DestDir: "{app}\\%s"' % (dirname)
966                iss.append(line)
967    
968            iss.append("")
969            iss.append("[Icons]")
970            for icon in self.icons_entries:
971                line = 'Name: "{group}\\%s"; Filename: "%s";' \
972                       % (icon.title, icon.install_name)
973                iss.append(line)
974    
975            return iss
976    
977    
978    class InnoIconItem:
979    
980        """Describe one item for the start menu for the Inno Setup installer"""
981    
982        def __init__(self, filename, title, install_name = None):
983            self.filename = filename
984            self.title = title
985            if install_name is not None:
986                self.install_name = install_name
987            else:
988                self.install_name = filename
989    
990    
991    class thuban_bdist_inno(bdist_inno):
992    
993        """Thuban specific Inno Setup stuff"""
994    
995        def run(self):
996            install_options = {
997                "prefix": ".",
998                "install_lib": "$base",
999                "install_data": "$base",
1000                "install_scripts": "$base",
1001                "warn_dir": 0,
1002                "extra_files": ["COPYING", "Lib/proj.dll"],
1003                }
1004            # don't make a symlink because we're simulating windows, so
1005            # that we can generate the iss-file even on Linux
1006            install_options["do_symlink"] = 0
1007    
1008            bdist_inno.run(self, install_options)
1009    
1010    class thuban_build_docs(Command):
1011    
1012        """Command to generate documentation from source code."""
1013    
1014        description = "Generate documentation."
1015    
1016        user_options = []
1017    
1018        def initialize_options(self): pass
1019    
1020        def finalize_options(self): pass
1021    
1022        def run(self, install_options = None):
1023            self.spawn(["happydoc", "-d./Doc", "./Thuban"])
1024    
1025    #
1026    #   Run the script
1027    #
1028    
1029    
1030  long_description = """\  long_description = """\
1031  Thuban is a viewer for geographic data written in Python  Thuban is a viewer for geographic data written in Python
1032  """  """
1033    
1034  setup(name = "thuban",  setup(name = "Thuban",
1035        version = "0.0.3",        version = "0.2.0",
1036        description = "Geographic data viewer",        description = "Geographic data viewer",
1037        long_description = long_description,        long_description = long_description,
1038        licence = "GPL",        licence = "GPL",
1039        author = "Intevation GmbH",        author = "Intevation GmbH",
1040        author_email = "[email protected]",        author_email = "[email protected]",
1041        url = "ftp:intevation.de/",        url = "http://thuban.intevation.de/",
1042    
1043        scripts = ["thuban.py"],        scripts = ["thuban.py"],
1044        packages = ["Thuban", "Thuban.Lib", "Thuban.Model", "Thuban.UI"],        packages = ["Thuban", "Thuban.Lib", "Thuban.Model", "Thuban.UI"],
# Line 390  setup(name = "thuban", Line 1052  setup(name = "thuban",
1052                   {"prefix": prefix,                   {"prefix": prefix,
1053                    # make sure both libs and scripts are installed in the                    # make sure both libs and scripts are installed in the
1054                    # same directory.                    # same directory.
1055                    "install_lib": "$base/thuban",                    "install_lib": "$base/lib/thuban",
1056                    "install_scripts": "$base/thuban",                    "install_scripts": "$base/lib/thuban",
1057                    "install_data": "$base/thuban/",                    "install_data": "$base/lib/thuban",
1058    
1059                    # Don't print warning messages about the lib dir not                    # Don't print warning messages about the lib dir not
1060                    # being on Python's path. The libraries are Thuban                    # being on Python's path. The libraries are Thuban
1061                    # specific and are installed just for Thuban. They'll                    # specific and are installed just for Thuban. They'll
1062                    # be automatically on Python's path when Thuban is run                    # be automatically on Python's path when Thuban is run
1063                    "warn_dir": 0,                    "warn_dir": 0,
1064                    }},                    },
1065                     "bdist_inno":
1066                     {"icons_entries": [InnoIconItem(".\\thuban.py",
1067                                                     "Start Thuban",
1068                                                     "{app}\\thuban.pyw")],
1069                      "license_file": "COPYING",
1070                      }
1071                     },
1072        cmdclass = {"build_py": thuban_build_py,        cmdclass = {"build_py": thuban_build_py,
1073                    "install_local": InstallLocal,                    "install_local": InstallLocal,
1074                    "install": ThubanInstall})                    "install": ThubanInstall,
1075                      "bdist_rpm": thuban_bdist_rpm,
1076                      "bdist_inno": thuban_bdist_inno,
1077                      "data_dist": data_dist,
1078                      "build_docs": thuban_build_docs
1079                      })
1080    
1081    

Legend:
Removed from v.6  
changed lines
  Added in v.671

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26