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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26