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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26