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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 212 - (hide annotations)
Wed Jul 10 14:06:09 2002 UTC (22 years, 8 months ago) by bh
Original Path: trunk/thuban/setup.py
File MIME type: text/x-python
File size: 35981 byte(s)
	* setup.py (create_init_module): New configurable variable whose
	default depends on the platform we're running on.
	(ThubanInstall.initialize_options): Initialize
	self.create_init_module from the global create_init_module
	(ThubanInstall.user_options): indictate that the options
	create-init-module and init-module-dir have arguments.

	* setup.py: In the setup call change the version number to include
	cvs.

1 bh 86 # Copyright (c) 2001, 2002 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """Distutils setup script for Thuban."""
9    
10     __version__ = "$Revision$"
11    
12     # Configuration:
13     #
14     # depending on your platform you may have to configure some variables by
15     # hand below.
16     #
17    
18     import os
19 bh 15 from types import TupleType
20 bh 6 from distutils.core import setup, Extension, Command
21 bh 204 from distutils.command.install import install, INSTALL_SCHEMES, subst_vars
22 bh 6 from distutils.command.build_py import build_py
23 bh 19 from distutils.command.bdist_rpm import bdist_rpm
24 bh 15 from distutils.file_util import write_file
25 bh 67 from distutils.filelist import FileList
26 bh 18 from distutils.util import convert_path, change_root
27 bh 6
28 bh 67 from distutils import archive_util, dir_util
29 bh 6 import distutils
30    
31     from string import split
32     import string
33    
34     if os.name == "posix":
35     ###################################################################
36     # Posix configuration. Adapt this if you're running some kind of
37     # Unix like system.
38    
39     # Directories where Proj4 is installed
40     proj4_prefix = "/usr/local/"
41     proj4_incdir = os.path.join(proj4_prefix, "include")
42     proj4_libdir = os.path.join(proj4_prefix, "lib")
43     proj4_lib = "proj"
44    
45    
46 bh 212 # You shouldn't have to modify anything below here
47 bh 6 ###################################################################
48    
49     # The installation prefix (similar to autoconf's --prefix). This is
50     # only the default value, you can override it on the command line
51 bh 203 # 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 bh 6 prefix = "/usr/local/"
56    
57 bh 212 # 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 bh 6 # On POSIX-systems we run wxgtk-config to determine the C++-compiler
63     # flags
64 bh 19 wx_config_script = "wx-config"
65 bh 6 # These lists will be filled automatically below
66     wx_defs = []
67     wx_incdirs = []
68     wx_libdirs = []
69     wx_libs = []
70    
71     elif os.name == "nt":
72     #################################################################
73     # Windows configuration.
74     #
75    
76     # Directories where Proj4 is installed
77     proj4_prefix = r"D:\cygwin\home\user\proj-4.4.3\src"
78     proj4_incdir = proj4_prefix
79     proj4_libdir = proj4_prefix
80     proj4_lib = "proj_i"
81    
82 bh 15 # Define include and lib directories for wxWindows and
83     wx_prefix = r"D:\wx230"
84     wx_inc = os.path.join(wx_prefix, "include")
85     wx_lib = os.path.join(wx_prefix, "lib")
86    
87 bh 6 #
88     # Unless you use a wxPython version other than 2.3.1, you probably
89     # shouldn't have to modify anything below here
90     ##################################################################
91    
92     # Installation prefix. Just install relative to current directory by
93     # default. This is only the default value, you can override it on
94     # the command line with the install command's --prefix option
95     prefix = r"install"
96    
97 bh 212 # Whether to create the thubaninit module. You can override this
98     # value on the commandline with the --create-init-module to the
99     # install command. By default we don't create it under NT because we
100     # most often run install only as part of bdist_inno where we can't
101     # really create because it needs information only known at install
102     # time.
103     create_init_module = 0
104    
105 bh 6 # There doesn't seem to be an easy way to get at the wx compiler
106     # flags, so we define them here. These flags work for us with
107     # wxPython 2.3.1. They may have to be modified for other versions.
108    
109     # there's no config script.
110     wx_config_script = ""
111    
112     # the values of wx_defs and wx_libs. copied from the wxPython
113     # setup.py
114     wx_defs = [ ('WIN32', None), # Some of these are no longer
115     ('__WIN32__', None), # necessary. Anybody know which?
116     ('_WINDOWS', None),
117     ('__WINDOWS__', None),
118     ('WINVER', '0x0400'),
119     ('__WIN95__', None),
120     ('STRICT', None),
121    
122     ('__WXMSW__', None),
123     ('WXUSINGDLL', '1'),
124    
125     ('SWIG_GLOBAL', None),
126     ('HAVE_CONFIG_H', None),
127     ('WXP_USE_THREAD', '1'),
128     ]
129    
130     wx_incdirs = [wx_inc]
131     wx_libdirs = [wx_lib]
132     wx_libs = ["wx23_1h"]
133     wx_libs = wx_libs + ['kernel32', 'user32', 'gdi32', 'comdlg32',
134     'winspool', 'winmm', 'shell32', 'oldnames',
135     'comctl32', 'ctl3d32', 'odbc32', 'ole32', 'oleaut32',
136     'uuid', 'rpcrt4', 'advapi32', 'wsock32']
137     else:
138     raise RuntimeError("Unsupported platform " + os.name)
139    
140    
141     ######################################################################
142     #
143     # There's nothing beyond this point that has to be modified for a
144     # normal installation
145     #
146     ######################################################################
147    
148    
149     #
150     # Functions to determine wxWindows config on POSIX systems
151     #
152    
153     def run_script(cmdline):
154     """Run command and return its stdout or none in case of errors"""
155     pipe = os.popen(cmdline)
156     result = pipe.read()
157     if pipe.close() is not None:
158     print '"' + cmdline + '"', 'failed'
159     return None
160     return result
161    
162    
163     def run_wx_script(command):
164 bh 19 # first, determine the C++ preprocessor flags Use --cflags here
165     # because it seems that older version don't have --cxxflags and
166     # newer ones return the same result for both
167     flags = run_script(command + ' --cflags ')
168 bh 6 if flags is None:
169     return 0
170     for flag in split(flags):
171     start = flag[:2]
172     value = flag[2:]
173     if start == "-I":
174     wx_incdirs.append(value)
175     elif start == "-D":
176     wx_defs.append((value, None))
177    
178     # determine the library flags
179     flags = run_script(command + ' --libs')
180     if flags is None:
181     return 0
182     for flag in split(flags):
183     start = flag[:2]
184     value = flag[2:]
185     if start == "-L":
186     wx_libdirs.append(value)
187     elif start == "-l":
188     wx_libs.append(value)
189    
190     if wx_config_script:
191     # if there's a wx config script, run it to determine the configuration
192     run_wx_script(wx_config_script)
193    
194    
195    
196     #
197     # Define some extension and python modules
198     #
199     # The C-extension names are prefixed woth "Lib." so they get put into
200     # the Lib/ subdirectory. Lib/ is not really a package but distutils
201     # doesn't care
202    
203     # subdirectory containing the extensions
204     ext_dir = "extensions"
205    
206     # subdirectory with some shapelib files
207     shp_dir = ext_dir + "/shapelib"
208    
209     # lists to fill with the module descriptions
210     extensions = []
211     py_modules = []
212    
213    
214     #
215     # Thuban specific modules
216     #
217    
218     extensions.append(Extension("Lib.wxproj",
219 bh 97 [ext_dir + "/thuban/wxproj.cpp"],
220     include_dirs = ([shp_dir, proj4_incdir,
221     ext_dir + "/pyshapelib/"]
222     + wx_incdirs),
223 bh 6 define_macros = wx_defs,
224     library_dirs = [proj4_libdir] + wx_libdirs,
225     libraries = [proj4_lib] + wx_libs))
226    
227     #
228     # shapelib wrappers are also distributed with thuban
229     #
230    
231     extensions.append(Extension("Lib.shapelibc",
232     [ext_dir + "/pyshapelib/shapelib_wrap.c",
233 bh 142 shp_dir + "/shpopen.c",
234     shp_dir + "/shptree.c"],
235 bh 6 include_dirs = [shp_dir]))
236 bh 142 extensions.append(Extension("Lib.shptree",
237     [ext_dir + "/pyshapelib/shptreemodule.c"],
238     include_dirs = [shp_dir]))
239 bh 6 extensions.append(Extension("Lib.dbflibc",
240     [ext_dir + "/pyshapelib/dbflib_wrap.c",
241     shp_dir + "/dbfopen.c"],
242     include_dirs = [shp_dir]))
243 bh 164 for name in ("shapelib", "dbflib"):
244 bh 6 py_modules.append(ext_dir + "/pyshapelib/" + name)
245    
246     #
247     # PROJ4 bindings are also distributed with thuban
248     #
249     extensions.append(Extension("Lib.Projectionc",
250     [ext_dir + "/pyprojection/Projection_wrap.c"],
251     include_dirs = [proj4_incdir],
252     library_dirs = [proj4_libdir],
253     libraries = [proj4_lib]))
254     py_modules.append(ext_dir + "/pyprojection/Projection")
255    
256    
257     #
258     # Data files
259     #
260    
261     data_files = []
262    
263     # bitmaps
264 bh 15 dir = "Resources/Bitmaps"
265 bh 6 bitmaps = []
266     for file in os.listdir(os.path.join("Resources", "Bitmaps")):
267     if string.lower(file[-4:]) == ".xpm":
268 bh 15 bitmaps.append(dir + '/' + file)
269 bh 6 data_files.append((dir, bitmaps))
270    
271     #
272     # Command definitions
273     #
274     # So far distutils are only meant to distribute python extensions, not
275     # complete applications, so we have to redefine a few commands
276 bh 67 #
277 bh 6
278    
279 bh 67 # Much of the data_dist command is directly copied from the distutils'
280     # sdist command
281     class data_dist(Command):
282 bh 6
283 bh 67 description = "create a data distribution (tarball, zip file, etc.)"
284    
285     user_options = [
286     ('formats=', None,
287     "formats for source distribution (comma-separated list)"),
288     ('keep-temp', 'k',
289     "keep the distribution tree around after creating " +
290     "archive file(s)"),
291     ('dist-dir=', 'd',
292     "directory to put the source distribution archive(s) in "
293     "[default: dist]"),
294     ]
295    
296     boolean_options = ['keep-temp']
297    
298     def initialize_options (self):
299     self.formats = None
300     self.keep_temp = 0
301     self.dist_dir = None
302    
303     def finalize_options (self):
304     self.ensure_string_list('formats')
305     if self.formats is None:
306     self.formats = ["zip"]
307     bad_format = archive_util.check_archive_formats(self.formats)
308     if bad_format:
309     raise DistutilsOptionError, \
310     "unknown archive format '%s'" % bad_format
311    
312     if self.dist_dir is None:
313     self.dist_dir = "dist"
314    
315    
316     def run(self):
317     # 'filelist' contains the list of files that will make up the
318     # manifest
319     self.filelist = FileList()
320    
321     # Do whatever it takes to get the list of files to process.
322     # File list is accumulated in 'self.filelist'.
323     self.get_file_list()
324    
325     # Otherwise, go ahead and create the source distribution tarball,
326     # or zipfile, or whatever.
327     self.make_distribution()
328    
329     def get_file_list(self):
330     """Figure out the list of files to include in the data
331     distribution, and put it in 'self.filelist'.
332     """
333     self.filelist.findall("Data")
334     self.filelist.include_pattern("*", anchor = 0)
335     self.filelist.exclude_pattern(r'/(RCS|CVS)/.*', is_regex=1)
336     self.filelist.sort()
337     self.filelist.remove_duplicates()
338    
339     def make_release_tree(self, base_dir, files):
340     """Create the directory tree that will become the source
341     distribution archive. All directories implied by the filenames in
342     'files' are created under 'base_dir', and then we hard link or copy
343     (if hard linking is unavailable) those files into place.
344     Essentially, this duplicates the developer's source tree, but in a
345     directory named after the distribution, containing only the files
346     to be distributed.
347     """
348     # Create all the directories under 'base_dir' necessary to
349     # put 'files' there; the 'mkpath()' is just so we don't die
350     # if the manifest happens to be empty.
351     self.mkpath(base_dir)
352     dir_util.create_tree(base_dir, files,
353     verbose=self.verbose, dry_run=self.dry_run)
354    
355     # And walk over the list of files, either making a hard link (if
356     # os.link exists) to each one that doesn't already exist in its
357     # corresponding location under 'base_dir', or copying each file
358     # that's out-of-date in 'base_dir'. (Usually, all files will be
359     # out-of-date, because by default we blow away 'base_dir' when
360     # we're done making the distribution archives.)
361    
362     if hasattr(os, 'link'): # can make hard links on this system
363     link = 'hard'
364     msg = "making hard links in %s..." % base_dir
365     else: # nope, have to copy
366     link = None
367     msg = "copying files to %s..." % base_dir
368    
369     if not files:
370     self.warn("no files to distribute -- empty manifest?")
371     else:
372     self.announce(msg)
373     for file in files:
374     if not os.path.isfile(file):
375     self.warn("'%s' not a regular file -- skipping" % file)
376     else:
377     dest = os.path.join(base_dir, file)
378     self.copy_file(file, dest, link=link)
379    
380    
381     def make_distribution (self):
382     """Create the source distribution(s). First, we create the release
383     tree with 'make_release_tree()'; then, we create all required
384     archive files (according to 'self.formats') from the release tree.
385     Finally, we clean up by blowing away the release tree (unless
386     'self.keep_temp' is true). The list of archive files created is
387     stored so it can be retrieved later by 'get_archive_files()'.
388     """
389     # Don't warn about missing meta-data here -- should be (and is!)
390     # done elsewhere.
391     base_dir = "Thuban-data-" + self.distribution.get_version()
392     base_name = os.path.join(self.dist_dir, base_dir)
393    
394     self.make_release_tree(base_dir, self.filelist.files)
395     archive_files = [] # remember names of files we create
396     for fmt in self.formats:
397     file = self.make_archive(base_name, fmt, base_dir=base_dir)
398     archive_files.append(file)
399    
400     self.archive_files = archive_files
401    
402     if not self.keep_temp:
403     dir_util.remove_tree(base_dir, self.verbose, self.dry_run)
404    
405    
406    
407 bh 6 class InstallLocal(Command):
408    
409     """
410     A new install command to just link (or copy, on non-POSIX systems)
411     the extension modules to the top directory so that Thuban can be run
412     directly from the source dir.
413     """
414    
415     description =\
416 bh 71 "Create some symlinks so you can run thuban from the source directory"
417 bh 6
418     user_options = [
419     ('skip-build', None, "skip the build steps"),
420     ]
421    
422     def initialize_options (self):
423     self.extensions = None
424     self.build_dir = None
425     self.skip_build = None
426    
427     def finalize_options (self):
428     self.set_undefined_options("install",
429     ("build_lib", "build_dir"),
430     ('skip_build', 'skip_build'))
431     self.extensions = self.distribution.ext_modules
432    
433     def run(self):
434     # Make sure we have built everything we need first
435     self.build()
436    
437     # now do the work. Simply link or copy the Lib dir
438     libdir = os.path.join(self.build_dir, "Lib")
439     if os.name == "posix":
440 bh 71 # on posix, just link the Lib dir
441 bh 6 self.link_dir(libdir, "Lib")
442     else:
443     self.copy_tree(libdir, "Lib")
444    
445     def link_dir(self, src, dest):
446     """Create a symbolic link dest pointing to src"""
447     if self.verbose:
448 bh 15 self.announce("symlinking %s -> %s" % (src, dest))
449 bh 6 if self.dry_run:
450     return
451    
452     if not (os.path.exists(dest) and os.path.samefile(src, dest)):
453     os.symlink(src, dest)
454    
455     def build (self):
456     if not self.skip_build:
457     if self.distribution.has_pure_modules():
458     self.run_command('build_py')
459     if self.distribution.has_ext_modules():
460     self.run_command('build_ext')
461    
462    
463    
464     class thuban_build_py(build_py):
465    
466     """
467 bh 8 A new build_py that can deal with both packages and modules in one
468     distribution.
469 bh 6 """
470    
471     def run(self):
472 bh 8 """The same the as the original in build_py revision 1.33 except
473 bh 6 that this allows both packages and modules to be in one
474     distribution
475     """
476     if not self.py_modules and not self.packages:
477     return
478    
479     # Now we're down to two cases: 'py_modules' only and 'packages' only.
480     if self.py_modules:
481     self.build_modules()
482     if self.packages:
483     self.build_packages()
484    
485     self.byte_compile(self.get_outputs(include_bytecode=0))
486    
487     def find_modules (self):
488     """Thuban specific version of build_py.find_modules. Unlike the
489     original version, we assume that the modules in self.py_modules
490     can contain directories and are all to be placed into the same
491     subdirectory, Lib, in the build directory. This is achieved by
492     returning the modules as a list (package, module, filename)
493     where package is 'Lib', module is the basename of the module name
494     and filename is the filename relative to the package root.
495     """
496     modules = []
497     for module in self.py_modules:
498     module_base = os.path.basename(module)
499     module_file = module + ".py"
500     if not self.check_module(module, module_file):
501     continue
502    
503     modules.append(("Lib", module_base, module_file))
504     return modules
505    
506 bh 15 def find_all_modules (self):
507     # same as find_all_modules of the original build_py command
508     # (rev. 1.33) but handle installations with both modules and
509     # packages. Needed here so tha the get_outputs works correctly
510     modules = []
511     if self.py_modules:
512     modules.extend(self.find_modules())
513     if self.packages:
514     for package in self.packages:
515     package_dir = self.get_package_dir(package)
516     m = self.find_package_modules(package, package_dir)
517     modules.extend(m)
518 bh 6
519 bh 15 return modules
520    
521    
522 bh 204 thubaninit_contents = """
523     # This module was automatically generated by Thuban's install script
524     '''Import this module once per program (best place is probably the file
525     that ends up as your __main__ module) to be able to import Thuban
526     afterwards.
527 bh 15
528 bh 204 Usage:
529    
530     import thubaninit
531     import Thuban
532     '''
533     import sys, os
534     sys.path.insert(0, %(thubandir)s)
535    
536     # Put the Lib dir into the path. The Lib dir contains some extra Python
537     # modules
538     import Thuban
539     thubandir = os.path.join(Thuban.__path__[0], '..')
540     dir = os.path.join(thubandir, "Lib")
541     if os.path.isdir(dir):
542     sys.path.insert(0, dir)
543     """
544    
545    
546 bh 6 class ThubanInstall(install):
547    
548 bh 8 """
549     Thuban specific install command.
550    
551     Extend the standard install command to symlink the installed script
552     to $prefix/bin/
553     """
554 bh 15
555     user_options = install.user_options[:]
556     user_options.extend([("do-symlink", None,
557     "Create a symlink to the script in <prefix>/bin."
558     "(default on posix systems and only relevant there)"),
559    
560     ("extra-files", None,
561 bh 204 "List of filenames or (src, dest) pairs describing"
562 bh 15 " extra files to install "
563     "(can only be set from witin setup.py"),
564 bh 204
565 bh 212 ("create-init-module=", None,
566     "If true, create a module in the site-packages"
567     " directory that tweaks sys.path to let you easily"
568     " import thuban modules from outside of thuban."),
569     ("init-module-dir=", None,
570 bh 204 "Directory in which to create the init module."
571     " Defaults to Python's site-packages directory."),
572    
573 bh 15 ])
574    
575     boolean_options = install.boolean_options[:]
576     boolean_options.append("do-symlink")
577 bh 204 boolean_options.append("create-init-module")
578 bh 15
579     def initialize_options(self):
580     self.do_symlink = None
581     self.extra_files = []
582 bh 212
583     # initialize the create_init_module flag from the global
584     # determined at runtime
585     self.create_init_module = create_init_module
586 bh 204 self.init_module_dir = None
587 bh 15 install.initialize_options(self)
588    
589     def finalize_options(self):
590     if self.do_symlink is None:
591     if os.name == "posix":
592     self.do_symlink = 1
593     else:
594     self.do_symlink = 0
595     install.finalize_options(self)
596 bh 204 self.expand_with_pure_python_dirs(["init_module_dir"])
597 bh 15
598 bh 204 def expand_with_pure_python_dirs(self, attrs):
599     """Expand the attributes with default values of base and platbase"""
600     # it seems that the values for "prefix" and "exec_prefix" in
601     # self.config_vars are the corresponding values used by the
602     # python interpreter, so we just assign these to "base" and
603     # "platbase".
604     config_vars = self.config_vars.copy()
605     config_vars["base"] = self.config_vars["prefix"]
606     config_vars["platbase"] = self.config_vars["exec_prefix"]
607     for attr in attrs:
608     val = getattr(self, attr)
609     if val is not None:
610     if os.name == 'posix':
611     val = os.path.expanduser(val)
612     val = subst_vars(val, config_vars)
613     setattr(self, attr, val)
614    
615     def select_scheme(self, scheme):
616     """Extend the inherited method to set init_module_dir"""
617     install.select_scheme(self, scheme)
618     # only set init_module_dir if it wasn't set by the user
619     if self.init_module_dir is None:
620     self.init_module_dir = INSTALL_SCHEMES[scheme]['purelib']
621    
622     def convert_paths(self, *args):
623     """Extend the inherited method so that we can remember some filename
624     """
625     # remember the installation directory before its root gets
626     # changed
627     self.install_lib_orig = self.install_lib
628     apply(install.convert_paths, (self,) + args)
629    
630 bh 6 def run(self):
631     install.run(self)
632 bh 15 for item in self.extra_files:
633     if type(item) == TupleType:
634     src, dest = item
635     else:
636     src = dest = item
637     self.copy_file(convert_path(src),
638     os.path.join(self.root, convert_path(dest)))
639    
640     if os.name == "posix" and self.do_symlink:
641 bh 19 install_scripts = self.install_scripts
642     if self.root:
643     install_scripts = install_scripts[len(self.root):]
644     scriptfile = os.path.join(install_scripts, "thuban.py")
645 bh 6 bindir = os.path.join(self.prefix, "bin")
646 bh 18 if self.root:
647     bindir = change_root(self.root, bindir)
648 bh 6 binfile = os.path.join(bindir, "thuban")
649     self.mkpath(bindir)
650 bh 19 self.link_file(scriptfile, binfile)
651 bh 6
652 bh 204 if self.create_init_module:
653     # create the init module
654     initfilename = self.thuban_init_filename()
655     if self.root:
656     initfilename = change_root(self.root, initfilename)
657     contents = thubaninit_contents % {
658     "thubandir": repr(self.install_lib_orig)
659     }
660     self.mkpath(os.path.dirname(initfilename))
661     self.execute(write_file, (initfilename, split(contents, "\n")),
662     "Create %s" % initfilename)
663    
664 bh 19 def link_file(self, src, dest):
665     """Create a symbolic link dest pointing to src.
666    
667     Unlike the symlink variant of the command object's copy_file
668     method, this method even performs the link if src doesn't exist.
669     This is useful when installing with an alternat root directory"""
670     if self.verbose:
671     self.announce("symlinking %s -> %s" % (src, dest))
672     if self.dry_run:
673     return
674    
675     if not os.path.exists(dest):
676     os.symlink(src, dest)
677    
678 bh 204 def thuban_init_filename(self):
679     """Return the filename for the init-module"""
680     # Since we override the normal install dirs to point to our own
681     # prefix we have to reach into installed
682     return self.init_module_dir + "/thubaninit.py"
683 bh 19
684 bh 15 def get_outputs (self):
685     outputs = install.get_outputs(self)
686     for item in self.extra_files:
687     if type(item) == TupleType:
688     src, dest = item
689     else:
690     src = dest = item
691     outputs.append(os.path.join(self.root, convert_path(dest)))
692 bh 19 if os.name == "posix" and self.do_symlink:
693     bindir = os.path.join(self.prefix, "bin")
694     if self.root:
695     bindir = change_root(self.root, bindir)
696     binfile = os.path.join(bindir, "thuban")
697     outputs.append(binfile)
698 bh 204 if self.create_init_module:
699     initfilename = self.thuban_init_filename()
700     if self.root:
701     initfilename = change_root(self.root, initfilename)
702     outputs.append(initfilename)
703 bh 15 return outputs
704 bh 6
705 bh 19
706 bh 203 # scripts to override some of the commands put into the spec-file by the
707     # bdist_rpm command.
708    
709 bh 19 bdist_rpm_prep_script = '''
710     %setup
711     cp extensions/pyshapelib/{README,README.pyshapelib}
712     cp extensions/pyshapelib/{COPYING,COPYING.pyshapelib}
713     cp extensions/pyprojection/{LICENSE,LICENSE.pyprojection}
714     '''
715    
716 bh 203 bdist_rpm_install_script = '''
717     %(python)s setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES \
718     --prefix=%(prefix)s
719     '''
720 bh 19
721    
722     class thuban_bdist_rpm(bdist_rpm):
723    
724     """Thuban specific RPM distribution command"""
725    
726 bh 203 user_options = bdist_rpm.user_options[:]
727     user_options.extend([("prefix=", None, "Install prefix for the RPM"),
728     ])
729    
730 bh 90 def initialize_options(self):
731 bh 203 # per default, RPMs are installed in /usr
732     self.prefix = "/usr/"
733 bh 19
734 bh 203 # create the scripts we want to override. We actually fill them
735     # with contents later because some values we put into those
736     # scripts such as the python interpreter to use are only known
737     # then.
738     open("bdist_rpm_prep", "w").close()
739     open("bdist_rpm_install", "w").close()
740 bh 90 bdist_rpm.initialize_options(self)
741 bh 19
742 bh 203 def _make_spec_file(self):
743     # create the scripts for the spec-file. Now we know the python
744     # interpreter to use.
745     open("bdist_rpm_prep", "w").write(bdist_rpm_prep_script)
746     install = bdist_rpm_install_script % {"python": self.python,
747     "prefix": self.prefix}
748     open("bdist_rpm_install", "w").write(install)
749 bh 19
750 bh 203 #
751     return bdist_rpm._make_spec_file(self)
752    
753    
754 bh 15 class bdist_inno(Command):
755    
756     """Command to create a windows installer with Inno Setup"""
757    
758     description = "Create a windows installer with Inno Setup"
759    
760     user_options = [
761     ('skip-build', None, "skip the build steps"),
762     ('bdist-dir=', None,
763     "temporary directory for creating the distribution"),
764     ('run-inno', None,
765     "Run inno-setup to create the installer. On by default on nt"),
766     ('iss-name', None,
767     "The name of the iss file to generate. "
768     "Shouldn't contain directories"),
769    
770     # Parameters for the Inno Setup script
771     ('copyright', None, "Copyright notice for the Inno Setup file"),
772     ('default-dir-name', None,
773     "Default installation directory. Defaults to '{pf}\\<name>'"),
774     ('default-group-name', None,
775     "Default program group name. Defaults to <name>'"),
776     ("license-file", None, "File containing the license."),
777     ("output-basename", None,
778     "Base filename for the Inno Setup output "
779     "(defaults to <name>-<version>-<issrevision>)."),
780     ("iss-revision", None,
781     "revision of the generated installer of the package version"),
782    
783     ("icons-entries", None,
784     "List if InnoIconItems "
785     "(this can only be set from inside the setup.py script)"),
786     ]
787    
788     boolean_options = ["do-symlink"]
789    
790     def initialize_options(self):
791     self.skip_build = 0
792     self.bdist_dir = None
793     self.run_inno = None
794     self.iss_name = None
795     self.copyright = ""
796     self.default_dir_name = None
797     self.default_group_name = None
798     self.license_file = None
799     self.output_basename = None
800     self.iss_revision = None
801     self.icons_entries = []
802    
803     def finalize_options(self):
804     self.set_undefined_options("install",
805     ('skip_build', 'skip_build'))
806     if self.bdist_dir is None:
807     bdist_base = self.get_finalized_command('bdist').bdist_base
808     self.bdist_dir = os.path.join(bdist_base, 'inno')
809    
810     if self.run_inno is None:
811     self.run_inno = os.name == "nt"
812    
813     name = self.distribution.get_name()
814     if self.iss_name is None:
815     self.iss_name = name + '.iss'
816    
817     if self.default_dir_name is None:
818     self.default_dir_name = "{pf}\\" + name
819     if self.default_group_name is None:
820     self.default_group_name = name
821    
822     if self.iss_revision is None:
823     self.iss_revision = 0
824     if self.output_basename is None:
825     self.output_basename = "%s-%s-%d" \
826     % (name, self.distribution.get_version(),
827     self.iss_revision)
828    
829     def run(self, install_options = None):
830     """Execute the command. install_options if given, should be a
831     directory of additional options to set in the install step"""
832     # Obviously have to build before we can install
833     if not self.skip_build:
834     self.run_command('build')
835    
836     # Install in a temporary directory
837     install = self.reinitialize_command('install')
838     install.root = self.bdist_dir
839     if install_options is not None:
840     for key, value in install_options.items():
841     setattr(install, key, value)
842     if os.name != 'nt':
843     # Must force install to use the 'nt' scheme;
844     install.select_scheme('nt')
845    
846     self.announce("installing to %s" % self.bdist_dir)
847     install.ensure_finalized()
848     install.run()
849    
850     # Create the iss file
851     iss_file = os.path.join(self.bdist_dir, self.iss_name)
852     self.execute(write_file, (iss_file, self.generate_iss()),
853     "Create Inno Setup script file %s" % iss_file)
854    
855     # and invoke
856     if self.run_inno:
857     self.spawn(["iscc", iss_file])
858    
859     def generate_iss(self):
860     """Return the contents of the iss file as list of strings, one
861     string per line"""
862    
863     # first, turn the icons entries into a more usable form
864     icons = {}
865     for item in self.icons_entries:
866     icons[item.filename] = item
867    
868     iss = []
869    
870     name = self.distribution.get_name()
871     iss.extend(["[Setup]",
872     "AppName=" + name,
873     "AppVerName=" + name + " "+self.distribution.get_version(),
874     "DefaultDirName=" + self.default_dir_name,
875     "DefaultGroupName=" + self.default_group_name,
876     ])
877     if self.copyright:
878     iss.append("AppCopyright=" + self.copyright)
879     if self.license_file:
880     iss.append("LicenseFile=" + self.license_file)
881    
882     iss.append("OutputBasefilename=" + self.output_basename)
883    
884     iss.append("")
885     iss.append("[Files]")
886    
887     install = self.get_finalized_command("install")
888     install_scripts = self.get_finalized_command("install_scripts")
889     script_files = install_scripts.get_outputs()
890     prefixlen = len(self.bdist_dir) + len(os.sep)
891     for filename in install.get_outputs():
892     filename = filename[prefixlen:]
893     icon = icons.get(filename)
894     dirname = os.path.dirname(filename)
895     if os.name != "nt":
896     # change the separators to \ on non-windos systems
897     filename = string.join(string.split(filename, os.sep), "\\")
898     dirname = string.join(string.split(dirname, os.sep), "\\")
899     line = 'Source: "%s"' % filename
900     if icon is not None:
901     # install it as defined in the icon object
902     backslash = string.rfind(icon.install_name, "\\")
903     if backslash >= 0:
904     dirname = icon.install_name[:backslash]
905     basename = icon.install_name[backslash + 1:]
906     else:
907     dirname = ""
908     basename = icon.install_name
909     line = '%s; DestDir: "%s"; DestName: "%s"' % (line, dirname,
910     basename)
911     else:
912     line = line + '; DestDir: "{app}\\%s"' % (dirname)
913     iss.append(line)
914    
915     iss.append("")
916     iss.append("[Icons]")
917     for icon in self.icons_entries:
918     line = 'Name: "{group}\\%s"; Filename: "%s";' \
919     % (icon.title, icon.install_name)
920     iss.append(line)
921    
922     return iss
923    
924    
925     class InnoIconItem:
926    
927 bh 54 """Describe one item for the start menu for the Inno Setup installer"""
928 bh 15
929     def __init__(self, filename, title, install_name = None):
930     self.filename = filename
931     self.title = title
932     if install_name is not None:
933     self.install_name = install_name
934     else:
935     self.install_name = filename
936    
937 bh 54
938 bh 15 class thuban_bdist_inno(bdist_inno):
939    
940     """Thuban specific Inno Setup stuff"""
941    
942     def run(self):
943     install_options = {
944     "prefix": ".",
945     "install_scripts": "$base",
946     "warn_dir": 0,
947     "extra_files": ["COPYING", "Lib/proj.dll"],
948     }
949 bh 54 # don't make a symlink because we're simulating windows, so
950     # that we can generate the iss-file even on Linux
951     install_options["do_symlink"] = 0
952 bh 15 bdist_inno.run(self, install_options)
953    
954    
955     #
956     # Run the script
957     #
958    
959    
960 bh 6 long_description = """\
961     Thuban is a viewer for geographic data written in Python
962     """
963    
964 bh 15 setup(name = "Thuban",
965 bh 212 version = "0.1.3cvs",
966 bh 6 description = "Geographic data viewer",
967     long_description = long_description,
968     licence = "GPL",
969     author = "Intevation GmbH",
970     author_email = "[email protected]",
971 bh 209 url = "http://thuban.intevation.de/",
972 bh 6
973     scripts = ["thuban.py"],
974     packages = ["Thuban", "Thuban.Lib", "Thuban.Model", "Thuban.UI"],
975     ext_modules = extensions,
976     py_modules = py_modules,
977     data_files = data_files,
978    
979     # defaults for the install command
980     options = {"install":
981     # prefix defaults to python's prefix normally
982     {"prefix": prefix,
983     # make sure both libs and scripts are installed in the
984     # same directory.
985 bh 200 "install_lib": "$base/lib/thuban",
986     "install_scripts": "$base/lib/thuban",
987     "install_data": "$base/lib/thuban",
988 bh 6
989     # Don't print warning messages about the lib dir not
990     # being on Python's path. The libraries are Thuban
991     # specific and are installed just for Thuban. They'll
992     # be automatically on Python's path when Thuban is run
993     "warn_dir": 0,
994 bh 15 },
995     "bdist_inno":
996     {"icons_entries": [InnoIconItem(".\\thuban.py",
997     "Start Thuban",
998     "{app}\\thuban.pyw")],
999     "license_file": "COPYING",
1000     }
1001     },
1002 bh 6 cmdclass = {"build_py": thuban_build_py,
1003     "install_local": InstallLocal,
1004 bh 15 "install": ThubanInstall,
1005 bh 19 "bdist_rpm": thuban_bdist_rpm,
1006 bh 67 "bdist_inno": thuban_bdist_inno,
1007     "data_dist": data_dist
1008 bh 15 })
1009 bh 6
1010 bh 15

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26