/[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 18 - (hide annotations)
Mon Sep 3 16:25:09 2001 UTC (23 years, 6 months ago) by bh
Original Path: trunk/thuban/setup.py
File MIME type: text/x-python
File size: 23111 byte(s)
* Thuban/UI/mainwindow.py (MainWindow.AddLayer): Fit the map to
the window when the first layer is added to the map.

* setup.py (ThubanInstall.run): Honor the build root (self.root)
when linking thuban.py to <prefix>/bin

1 bh 6 # Copyright (c) 2001 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 bh 15 from types import TupleType
20 bh 6 from distutils.core import setup, Extension, Command
21     from distutils.command.install import install
22     from distutils.command.build_py import build_py
23 bh 15 from distutils.file_util import write_file
24 bh 18 from distutils.util import convert_path, change_root
25 bh 6
26     import distutils
27    
28     from string import split
29     import string
30    
31     if os.name == "posix":
32     ###################################################################
33     # Posix configuration. Adapt this if you're running some kind of
34     # Unix like system.
35    
36     # Directories where Proj4 is installed
37     proj4_prefix = "/usr/local/"
38     proj4_incdir = os.path.join(proj4_prefix, "include")
39     proj4_libdir = os.path.join(proj4_prefix, "lib")
40     proj4_lib = "proj"
41    
42    
43     # You shpuldn't have to modify anything below here
44     ###################################################################
45    
46     # The installation prefix (similar to autoconf's --prefix). This is
47     # only the default value, you can override it on the command line
48     # with the install command's --prefix option
49     prefix = "/usr/local/"
50    
51     # On POSIX-systems we run wxgtk-config to determine the C++-compiler
52     # flags
53     wx_config_script = "wxgtk-config"
54     # These lists will be filled automatically below
55     wx_defs = []
56     wx_incdirs = []
57     wx_libdirs = []
58     wx_libs = []
59    
60     elif os.name == "nt":
61     #################################################################
62     # Windows configuration.
63     #
64    
65     # Directories where Proj4 is installed
66     proj4_prefix = r"D:\cygwin\home\user\proj-4.4.3\src"
67     proj4_incdir = proj4_prefix
68     proj4_libdir = proj4_prefix
69     proj4_lib = "proj_i"
70    
71 bh 15 # Define include and lib directories for wxWindows and
72     wx_prefix = r"D:\wx230"
73     wx_inc = os.path.join(wx_prefix, "include")
74     wx_lib = os.path.join(wx_prefix, "lib")
75    
76 bh 6 #
77     # Unless you use a wxPython version other than 2.3.1, you probably
78     # shouldn't have to modify anything below here
79     ##################################################################
80    
81     # Installation prefix. Just install relative to current directory by
82     # default. This is only the default value, you can override it on
83     # the command line with the install command's --prefix option
84     prefix = r"install"
85    
86     # There doesn't seem to be an easy way to get at the wx compiler
87     # flags, so we define them here. These flags work for us with
88     # wxPython 2.3.1. They may have to be modified for other versions.
89    
90     # there's no config script.
91     wx_config_script = ""
92    
93     # the values of wx_defs and wx_libs. copied from the wxPython
94     # setup.py
95     wx_defs = [ ('WIN32', None), # Some of these are no longer
96     ('__WIN32__', None), # necessary. Anybody know which?
97     ('_WINDOWS', None),
98     ('__WINDOWS__', None),
99     ('WINVER', '0x0400'),
100     ('__WIN95__', None),
101     ('STRICT', None),
102    
103     ('__WXMSW__', None),
104     ('WXUSINGDLL', '1'),
105    
106     ('SWIG_GLOBAL', None),
107     ('HAVE_CONFIG_H', None),
108     ('WXP_USE_THREAD', '1'),
109     ]
110    
111     wx_incdirs = [wx_inc]
112     wx_libdirs = [wx_lib]
113     wx_libs = ["wx23_1h"]
114     wx_libs = wx_libs + ['kernel32', 'user32', 'gdi32', 'comdlg32',
115     'winspool', 'winmm', 'shell32', 'oldnames',
116     'comctl32', 'ctl3d32', 'odbc32', 'ole32', 'oleaut32',
117     'uuid', 'rpcrt4', 'advapi32', 'wsock32']
118     else:
119     raise RuntimeError("Unsupported platform " + os.name)
120    
121    
122     ######################################################################
123     #
124     # There's nothing beyond this point that has to be modified for a
125     # normal installation
126     #
127     ######################################################################
128    
129    
130     #
131     # Functions to determine wxWindows config on POSIX systems
132     #
133    
134     def run_script(cmdline):
135     """Run command and return its stdout or none in case of errors"""
136     pipe = os.popen(cmdline)
137     result = pipe.read()
138     if pipe.close() is not None:
139     print '"' + cmdline + '"', 'failed'
140     return None
141     return result
142    
143    
144     def run_wx_script(command):
145     # first, determine the C++ preprocessor flags
146     flags = run_script(command + ' --cxxflags ')
147     if flags is None:
148     return 0
149     for flag in split(flags):
150     start = flag[:2]
151     value = flag[2:]
152     if start == "-I":
153     wx_incdirs.append(value)
154     elif start == "-D":
155     wx_defs.append((value, None))
156    
157     # determine the library flags
158     flags = run_script(command + ' --libs')
159     if flags is None:
160     return 0
161     for flag in split(flags):
162     start = flag[:2]
163     value = flag[2:]
164     if start == "-L":
165     wx_libdirs.append(value)
166     elif start == "-l":
167     wx_libs.append(value)
168    
169     if wx_config_script:
170     # if there's a wx config script, run it to determine the configuration
171     run_wx_script(wx_config_script)
172    
173    
174    
175     #
176     # Define some extension and python modules
177     #
178     # The C-extension names are prefixed woth "Lib." so they get put into
179     # the Lib/ subdirectory. Lib/ is not really a package but distutils
180     # doesn't care
181    
182     # subdirectory containing the extensions
183     ext_dir = "extensions"
184    
185     # subdirectory with some shapelib files
186     shp_dir = ext_dir + "/shapelib"
187    
188     # lists to fill with the module descriptions
189     extensions = []
190     py_modules = []
191    
192    
193     #
194     # Thuban specific modules
195     #
196    
197     extensions.append(Extension("Lib.wxproj",
198     [ext_dir + "/thuban/wxproj.cpp",
199     shp_dir + "/shpopen.c"],
200     include_dirs = [shp_dir, proj4_incdir] +wx_incdirs,
201     define_macros = wx_defs,
202     library_dirs = [proj4_libdir] + wx_libdirs,
203     libraries = [proj4_lib] + wx_libs))
204    
205     #
206     # shapelib wrappers are also distributed with thuban
207     #
208    
209     extensions.append(Extension("Lib.shapelibc",
210     [ext_dir + "/pyshapelib/shapelib_wrap.c",
211     shp_dir + "/shpopen.c"],
212     include_dirs = [shp_dir]))
213     extensions.append(Extension("Lib.dbflibc",
214     [ext_dir + "/pyshapelib/dbflib_wrap.c",
215     shp_dir + "/dbfopen.c"],
216     include_dirs = [shp_dir]))
217     for name in ("shapelib", "dbflib"):
218     py_modules.append(ext_dir + "/pyshapelib/" + name)
219    
220     #
221     # PROJ4 bindings are also distributed with thuban
222     #
223     extensions.append(Extension("Lib.Projectionc",
224     [ext_dir + "/pyprojection/Projection_wrap.c"],
225     include_dirs = [proj4_incdir],
226     library_dirs = [proj4_libdir],
227     libraries = [proj4_lib]))
228     py_modules.append(ext_dir + "/pyprojection/Projection")
229    
230    
231     #
232     # Data files
233     #
234    
235     data_files = []
236    
237     # bitmaps
238 bh 15 dir = "Resources/Bitmaps"
239 bh 6 bitmaps = []
240     for file in os.listdir(os.path.join("Resources", "Bitmaps")):
241     if string.lower(file[-4:]) == ".xpm":
242 bh 15 bitmaps.append(dir + '/' + file)
243 bh 6 data_files.append((dir, bitmaps))
244    
245     #
246     # Command definitions
247     #
248     # So far distutils are only meant to distribute python extensions, not
249     # complete applications, so we have to redefine a few commands
250    
251    
252    
253     class InstallLocal(Command):
254    
255     """
256     A new install command to just link (or copy, on non-POSIX systems)
257     the extension modules to the top directory so that Thuban can be run
258     directly from the source dir.
259     """
260    
261     description =\
262     "Create some symlink so you can run thubanfrom the source directory"
263    
264     user_options = [
265     ('skip-build', None, "skip the build steps"),
266     ]
267    
268     def initialize_options (self):
269     self.extensions = None
270     self.build_dir = None
271     self.skip_build = None
272    
273     def finalize_options (self):
274     self.set_undefined_options("install",
275     ("build_lib", "build_dir"),
276     ('skip_build', 'skip_build'))
277     self.extensions = self.distribution.ext_modules
278    
279     def run(self):
280     # Make sure we have built everything we need first
281     self.build()
282    
283     # now do the work. Simply link or copy the Lib dir
284     libdir = os.path.join(self.build_dir, "Lib")
285     if os.name == "posix":
286     # on posix, just lilnk the Lib dir
287     self.link_dir(libdir, "Lib")
288     else:
289     self.copy_tree(libdir, "Lib")
290    
291     def link_dir(self, src, dest):
292     """Create a symbolic link dest pointing to src"""
293     if self.verbose:
294 bh 15 self.announce("symlinking %s -> %s" % (src, dest))
295 bh 6 if self.dry_run:
296     return
297    
298     if not (os.path.exists(dest) and os.path.samefile(src, dest)):
299     os.symlink(src, dest)
300    
301     def build (self):
302     if not self.skip_build:
303     if self.distribution.has_pure_modules():
304     self.run_command('build_py')
305     if self.distribution.has_ext_modules():
306     self.run_command('build_ext')
307    
308    
309    
310     class thuban_build_py(build_py):
311    
312     """
313 bh 8 A new build_py that can deal with both packages and modules in one
314     distribution.
315 bh 6 """
316    
317     def run(self):
318 bh 8 """The same the as the original in build_py revision 1.33 except
319 bh 6 that this allows both packages and modules to be in one
320     distribution
321     """
322     if not self.py_modules and not self.packages:
323     return
324    
325     # Now we're down to two cases: 'py_modules' only and 'packages' only.
326     if self.py_modules:
327     self.build_modules()
328     if self.packages:
329     self.build_packages()
330    
331     self.byte_compile(self.get_outputs(include_bytecode=0))
332    
333     def find_modules (self):
334     """Thuban specific version of build_py.find_modules. Unlike the
335     original version, we assume that the modules in self.py_modules
336     can contain directories and are all to be placed into the same
337     subdirectory, Lib, in the build directory. This is achieved by
338     returning the modules as a list (package, module, filename)
339     where package is 'Lib', module is the basename of the module name
340     and filename is the filename relative to the package root.
341     """
342     modules = []
343     for module in self.py_modules:
344     module_base = os.path.basename(module)
345     module_file = module + ".py"
346     if not self.check_module(module, module_file):
347     continue
348    
349     modules.append(("Lib", module_base, module_file))
350     return modules
351    
352 bh 15 def find_all_modules (self):
353     # same as find_all_modules of the original build_py command
354     # (rev. 1.33) but handle installations with both modules and
355     # packages. Needed here so tha the get_outputs works correctly
356     modules = []
357     if self.py_modules:
358     modules.extend(self.find_modules())
359     if self.packages:
360     for package in self.packages:
361     package_dir = self.get_package_dir(package)
362     m = self.find_package_modules(package, package_dir)
363     modules.extend(m)
364 bh 6
365 bh 15 return modules
366    
367    
368    
369 bh 6 class ThubanInstall(install):
370    
371 bh 8 """
372     Thuban specific install command.
373    
374     Extend the standard install command to symlink the installed script
375     to $prefix/bin/
376     """
377 bh 15
378     user_options = install.user_options[:]
379     user_options.extend([("do-symlink", None,
380     "Create a symlink to the script in <prefix>/bin."
381     "(default on posix systems and only relevant there)"),
382    
383     ("extra-files", None,
384     "List of filenames or (src, dest) pairs describing "
385     " extra files to install "
386     "(can only be set from witin setup.py"),
387     ])
388    
389     boolean_options = install.boolean_options[:]
390     boolean_options.append("do-symlink")
391    
392     def initialize_options(self):
393     self.do_symlink = None
394     self.extra_files = []
395     install.initialize_options(self)
396    
397     def finalize_options(self):
398     if self.do_symlink is None:
399     if os.name == "posix":
400     self.do_symlink = 1
401     else:
402     self.do_symlink = 0
403     install.finalize_options(self)
404    
405 bh 6 def run(self):
406     install.run(self)
407 bh 15 for item in self.extra_files:
408     if type(item) == TupleType:
409     src, dest = item
410     else:
411     src = dest = item
412     self.copy_file(convert_path(src),
413     os.path.join(self.root, convert_path(dest)))
414    
415     if os.name == "posix" and self.do_symlink:
416 bh 6 scriptfile = os.path.join(self.install_scripts, "thuban.py")
417     bindir = os.path.join(self.prefix, "bin")
418 bh 18 if self.root:
419     bindir = change_root(self.root, bindir)
420 bh 6 binfile = os.path.join(bindir, "thuban")
421     self.mkpath(bindir)
422     self.copy_file(scriptfile, binfile, link="sym")
423    
424 bh 15 def get_outputs (self):
425     outputs = install.get_outputs(self)
426     for item in self.extra_files:
427     if type(item) == TupleType:
428     src, dest = item
429     else:
430     src = dest = item
431     outputs.append(os.path.join(self.root, convert_path(dest)))
432     return outputs
433 bh 6
434 bh 15 class bdist_inno(Command):
435    
436     """Command to create a windows installer with Inno Setup"""
437    
438     description = "Create a windows installer with Inno Setup"
439    
440     user_options = [
441     ('skip-build', None, "skip the build steps"),
442     ('bdist-dir=', None,
443     "temporary directory for creating the distribution"),
444     ('run-inno', None,
445     "Run inno-setup to create the installer. On by default on nt"),
446     ('iss-name', None,
447     "The name of the iss file to generate. "
448     "Shouldn't contain directories"),
449    
450     # Parameters for the Inno Setup script
451     ('copyright', None, "Copyright notice for the Inno Setup file"),
452     ('default-dir-name', None,
453     "Default installation directory. Defaults to '{pf}\\<name>'"),
454     ('default-group-name', None,
455     "Default program group name. Defaults to <name>'"),
456     ("license-file", None, "File containing the license."),
457     ("output-basename", None,
458     "Base filename for the Inno Setup output "
459     "(defaults to <name>-<version>-<issrevision>)."),
460     ("iss-revision", None,
461     "revision of the generated installer of the package version"),
462    
463     ("icons-entries", None,
464     "List if InnoIconItems "
465     "(this can only be set from inside the setup.py script)"),
466     ]
467    
468     boolean_options = ["do-symlink"]
469    
470     def initialize_options(self):
471     self.skip_build = 0
472     self.bdist_dir = None
473     self.run_inno = None
474     self.iss_name = None
475     self.copyright = ""
476     self.default_dir_name = None
477     self.default_group_name = None
478     self.license_file = None
479     self.output_basename = None
480     self.iss_revision = None
481     self.icons_entries = []
482    
483     def finalize_options(self):
484     self.set_undefined_options("install",
485     ('skip_build', 'skip_build'))
486     if self.bdist_dir is None:
487     bdist_base = self.get_finalized_command('bdist').bdist_base
488     self.bdist_dir = os.path.join(bdist_base, 'inno')
489    
490     if self.run_inno is None:
491     self.run_inno = os.name == "nt"
492    
493     name = self.distribution.get_name()
494     if self.iss_name is None:
495     self.iss_name = name + '.iss'
496    
497     if self.default_dir_name is None:
498     self.default_dir_name = "{pf}\\" + name
499     if self.default_group_name is None:
500     self.default_group_name = name
501    
502     if self.iss_revision is None:
503     self.iss_revision = 0
504     if self.output_basename is None:
505     self.output_basename = "%s-%s-%d" \
506     % (name, self.distribution.get_version(),
507     self.iss_revision)
508    
509     def run(self, install_options = None):
510     """Execute the command. install_options if given, should be a
511     directory of additional options to set in the install step"""
512     # Obviously have to build before we can install
513     if not self.skip_build:
514     self.run_command('build')
515    
516     # Install in a temporary directory
517     install = self.reinitialize_command('install')
518     install.root = self.bdist_dir
519     if install_options is not None:
520     for key, value in install_options.items():
521     setattr(install, key, value)
522     if os.name != 'nt':
523     # Must force install to use the 'nt' scheme;
524     install.select_scheme('nt')
525     # don't make a symlink because we're simulating windows, so
526     # that we can generate the iss-file even on Linux
527     install.do_symlink = 0
528    
529     self.announce("installing to %s" % self.bdist_dir)
530     install.ensure_finalized()
531     install.run()
532    
533     # Create the iss file
534     iss_file = os.path.join(self.bdist_dir, self.iss_name)
535     self.execute(write_file, (iss_file, self.generate_iss()),
536     "Create Inno Setup script file %s" % iss_file)
537    
538     # and invoke
539     if self.run_inno:
540     self.spawn(["iscc", iss_file])
541    
542     def generate_iss(self):
543     """Return the contents of the iss file as list of strings, one
544     string per line"""
545    
546     # first, turn the icons entries into a more usable form
547     icons = {}
548     for item in self.icons_entries:
549     icons[item.filename] = item
550    
551     iss = []
552    
553     name = self.distribution.get_name()
554     iss.extend(["[Setup]",
555     "AppName=" + name,
556     "AppVerName=" + name + " "+self.distribution.get_version(),
557     "DefaultDirName=" + self.default_dir_name,
558     "DefaultGroupName=" + self.default_group_name,
559     ])
560     if self.copyright:
561     iss.append("AppCopyright=" + self.copyright)
562     if self.license_file:
563     iss.append("LicenseFile=" + self.license_file)
564    
565     iss.append("OutputBasefilename=" + self.output_basename)
566    
567     iss.append("")
568     iss.append("[Files]")
569    
570     install = self.get_finalized_command("install")
571     install_scripts = self.get_finalized_command("install_scripts")
572     script_files = install_scripts.get_outputs()
573     prefixlen = len(self.bdist_dir) + len(os.sep)
574     for filename in install.get_outputs():
575     filename = filename[prefixlen:]
576     icon = icons.get(filename)
577     dirname = os.path.dirname(filename)
578     if os.name != "nt":
579     # change the separators to \ on non-windos systems
580     filename = string.join(string.split(filename, os.sep), "\\")
581     dirname = string.join(string.split(dirname, os.sep), "\\")
582     line = 'Source: "%s"' % filename
583     if icon is not None:
584     # install it as defined in the icon object
585     backslash = string.rfind(icon.install_name, "\\")
586     if backslash >= 0:
587     dirname = icon.install_name[:backslash]
588     basename = icon.install_name[backslash + 1:]
589     else:
590     dirname = ""
591     basename = icon.install_name
592     line = '%s; DestDir: "%s"; DestName: "%s"' % (line, dirname,
593     basename)
594     else:
595     line = line + '; DestDir: "{app}\\%s"' % (dirname)
596     iss.append(line)
597    
598     iss.append("")
599     iss.append("[Icons]")
600     for icon in self.icons_entries:
601     line = 'Name: "{group}\\%s"; Filename: "%s";' \
602     % (icon.title, icon.install_name)
603     iss.append(line)
604    
605     return iss
606    
607    
608     class InnoIconItem:
609    
610     """Describe one item for he start menu for the Inno Setup installer"""
611    
612     def __init__(self, filename, title, install_name = None):
613     self.filename = filename
614     self.title = title
615     if install_name is not None:
616     self.install_name = install_name
617     else:
618     self.install_name = filename
619    
620    
621     class thuban_bdist_inno(bdist_inno):
622    
623     """Thuban specific Inno Setup stuff"""
624    
625     def run(self):
626     install_options = {
627     "prefix": ".",
628     "install_scripts": "$base",
629     "warn_dir": 0,
630     "extra_files": ["COPYING", "Lib/proj.dll"],
631     }
632     bdist_inno.run(self, install_options)
633    
634    
635     #
636     # Run the script
637     #
638    
639    
640 bh 6 long_description = """\
641     Thuban is a viewer for geographic data written in Python
642     """
643    
644 bh 15 setup(name = "Thuban",
645 bh 6 version = "0.0.3",
646     description = "Geographic data viewer",
647     long_description = long_description,
648     licence = "GPL",
649     author = "Intevation GmbH",
650     author_email = "[email protected]",
651     url = "ftp:intevation.de/",
652    
653     scripts = ["thuban.py"],
654     packages = ["Thuban", "Thuban.Lib", "Thuban.Model", "Thuban.UI"],
655     ext_modules = extensions,
656     py_modules = py_modules,
657     data_files = data_files,
658    
659     # defaults for the install command
660     options = {"install":
661     # prefix defaults to python's prefix normally
662     {"prefix": prefix,
663     # make sure both libs and scripts are installed in the
664     # same directory.
665     "install_lib": "$base/thuban",
666     "install_scripts": "$base/thuban",
667 bh 15 "install_data": "$base/thuban",
668 bh 6
669     # Don't print warning messages about the lib dir not
670     # being on Python's path. The libraries are Thuban
671     # specific and are installed just for Thuban. They'll
672     # be automatically on Python's path when Thuban is run
673     "warn_dir": 0,
674 bh 15 },
675     "bdist_inno":
676     {"icons_entries": [InnoIconItem(".\\thuban.py",
677     "Start Thuban",
678     "{app}\\thuban.pyw")],
679     "license_file": "COPYING",
680     }
681     },
682 bh 6 cmdclass = {"build_py": thuban_build_py,
683     "install_local": InstallLocal,
684 bh 15 "install": ThubanInstall,
685     "bdist_inno": thuban_bdist_inno
686     })
687 bh 6
688 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