##// END OF EJS Templates
setup: pass LD_LIBRARY_PATH to subprocess when determining version.
Christian Boos -
r9856:ed362d41 default
parent child Browse files
Show More
@@ -1,281 +1,283
1 1 #!/usr/bin/env python
2 2 #
3 3 # This is the mercurial setup script.
4 4 #
5 5 # 'python setup.py install', or
6 6 # 'python setup.py --help' for more options
7 7
8 8 import sys
9 9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
10 10 raise SystemExit("Mercurial requires Python 2.4 or later.")
11 11
12 12 # Solaris Python packaging brain damage
13 13 try:
14 14 import hashlib
15 15 sha = hashlib.sha1()
16 16 except:
17 17 try:
18 18 import sha
19 19 except:
20 20 raise SystemExit(
21 21 "Couldn't import standard hashlib (incomplete Python install).")
22 22
23 23 try:
24 24 import zlib
25 25 except:
26 26 raise SystemExit(
27 27 "Couldn't import standard zlib (incomplete Python install).")
28 28
29 29 import os, subprocess, time
30 30 import shutil
31 31 import tempfile
32 32 from distutils.core import setup, Extension
33 33 from distutils.dist import Distribution
34 34 from distutils.command.install_data import install_data
35 35 from distutils.command.build import build
36 36 from distutils.command.build_py import build_py
37 37 from distutils.spawn import spawn, find_executable
38 38 from distutils.ccompiler import new_compiler
39 39
40 40 extra = {}
41 41 scripts = ['hg']
42 42 if os.name == 'nt':
43 43 scripts.append('contrib/win32/hg.bat')
44 44
45 45 # simplified version of distutils.ccompiler.CCompiler.has_function
46 46 # that actually removes its temporary files.
47 47 def has_function(cc, funcname):
48 48 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
49 49 devnull = oldstderr = None
50 50 try:
51 51 try:
52 52 fname = os.path.join(tmpdir, 'funcname.c')
53 53 f = open(fname, 'w')
54 54 f.write('int main(void) {\n')
55 55 f.write(' %s();\n' % funcname)
56 56 f.write('}\n')
57 57 f.close()
58 58 # Redirect stderr to /dev/null to hide any error messages
59 59 # from the compiler.
60 60 # This will have to be changed if we ever have to check
61 61 # for a function on Windows.
62 62 devnull = open('/dev/null', 'w')
63 63 oldstderr = os.dup(sys.stderr.fileno())
64 64 os.dup2(devnull.fileno(), sys.stderr.fileno())
65 65 objects = cc.compile([fname], output_dir=tmpdir)
66 66 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
67 67 except:
68 68 return False
69 69 return True
70 70 finally:
71 71 if oldstderr is not None:
72 72 os.dup2(oldstderr, sys.stderr.fileno())
73 73 if devnull is not None:
74 74 devnull.close()
75 75 shutil.rmtree(tmpdir)
76 76
77 77 # py2exe needs to be installed to work
78 78 try:
79 79 import py2exe
80 80
81 81 # Help py2exe to find win32com.shell
82 82 try:
83 83 import modulefinder
84 84 import win32com
85 85 for p in win32com.__path__[1:]: # Take the path to win32comext
86 86 modulefinder.AddPackagePath("win32com", p)
87 87 pn = "win32com.shell"
88 88 __import__(pn)
89 89 m = sys.modules[pn]
90 90 for p in m.__path__[1:]:
91 91 modulefinder.AddPackagePath(pn, p)
92 92 except ImportError:
93 93 pass
94 94
95 95 extra['console'] = ['hg']
96 96
97 97 except ImportError:
98 98 pass
99 99
100 100 def runcmd(cmd, env):
101 101 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
102 102 stderr=subprocess.PIPE, env=env)
103 103 out, err = p.communicate()
104 104 # If root is executing setup.py, but the repository is owned by
105 105 # another user (as in "sudo python setup.py install") we will get
106 106 # trust warnings since the .hg/hgrc file is untrusted. That is
107 107 # fine, we don't want to load it anyway.
108 108 err = [e for e in err.splitlines()
109 109 if not e.startswith('Not trusting file')]
110 110 if err:
111 111 return ''
112 112 return out
113 113
114 114 version = ''
115 115
116 116 if os.path.isdir('.hg'):
117 117 # Execute hg out of this directory with a custom environment which
118 118 # includes the pure Python modules in mercurial/pure. We also take
119 119 # care to not use any hgrc files and do no localization.
120 120 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
121 121 env = {'PYTHONPATH': os.pathsep.join(pypath),
122 122 'HGRCPATH': '',
123 123 'LANGUAGE': 'C'}
124 if 'LD_LIBRARY_PATH' in os.environ:
125 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
124 126 if 'SystemRoot' in os.environ:
125 127 # Copy SystemRoot into the custom environment for Python 2.6
126 128 # under Windows. Otherwise, the subprocess will fail with
127 129 # error 0xc0150004. See: http://bugs.python.org/issue3440
128 130 env['SystemRoot'] = os.environ['SystemRoot']
129 131 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
130 132 l = runcmd(cmd, env).split()
131 133 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
132 134 l.pop()
133 135 if len(l) > 1: # tag found
134 136 version = l[-1]
135 137 if l[0].endswith('+'): # propagate the dirty status to the tag
136 138 version += '+'
137 139 elif len(l) == 1: # no tag found
138 140 cmd = [sys.executable, 'hg', 'parents', '--template',
139 141 '{latesttag}+{latesttagdistance}-']
140 142 version = runcmd(cmd, env) + l[0]
141 143 if version.endswith('+'):
142 144 version += time.strftime('%Y%m%d')
143 145 elif os.path.exists('.hg_archival.txt'):
144 146 kw = dict([t.strip() for t in l.split(':', 1)]
145 147 for l in open('.hg_archival.txt'))
146 148 if 'tag' in kw:
147 149 version = kw['tag']
148 150 elif 'latesttag' in kw:
149 151 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
150 152 else:
151 153 version = kw.get('node', '')[:12]
152 154
153 155 if version:
154 156 f = open("mercurial/__version__.py", "w")
155 157 f.write('# this file is autogenerated by setup.py\n')
156 158 f.write('version = "%s"\n' % version)
157 159 f.close()
158 160
159 161
160 162 try:
161 163 from mercurial import __version__
162 164 version = __version__.version
163 165 except ImportError:
164 166 version = 'unknown'
165 167
166 168 class install_package_data(install_data):
167 169 def finalize_options(self):
168 170 self.set_undefined_options('install',
169 171 ('install_lib', 'install_dir'))
170 172 install_data.finalize_options(self)
171 173
172 174 class build_mo(build):
173 175
174 176 description = "build translations (.mo files)"
175 177
176 178 def run(self):
177 179 if not find_executable('msgfmt'):
178 180 self.warn("could not find msgfmt executable, no translations "
179 181 "will be built")
180 182 return
181 183
182 184 podir = 'i18n'
183 185 if not os.path.isdir(podir):
184 186 self.warn("could not find %s/ directory" % podir)
185 187 return
186 188
187 189 join = os.path.join
188 190 for po in os.listdir(podir):
189 191 if not po.endswith('.po'):
190 192 continue
191 193 pofile = join(podir, po)
192 194 modir = join('locale', po[:-3], 'LC_MESSAGES')
193 195 mofile = join(modir, 'hg.mo')
194 196 cmd = ['msgfmt', '-v', '-o', mofile, pofile]
195 197 if sys.platform != 'sunos5':
196 198 # msgfmt on Solaris does not know about -c
197 199 cmd.append('-c')
198 200 self.mkpath(modir)
199 201 self.make_file([pofile], mofile, spawn, (cmd,))
200 202 self.distribution.data_files.append((join('mercurial', modir),
201 203 [mofile]))
202 204
203 205 build.sub_commands.append(('build_mo', None))
204 206
205 207 Distribution.pure = 0
206 208 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
207 209 "code instead of C extensions"))
208 210
209 211 class hg_build_py(build_py):
210 212
211 213 def finalize_options(self):
212 214 build_py.finalize_options(self)
213 215
214 216 if self.distribution.pure:
215 217 if self.py_modules is None:
216 218 self.py_modules = []
217 219 for ext in self.distribution.ext_modules:
218 220 if ext.name.startswith("mercurial."):
219 221 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
220 222 self.distribution.ext_modules = []
221 223
222 224 def find_modules(self):
223 225 modules = build_py.find_modules(self)
224 226 for module in modules:
225 227 if module[0] == "mercurial.pure":
226 228 if module[1] != "__init__":
227 229 yield ("mercurial", module[1], module[2])
228 230 else:
229 231 yield module
230 232
231 233 cmdclass = {'install_data': install_package_data,
232 234 'build_mo': build_mo,
233 235 'build_py': hg_build_py}
234 236
235 237 ext_modules=[
236 238 Extension('mercurial.base85', ['mercurial/base85.c']),
237 239 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
238 240 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
239 241 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
240 242 Extension('mercurial.parsers', ['mercurial/parsers.c']),
241 243 Extension('mercurial.osutil', ['mercurial/osutil.c']),
242 244 ]
243 245
244 246 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
245 247 'hgext.highlight', 'hgext.zeroconf', ]
246 248
247 249 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
248 250 # The inotify extension is only usable with Linux 2.6 kernels.
249 251 # You also need a reasonably recent C library.
250 252 cc = new_compiler()
251 253 if has_function(cc, 'inotify_add_watch'):
252 254 ext_modules.append(Extension('hgext.inotify.linux._inotify',
253 255 ['hgext/inotify/linux/_inotify.c']))
254 256 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
255 257
256 258 datafiles = []
257 259 for root in ('templates', 'i18n', 'help'):
258 260 for dir, dirs, files in os.walk(root):
259 261 dirs[:] = [x for x in dirs if not x.startswith('.')]
260 262 files = [x for x in files if not x.startswith('.')]
261 263 datafiles.append((os.path.join('mercurial', dir),
262 264 [os.path.join(dir, file_) for file_ in files]))
263 265
264 266 setup(name='mercurial',
265 267 version=version,
266 268 author='Matt Mackall',
267 269 author_email='mpm@selenic.com',
268 270 url='http://mercurial.selenic.com/',
269 271 description='Scalable distributed SCM',
270 272 license='GNU GPL',
271 273 scripts=scripts,
272 274 packages=packages,
273 275 ext_modules=ext_modules,
274 276 data_files=datafiles,
275 277 cmdclass=cmdclass,
276 278 options=dict(py2exe=dict(packages=['hgext', 'email']),
277 279 bdist_mpkg=dict(zipdist=True,
278 280 license='COPYING',
279 281 readme='contrib/macosx/Readme.html',
280 282 welcome='contrib/macosx/Welcome.html')),
281 283 **extra)
General Comments 0
You need to be logged in to leave comments. Login now