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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 671 - (show annotations)
Tue Apr 15 18:09:47 2003 UTC (21 years, 10 months ago) by bh
Original Path: trunk/thuban/setup.py
File MIME type: text/x-python
File size: 38461 byte(s)
* Thuban/__init__.py (_): Implement the translation function for
real using the python gettext module.

* Thuban/UI/classifier.py (ClassTable.GetRowLabelValue): Don't
translate empty strings.

* Thuban/UI/application.py (ThubanApplication.read_startup_files):
Add a missing space to a warning message

* po/README: New. Notes about the management of the translation
files.

* po/Makefile: New. Makefile to help manage the translation files.

* po/es.po: New. Spanish translation by Daniel Calvelo Aros

* MANIFEST.in: Include the *.mo files in Resources/Locale and the
translations and support files in po/

* setup.py (data_files): Add the *.mo files to the data_files too

* README: Add note about the translations when building from CVS

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26