/[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 555 - (hide annotations)
Tue Mar 25 16:21:23 2003 UTC (21 years, 11 months ago) by jonathan
Original Path: trunk/thuban/setup.py
File MIME type: text/x-python
File size: 38451 byte(s)
Added custom script bdist_rpm_build_script so that when the rpm is built
the path to wx-config is correct.

1 bh 452 # Copyright (c) 2001, 2002, 2003 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 jonathan 515 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 bh 15
88 jonathan 515
89 bh 6 #
90 jonathan 515 # Unless you use a wxPython version other than 2.4.0, you probably
91 bh 6 # shouldn't have to modify anything below here
92     ##################################################################
93    
94     # Installation prefix. Just install relative to current directory by
95     # default. This is only the default value, you can override it on
96     # the command line with the install command's --prefix option
97     prefix = r"install"
98    
99 bh 212 # 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 bh 6 # 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
109     # wxPython 2.3.1. They may have to be modified for other versions.
110    
111     # there's no config script.
112     wx_config_script = ""
113    
114     # the values of wx_defs and wx_libs. copied from the wxPython
115     # setup.py
116     wx_defs = [ ('WIN32', None), # Some of these are no longer
117     ('__WIN32__', None), # necessary. Anybody know which?
118     ('_WINDOWS', None),
119     ('__WINDOWS__', None),
120     ('WINVER', '0x0400'),
121     ('__WIN95__', None),
122     ('STRICT', None),
123    
124     ('__WXMSW__', None),
125     ('WXUSINGDLL', '1'),
126    
127     ('SWIG_GLOBAL', None),
128     ('HAVE_CONFIG_H', None),
129     ('WXP_USE_THREAD', '1'),
130     ]
131    
132 jonathan 515 wx_incdirs = wx_inc
133     wx_libdirs = wx_lib
134     wx_libs = ["wxmsw24h"]
135    
136 bh 6 wx_libs = wx_libs + ['kernel32', 'user32', 'gdi32', 'comdlg32',
137     'winspool', 'winmm', 'shell32', 'oldnames',
138     'comctl32', 'ctl3d32', 'odbc32', 'ole32', 'oleaut32',
139     'uuid', 'rpcrt4', 'advapi32', 'wsock32']
140     else:
141     raise RuntimeError("Unsupported platform " + os.name)
142    
143    
144     ######################################################################
145     #
146     # There's nothing beyond this point that has to be modified for a
147     # normal installation
148     #
149     ######################################################################
150    
151    
152     #
153     # Functions to determine wxWindows config on POSIX systems
154     #
155    
156     def run_script(cmdline):
157     """Run command and return its stdout or none in case of errors"""
158     pipe = os.popen(cmdline)
159     result = pipe.read()
160     if pipe.close() is not None:
161     print '"' + cmdline + '"', 'failed'
162     return None
163     return result
164    
165    
166     def run_wx_script(command):
167 bh 19 # first, determine the C++ preprocessor flags Use --cflags here
168     # 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 bh 6 if flags is None:
172     return 0
173     for flag in split(flags):
174     start = flag[:2]
175     value = flag[2:]
176     if start == "-I":
177     wx_incdirs.append(value)
178     elif start == "-D":
179     wx_defs.append((value, None))
180    
181     # determine the library flags
182     flags = run_script(command + ' --libs')
183     if flags is None:
184     return 0
185     for flag in split(flags):
186     start = flag[:2]
187     value = flag[2:]
188     if start == "-L":
189     wx_libdirs.append(value)
190     elif start == "-l":
191     wx_libs.append(value)
192    
193     if wx_config_script:
194     # if there's a wx config script, run it to determine the configuration
195     run_wx_script(wx_config_script)
196    
197    
198    
199     #
200     # Define some extension and python modules
201     #
202     # The C-extension names are prefixed woth "Lib." so they get put into
203     # the Lib/ subdirectory. Lib/ is not really a package but distutils
204     # doesn't care
205    
206     # subdirectory containing the extensions
207     ext_dir = "extensions"
208    
209     # subdirectory with some shapelib files
210     shp_dir = ext_dir + "/shapelib"
211    
212     # lists to fill with the module descriptions
213     extensions = []
214     py_modules = []
215    
216    
217     #
218     # Thuban specific modules
219     #
220    
221     extensions.append(Extension("Lib.wxproj",
222 bh 97 [ext_dir + "/thuban/wxproj.cpp"],
223     include_dirs = ([shp_dir, proj4_incdir,
224     ext_dir + "/pyshapelib/"]
225     + wx_incdirs),
226 bh 6 define_macros = wx_defs,
227     library_dirs = [proj4_libdir] + wx_libdirs,
228     libraries = [proj4_lib] + wx_libs))
229    
230     #
231     # shapelib wrappers are also distributed with thuban
232     #
233    
234     extensions.append(Extension("Lib.shapelibc",
235     [ext_dir + "/pyshapelib/shapelib_wrap.c",
236 bh 142 shp_dir + "/shpopen.c",
237     shp_dir + "/shptree.c"],
238 bh 6 include_dirs = [shp_dir]))
239 bh 142 extensions.append(Extension("Lib.shptree",
240     [ext_dir + "/pyshapelib/shptreemodule.c"],
241     include_dirs = [shp_dir]))
242 bh 6 extensions.append(Extension("Lib.dbflibc",
243     [ext_dir + "/pyshapelib/dbflib_wrap.c",
244     shp_dir + "/dbfopen.c"],
245     include_dirs = [shp_dir]))
246 bh 164 for name in ("shapelib", "dbflib"):
247 bh 6 py_modules.append(ext_dir + "/pyshapelib/" + name)
248    
249     #
250     # PROJ4 bindings are also distributed with thuban
251     #
252     extensions.append(Extension("Lib.Projectionc",
253     [ext_dir + "/pyprojection/Projection_wrap.c"],
254     include_dirs = [proj4_incdir],
255     library_dirs = [proj4_libdir],
256     libraries = [proj4_lib]))
257     py_modules.append(ext_dir + "/pyprojection/Projection")
258    
259    
260     #
261     # Data files
262     #
263    
264     data_files = []
265    
266     # bitmaps
267 bh 15 dir = "Resources/Bitmaps"
268 bh 6 bitmaps = []
269     for file in os.listdir(os.path.join("Resources", "Bitmaps")):
270     if string.lower(file[-4:]) == ".xpm":
271 bh 15 bitmaps.append(dir + '/' + file)
272 bh 6 data_files.append((dir, bitmaps))
273    
274     #
275     # Command definitions
276     #
277     # So far distutils are only meant to distribute python extensions, not
278     # complete applications, so we have to redefine a few commands
279 bh 67 #
280 bh 6
281    
282 bh 67 # Much of the data_dist command is directly copied from the distutils'
283     # sdist command
284     class data_dist(Command):
285 bh 6
286 bh 67 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    
410 bh 6 class InstallLocal(Command):
411    
412     """
413     A new install command to just link (or copy, on non-POSIX systems)
414     the extension modules to the top directory so that Thuban can be run
415     directly from the source dir.
416     """
417    
418     description =\
419 bh 71 "Create some symlinks so you can run thuban from the source directory"
420 bh 6
421     user_options = [
422     ('skip-build', None, "skip the build steps"),
423 bh 253 ('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 bh 6 ]
428    
429 bh 253 boolean_options = ["create-init-module"]
430     negative_opt = {'dont-create-init-module' : 'create-init-module'}
431    
432    
433 bh 6 def initialize_options (self):
434     self.extensions = None
435     self.build_dir = None
436     self.skip_build = None
437 bh 253 self.create_init_module = None
438 bh 6
439     def finalize_options (self):
440     self.set_undefined_options("install",
441     ("build_lib", "build_dir"),
442     ('skip_build', 'skip_build'))
443     self.extensions = self.distribution.ext_modules
444 bh 253 if self.create_init_module is None:
445     # by default we create the init module
446     self.create_init_module = 1
447 bh 6
448     def run(self):
449     # Make sure we have built everything we need first
450     self.build()
451    
452     # now do the work. Simply link or copy the Lib dir
453     libdir = os.path.join(self.build_dir, "Lib")
454     if os.name == "posix":
455 bh 71 # on posix, just link the Lib dir
456 bh 6 self.link_dir(libdir, "Lib")
457     else:
458     self.copy_tree(libdir, "Lib")
459    
460 bh 253 # 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 bh 6 def link_dir(self, src, dest):
469     """Create a symbolic link dest pointing to src"""
470     if self.verbose:
471 bh 15 self.announce("symlinking %s -> %s" % (src, dest))
472 bh 6 if self.dry_run:
473     return
474    
475     if not (os.path.exists(dest) and os.path.samefile(src, dest)):
476     os.symlink(src, dest)
477    
478     def build (self):
479     if not self.skip_build:
480     if self.distribution.has_pure_modules():
481     self.run_command('build_py')
482     if self.distribution.has_ext_modules():
483     self.run_command('build_ext')
484    
485    
486    
487     class thuban_build_py(build_py):
488    
489     """
490 bh 8 A new build_py that can deal with both packages and modules in one
491     distribution.
492 bh 6 """
493    
494 bh 452 # 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 bh 6 def run(self):
500 bh 8 """The same the as the original in build_py revision 1.33 except
501 bh 6 that this allows both packages and modules to be in one
502     distribution
503     """
504     if not self.py_modules and not self.packages:
505     return
506    
507     # Now we're down to two cases: 'py_modules' only and 'packages' only.
508     if self.py_modules:
509     self.build_modules()
510     if self.packages:
511     self.build_packages()
512    
513     self.byte_compile(self.get_outputs(include_bytecode=0))
514    
515     def find_modules (self):
516     """Thuban specific version of build_py.find_modules. Unlike the
517     original version, we assume that the modules in self.py_modules
518     can contain directories and are all to be placed into the same
519     subdirectory, Lib, in the build directory. This is achieved by
520     returning the modules as a list (package, module, filename)
521     where package is 'Lib', module is the basename of the module name
522     and filename is the filename relative to the package root.
523     """
524     modules = []
525     for module in self.py_modules:
526     module_base = os.path.basename(module)
527     module_file = module + ".py"
528     if not self.check_module(module, module_file):
529     continue
530    
531     modules.append(("Lib", module_base, module_file))
532     return modules
533    
534 bh 15 def find_all_modules (self):
535     # same as find_all_modules of the original build_py command
536     # (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 bh 6
547 bh 15 return modules
548    
549    
550 bh 253 thubaninit_contents_start = """
551 bh 204 # 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 bh 15
556 bh 204 Usage:
557    
558     import thubaninit
559     import Thuban
560     '''
561     import sys, os
562 bh 253 """
563    
564     thubaninit_contents_thubaninitdir = """
565 bh 204 sys.path.insert(0, %(thubandir)s)
566 bh 253 """
567     thubaninit_contents_otherdirs = """
568 bh 204 # 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 bh 253 def thubaninit_contents(thubandir):
578     """Return the contents of the the thubaninit file as a list of lines.
579 bh 204
580 bh 253 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 bh 6 class ThubanInstall(install):
593    
594 bh 8 """
595     Thuban specific install command.
596    
597     Extend the standard install command to symlink the installed script
598     to $prefix/bin/
599     """
600 bh 15
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 bh 204 "List of filenames or (src, dest) pairs describing"
608 bh 15 " extra files to install "
609     "(can only be set from witin setup.py"),
610 bh 204
611 bh 212 ("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 bh 204 "Directory in which to create the init module."
617     " Defaults to Python's site-packages directory."),
618 bh 15 ])
619    
620     boolean_options = install.boolean_options[:]
621     boolean_options.append("do-symlink")
622 bh 204 boolean_options.append("create-init-module")
623 bh 15
624     def initialize_options(self):
625     self.do_symlink = None
626     self.extra_files = []
627 bh 212
628     # initialize the create_init_module flag from the global
629     # determined at runtime
630     self.create_init_module = create_init_module
631 bh 204 self.init_module_dir = None
632 bh 15 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 bh 204 self.expand_with_pure_python_dirs(["init_module_dir"])
642 bh 15
643 bh 204 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 bh 6 def run(self):
676     install.run(self)
677 bh 15 for item in self.extra_files:
678     if type(item) == TupleType:
679     src, dest = item
680     else:
681     src = dest = item
682 bh 266 self.copy_file(convert_path(src),
683 bh 15 os.path.join(self.root, convert_path(dest)))
684    
685     if os.name == "posix" and self.do_symlink:
686 bh 19 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 bh 6 bindir = os.path.join(self.prefix, "bin")
691 bh 18 if self.root:
692     bindir = change_root(self.root, bindir)
693 bh 6 binfile = os.path.join(bindir, "thuban")
694     self.mkpath(bindir)
695 bh 19 self.link_file(scriptfile, binfile)
696 bh 6
697 bh 204 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 bh 266 contents = thubaninit_contents(self.install_lib_orig)
703 bh 204 self.mkpath(os.path.dirname(initfilename))
704 bh 253 self.execute(write_file, (initfilename, contents),
705 bh 204 "Create %s" % initfilename)
706    
707 bh 19 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 bh 204 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 bh 19
727 bh 15 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 bh 19 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 bh 204 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 bh 15 return outputs
747 bh 6
748 bh 19
749 bh 203 # scripts to override some of the commands put into the spec-file by the
750     # bdist_rpm command.
751    
752 bh 19 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 jonathan 555 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 bh 203 bdist_rpm_install_script = '''
764     %(python)s setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES \
765     --prefix=%(prefix)s
766     '''
767 bh 19
768 bh 266
769 bh 19 class thuban_bdist_rpm(bdist_rpm):
770    
771     """Thuban specific RPM distribution command"""
772    
773 bh 203 user_options = bdist_rpm.user_options[:]
774     user_options.extend([("prefix=", None, "Install prefix for the RPM"),
775     ])
776    
777 bh 90 def initialize_options(self):
778 bh 203 # per default, RPMs are installed in /usr
779     self.prefix = "/usr/"
780 bh 19
781 bh 203 # 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 jonathan 555 open("bdist_rpm_build", "w").close()
787 bh 203 open("bdist_rpm_install", "w").close()
788 bh 90 bdist_rpm.initialize_options(self)
789 bh 19
790 bh 203 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 jonathan 555
795     build = bdist_rpm_build_script % {"python": self.python,
796     "prefix": self.prefix}
797     open("bdist_rpm_build", "w").write(build)
798    
799 bh 203 install = bdist_rpm_install_script % {"python": self.python,
800     "prefix": self.prefix}
801     open("bdist_rpm_install", "w").write(install)
802 bh 19
803 bh 203 #
804     return bdist_rpm._make_spec_file(self)
805    
806    
807 bh 15 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 jonathan 533
887 bh 15 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 bh 266 # and invoke
910 bh 15 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 bh 266
976 bh 15 return iss
977    
978    
979     class InnoIconItem:
980    
981 bh 54 """Describe one item for the start menu for the Inno Setup installer"""
982 bh 15
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 bh 266
992 bh 15 class thuban_bdist_inno(bdist_inno):
993    
994     """Thuban specific Inno Setup stuff"""
995    
996     def run(self):
997     install_options = {
998     "prefix": ".",
999 jonathan 533 "install_lib": "$base",
1000     "install_data": "$base",
1001 bh 15 "install_scripts": "$base",
1002     "warn_dir": 0,
1003     "extra_files": ["COPYING", "Lib/proj.dll"],
1004     }
1005 bh 54 # 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 jonathan 533
1009 bh 15 bdist_inno.run(self, install_options)
1010 bh 266
1011 jonathan 543 class thuban_build_docs(Command):
1012 bh 266
1013 jonathan 543 """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 bh 15 #
1027     # Run the script
1028     #
1029    
1030    
1031 bh 6 long_description = """\
1032     Thuban is a viewer for geographic data written in Python
1033     """
1034    
1035 bh 15 setup(name = "Thuban",
1036 jonathan 532 version = "0.2.0",
1037 bh 6 description = "Geographic data viewer",
1038     long_description = long_description,
1039     licence = "GPL",
1040     author = "Intevation GmbH",
1041     author_email = "[email protected]",
1042 bh 209 url = "http://thuban.intevation.de/",
1043 bh 6
1044     scripts = ["thuban.py"],
1045     packages = ["Thuban", "Thuban.Lib", "Thuban.Model", "Thuban.UI"],
1046     ext_modules = extensions,
1047     py_modules = py_modules,
1048     data_files = data_files,
1049    
1050     # defaults for the install command
1051     options = {"install":
1052     # prefix defaults to python's prefix normally
1053     {"prefix": prefix,
1054     # make sure both libs and scripts are installed in the
1055     # same directory.
1056 bh 200 "install_lib": "$base/lib/thuban",
1057     "install_scripts": "$base/lib/thuban",
1058     "install_data": "$base/lib/thuban",
1059 bh 6
1060     # Don't print warning messages about the lib dir not
1061     # being on Python's path. The libraries are Thuban
1062     # specific and are installed just for Thuban. They'll
1063     # be automatically on Python's path when Thuban is run
1064     "warn_dir": 0,
1065 bh 15 },
1066     "bdist_inno":
1067     {"icons_entries": [InnoIconItem(".\\thuban.py",
1068     "Start Thuban",
1069     "{app}\\thuban.pyw")],
1070     "license_file": "COPYING",
1071     }
1072     },
1073 bh 6 cmdclass = {"build_py": thuban_build_py,
1074     "install_local": InstallLocal,
1075 bh 15 "install": ThubanInstall,
1076 bh 19 "bdist_rpm": thuban_bdist_rpm,
1077 bh 67 "bdist_inno": thuban_bdist_inno,
1078 jonathan 543 "data_dist": data_dist,
1079     "build_docs": thuban_build_docs
1080 bh 15 })
1081 bh 6
1082 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