use pycompat.popen at more places
[PyX.git] / setup.py
blob3d78d590c30c10ac05f2fa640e50eccc92e481e4
1 #!/usr/bin/env python
2 # -*- encoding: utf-8 -*-
4 """Python package for the generation of PostScript and PDF files
6 PyX is a Python package for the creation of PostScript and PDF files. It
7 combines an abstraction of the PostScript drawing model with a TeX/LaTeX
8 interface. Complex tasks like 2d and 3d plots in publication-ready quality are
9 built out of these primitives.
10 """
12 try:
13 from distutils import log
14 except:
15 log = None
16 from distutils.core import setup, Extension
17 from distutils.util import change_root, convert_path
18 from distutils.command.build_py import build_py
19 from distutils.command.install_data import install_data
20 from distutils.command.install_lib import install_lib
21 import ConfigParser
22 import sys, os
23 import pyx
26 # build list of extension modules
29 ext_modules = []
30 pykpathsea_ext_module = Extension("pyx.pykpathsea",
31 sources=["pyx/pykpathsea.c"],
32 libraries=["kpathsea"])
33 t1code_ext_module = Extension("pyx.font._t1code",
34 sources=["pyx/font/_t1code.c"])
36 # obtain information on which modules have to be built from setup.cfg file
37 cfg = ConfigParser.ConfigParser()
38 cfg.read("setup.cfg")
39 if cfg.has_section("PyX"):
40 if cfg.has_option("PyX", "build_pykpathsea") and cfg.getboolean("PyX", "build_pykpathsea"):
41 ext_modules.append(pykpathsea_ext_module)
42 if cfg.has_option("PyX", "build_t1code") and cfg.getboolean("PyX", "build_t1code"):
43 ext_modules.append(t1code_ext_module)
45 ################################################################################
46 # data files
49 # share/pyx is taken relative to "setup.py install --home=..."
50 # whereas /etc is taken relative to "setup.py install --root=..."
52 data_files = []
54 # variable names in siteconfig.py for a list of files in data_files
55 siteconfignames = {}
57 def adddatafiles(siteconfigname, dir, files):
58 """store siteconfigname for files in siteconfignames and add (dir, files) to data_files"""
59 # convert files to a tuple to make it hashable
60 files = tuple(files)
61 data_files.append((dir, files))
62 siteconfignames[files] = siteconfigname
64 adddatafiles("lfsdir", "share/pyx", ["pyx/lfs/10pt.lfs",
65 "pyx/lfs/11pt.lfs",
66 "pyx/lfs/12pt.lfs",
67 "pyx/lfs/10ptex.lfs",
68 "pyx/lfs/11ptex.lfs",
69 "pyx/lfs/12ptex.lfs",
70 "pyx/lfs/foils17pt.lfs",
71 "pyx/lfs/foils20pt.lfs",
72 "pyx/lfs/foils25pt.lfs",
73 "pyx/lfs/foils30pt.lfs"])
74 adddatafiles("sharedir", "share/pyx", ["contrib/pyx.def"])
76 # Note that on windows we can't install to absolute paths. Hence
77 # we put the global pyxrc into the share directory as well.
78 adddatafiles("pyxrcdir", os.name != "nt" and "/etc" or "share/pyx", ["pyxrc"])
80 ################################################################################
81 # extend install commands to overwrite siteconfig.py during build and install
85 class pyx_build_py(build_py):
87 def build_module(self, module, module_file, package):
88 if package == "pyx" and module == "siteconfig":
89 # generate path information as the original build_module does it
90 outfile = self.get_module_outfile(self.build_lib, [package], module)
91 outdir = os.path.dirname(outfile)
92 self.mkpath(outdir)
94 if log:
95 log.info("creating proper %s" % outfile)
97 # create the additional relative path parts to be inserted into the
98 # os.path.join methods in the original siteconfig.py
99 indir = os.path.dirname(module_file)
100 addjoinstring = ", ".join(["'..'" for d in outdir.split(os.path.sep)] +
101 ["'%s'" % d for d in indir.split(os.path.sep)])
103 # write a modifed version of siteconfig.py
104 fin = open(module_file, "r")
105 fout = open(outfile, "w")
106 for line in fin.readlines():
107 fout.write(line.replace("os.path.join(os.path.dirname(__file__), ",
108 "os.path.join(os.path.dirname(__file__), %s, " % addjoinstring))
109 fin.close()
110 fout.close()
111 else:
112 return build_py.build_module(self, module, module_file, package)
115 class pyx_install_data(install_data):
117 def run(self):
118 self.siteconfiglines = []
119 for dir, files in self.data_files:
120 # append siteconfiglines by "<siteconfigname> = <dir>"
122 # get the install directory
123 # (the following four lines are copied from within the install_data.run loop)
124 dir = convert_path(dir)
125 if not os.path.isabs(dir):
126 dir = os.path.join(self.install_dir, dir)
127 elif self.root:
128 dir = change_root(self.root, dir)
130 self.siteconfiglines.append("%s = '%s'\n" % (siteconfignames[files], dir))
132 install_data.run(self)
135 class pyx_install_lib(install_lib):
137 def run(self):
138 # siteconfig.py depends on install_data:
139 self.run_command('install_data')
140 install_lib.run(self)
142 def install(self):
143 # first we perform the tree_copy
144 result = install_lib.install(self)
146 # siteconfiglines have been created by install_data
147 siteconfiglines = self.distribution.command_obj["install_data"].siteconfiglines
149 # such that we can easily overwrite siteconfig.py
150 outfile = os.path.join(self.install_dir, "pyx", "siteconfig.py")
151 if log:
152 log.info("creating proper %s" % outfile)
153 f = open(outfile, "w")
154 f.writelines(siteconfiglines)
155 f.close()
157 return result
159 ################################################################################
160 # additional package metadata (only available in Python 2.3 and above)
163 if sys.version_info >= (2, 3):
164 addargs = { "classifiers":
165 [ "Development Status :: 3 - Alpha",
166 "Intended Audience :: Developers",
167 "Intended Audience :: End Users/Desktop",
168 "License :: OSI Approved :: GNU General Public License (GPL)",
169 "Operating System :: OS Independent",
170 "Programming Language :: Python",
171 "Topic :: Multimedia :: Graphics",
172 "Topic :: Scientific/Engineering :: Visualization",
173 "Topic :: Software Development :: Libraries :: Python Modules" ],
174 "download_url":
175 "http://sourceforge.net/project/showfiles.php?group_id=45430",
176 "platforms":
177 "OS independent",
179 else:
180 addargs = {}
182 # We're using the module docstring as the distutils descriptions. (seen in Zope3 setup.py)
183 doclines = __doc__.split("\n")
185 setup(name="PyX",
186 version=pyx.__version__,
187 author="Jörg Lehmann, André Wobst",
188 author_email="pyx-devel@lists.sourceforge.net",
189 url="http://pyx.sourceforge.net/",
190 description=doclines[0],
191 long_description="\n".join(doclines[2:]),
192 license="GPL",
193 packages=["pyx", "pyx/graph", "pyx/graph/axis", "pyx/font", "pyx/dvi", "pyx/pykpathsea"],
194 ext_modules=ext_modules,
195 data_files=data_files,
196 cmdclass = {"build_py": pyx_build_py,
197 "install_data": pyx_install_data,
198 "install_lib": pyx_install_lib},
199 **addargs)