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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26