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

Legend:
Removed from v.8  
changed lines
  Added in v.928

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26