##// END OF EJS Templates
setup: set env global earlier (3073)
Matt Mackall -
r15367:b357a972 stable
parent child Browse files
Show More
@@ -1,442 +1,442 b''
1 #
1 #
2 # This is the mercurial setup script.
2 # This is the mercurial setup script.
3 #
3 #
4 # 'python setup.py install', or
4 # 'python setup.py install', or
5 # 'python setup.py --help' for more options
5 # 'python setup.py --help' for more options
6
6
7 import sys, platform
7 import sys, platform
8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 4, 0, 'final'):
8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 4, 0, 'final'):
9 raise SystemExit("Mercurial requires Python 2.4 or later.")
9 raise SystemExit("Mercurial requires Python 2.4 or later.")
10
10
11 if sys.version_info[0] >= 3:
11 if sys.version_info[0] >= 3:
12 def b(s):
12 def b(s):
13 '''A helper function to emulate 2.6+ bytes literals using string
13 '''A helper function to emulate 2.6+ bytes literals using string
14 literals.'''
14 literals.'''
15 return s.encode('latin1')
15 return s.encode('latin1')
16 else:
16 else:
17 def b(s):
17 def b(s):
18 '''A helper function to emulate 2.6+ bytes literals using string
18 '''A helper function to emulate 2.6+ bytes literals using string
19 literals.'''
19 literals.'''
20 return s
20 return s
21
21
22 # Solaris Python packaging brain damage
22 # Solaris Python packaging brain damage
23 try:
23 try:
24 import hashlib
24 import hashlib
25 sha = hashlib.sha1()
25 sha = hashlib.sha1()
26 except:
26 except:
27 try:
27 try:
28 import sha
28 import sha
29 except:
29 except:
30 raise SystemExit(
30 raise SystemExit(
31 "Couldn't import standard hashlib (incomplete Python install).")
31 "Couldn't import standard hashlib (incomplete Python install).")
32
32
33 try:
33 try:
34 import zlib
34 import zlib
35 except:
35 except:
36 raise SystemExit(
36 raise SystemExit(
37 "Couldn't import standard zlib (incomplete Python install).")
37 "Couldn't import standard zlib (incomplete Python install).")
38
38
39 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
39 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
40 isironpython = False
40 isironpython = False
41 try:
41 try:
42 isironpython = platform.python_implementation().lower().find("ironpython") != -1
42 isironpython = platform.python_implementation().lower().find("ironpython") != -1
43 except:
43 except:
44 pass
44 pass
45
45
46 if isironpython:
46 if isironpython:
47 print "warning: IronPython detected (no bz2 support)"
47 print "warning: IronPython detected (no bz2 support)"
48 else:
48 else:
49 try:
49 try:
50 import bz2
50 import bz2
51 except:
51 except:
52 raise SystemExit(
52 raise SystemExit(
53 "Couldn't import standard bz2 (incomplete Python install).")
53 "Couldn't import standard bz2 (incomplete Python install).")
54
54
55 import os, subprocess, time
55 import os, subprocess, time
56 import shutil
56 import shutil
57 import tempfile
57 import tempfile
58 from distutils import log
58 from distutils import log
59 from distutils.core import setup, Command, Extension
59 from distutils.core import setup, Command, Extension
60 from distutils.dist import Distribution
60 from distutils.dist import Distribution
61 from distutils.command.build import build
61 from distutils.command.build import build
62 from distutils.command.build_ext import build_ext
62 from distutils.command.build_ext import build_ext
63 from distutils.command.build_py import build_py
63 from distutils.command.build_py import build_py
64 from distutils.command.install_scripts import install_scripts
64 from distutils.command.install_scripts import install_scripts
65 from distutils.spawn import spawn, find_executable
65 from distutils.spawn import spawn, find_executable
66 from distutils.ccompiler import new_compiler
66 from distutils.ccompiler import new_compiler
67 from distutils.errors import CCompilerError, DistutilsExecError
67 from distutils.errors import CCompilerError, DistutilsExecError
68 from distutils.sysconfig import get_python_inc
68 from distutils.sysconfig import get_python_inc
69 from distutils.version import StrictVersion
69 from distutils.version import StrictVersion
70
70
71 scripts = ['hg']
71 scripts = ['hg']
72 if os.name == 'nt':
72 if os.name == 'nt':
73 scripts.append('contrib/win32/hg.bat')
73 scripts.append('contrib/win32/hg.bat')
74
74
75 # simplified version of distutils.ccompiler.CCompiler.has_function
75 # simplified version of distutils.ccompiler.CCompiler.has_function
76 # that actually removes its temporary files.
76 # that actually removes its temporary files.
77 def hasfunction(cc, funcname):
77 def hasfunction(cc, funcname):
78 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
78 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
79 devnull = oldstderr = None
79 devnull = oldstderr = None
80 try:
80 try:
81 try:
81 try:
82 fname = os.path.join(tmpdir, 'funcname.c')
82 fname = os.path.join(tmpdir, 'funcname.c')
83 f = open(fname, 'w')
83 f = open(fname, 'w')
84 f.write('int main(void) {\n')
84 f.write('int main(void) {\n')
85 f.write(' %s();\n' % funcname)
85 f.write(' %s();\n' % funcname)
86 f.write('}\n')
86 f.write('}\n')
87 f.close()
87 f.close()
88 # Redirect stderr to /dev/null to hide any error messages
88 # Redirect stderr to /dev/null to hide any error messages
89 # from the compiler.
89 # from the compiler.
90 # This will have to be changed if we ever have to check
90 # This will have to be changed if we ever have to check
91 # for a function on Windows.
91 # for a function on Windows.
92 devnull = open('/dev/null', 'w')
92 devnull = open('/dev/null', 'w')
93 oldstderr = os.dup(sys.stderr.fileno())
93 oldstderr = os.dup(sys.stderr.fileno())
94 os.dup2(devnull.fileno(), sys.stderr.fileno())
94 os.dup2(devnull.fileno(), sys.stderr.fileno())
95 objects = cc.compile([fname], output_dir=tmpdir)
95 objects = cc.compile([fname], output_dir=tmpdir)
96 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
96 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
97 except:
97 except:
98 return False
98 return False
99 return True
99 return True
100 finally:
100 finally:
101 if oldstderr is not None:
101 if oldstderr is not None:
102 os.dup2(oldstderr, sys.stderr.fileno())
102 os.dup2(oldstderr, sys.stderr.fileno())
103 if devnull is not None:
103 if devnull is not None:
104 devnull.close()
104 devnull.close()
105 shutil.rmtree(tmpdir)
105 shutil.rmtree(tmpdir)
106
106
107 # py2exe needs to be installed to work
107 # py2exe needs to be installed to work
108 try:
108 try:
109 import py2exe
109 import py2exe
110 py2exeloaded = True
110 py2exeloaded = True
111 except ImportError:
111 except ImportError:
112 py2exeloaded = False
112 py2exeloaded = False
113
113
114 def runcmd(cmd, env):
114 def runcmd(cmd, env):
115 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
115 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
116 stderr=subprocess.PIPE, env=env)
116 stderr=subprocess.PIPE, env=env)
117 out, err = p.communicate()
117 out, err = p.communicate()
118 return out, err
118 return out, err
119
119
120 def runhg(cmd, env):
120 def runhg(cmd, env):
121 out, err = runcmd(cmd, env)
121 out, err = runcmd(cmd, env)
122 # If root is executing setup.py, but the repository is owned by
122 # If root is executing setup.py, but the repository is owned by
123 # another user (as in "sudo python setup.py install") we will get
123 # another user (as in "sudo python setup.py install") we will get
124 # trust warnings since the .hg/hgrc file is untrusted. That is
124 # trust warnings since the .hg/hgrc file is untrusted. That is
125 # fine, we don't want to load it anyway. Python may warn about
125 # fine, we don't want to load it anyway. Python may warn about
126 # a missing __init__.py in mercurial/locale, we also ignore that.
126 # a missing __init__.py in mercurial/locale, we also ignore that.
127 err = [e for e in err.splitlines()
127 err = [e for e in err.splitlines()
128 if not e.startswith(b('Not trusting file')) \
128 if not e.startswith(b('Not trusting file')) \
129 and not e.startswith(b('warning: Not importing'))]
129 and not e.startswith(b('warning: Not importing'))]
130 if err:
130 if err:
131 return ''
131 return ''
132 return out
132 return out
133
133
134 version = ''
134 version = ''
135
135
136 env = {'HGRCPATH': '', 'LANGUAGE': 'C'}
137
136 if os.path.isdir('.hg'):
138 if os.path.isdir('.hg'):
137 # Execute hg out of this directory with a custom environment which
139 # Execute hg out of this directory with a custom environment which
138 # includes the pure Python modules in mercurial/pure. We also take
140 # includes the pure Python modules in mercurial/pure. We also take
139 # care to not use any hgrc files and do no localization.
141 # care to not use any hgrc files and do no localization.
140 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
142 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
141 env = {'PYTHONPATH': os.pathsep.join(pypath),
143 env['PYTHONPATH'] = os.pathsep.join(pypath)
142 'HGRCPATH': '',
143 'LANGUAGE': 'C'}
144 if 'LD_LIBRARY_PATH' in os.environ:
144 if 'LD_LIBRARY_PATH' in os.environ:
145 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
145 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
146 if 'SystemRoot' in os.environ:
146 if 'SystemRoot' in os.environ:
147 # Copy SystemRoot into the custom environment for Python 2.6
147 # Copy SystemRoot into the custom environment for Python 2.6
148 # under Windows. Otherwise, the subprocess will fail with
148 # under Windows. Otherwise, the subprocess will fail with
149 # error 0xc0150004. See: http://bugs.python.org/issue3440
149 # error 0xc0150004. See: http://bugs.python.org/issue3440
150 env['SystemRoot'] = os.environ['SystemRoot']
150 env['SystemRoot'] = os.environ['SystemRoot']
151 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
151 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
152 l = runhg(cmd, env).split()
152 l = runhg(cmd, env).split()
153 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
153 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
154 l.pop()
154 l.pop()
155 if len(l) > 1: # tag found
155 if len(l) > 1: # tag found
156 version = l[-1]
156 version = l[-1]
157 if l[0].endswith('+'): # propagate the dirty status to the tag
157 if l[0].endswith('+'): # propagate the dirty status to the tag
158 version += '+'
158 version += '+'
159 elif len(l) == 1: # no tag found
159 elif len(l) == 1: # no tag found
160 cmd = [sys.executable, 'hg', 'parents', '--template',
160 cmd = [sys.executable, 'hg', 'parents', '--template',
161 '{latesttag}+{latesttagdistance}-']
161 '{latesttag}+{latesttagdistance}-']
162 version = runhg(cmd, env) + l[0]
162 version = runhg(cmd, env) + l[0]
163 if version.endswith('+'):
163 if version.endswith('+'):
164 version += time.strftime('%Y%m%d')
164 version += time.strftime('%Y%m%d')
165 elif os.path.exists('.hg_archival.txt'):
165 elif os.path.exists('.hg_archival.txt'):
166 kw = dict([[t.strip() for t in l.split(':', 1)]
166 kw = dict([[t.strip() for t in l.split(':', 1)]
167 for l in open('.hg_archival.txt')])
167 for l in open('.hg_archival.txt')])
168 if 'tag' in kw:
168 if 'tag' in kw:
169 version = kw['tag']
169 version = kw['tag']
170 elif 'latesttag' in kw:
170 elif 'latesttag' in kw:
171 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
171 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
172 else:
172 else:
173 version = kw.get('node', '')[:12]
173 version = kw.get('node', '')[:12]
174
174
175 if version:
175 if version:
176 f = open("mercurial/__version__.py", "w")
176 f = open("mercurial/__version__.py", "w")
177 f.write('# this file is autogenerated by setup.py\n')
177 f.write('# this file is autogenerated by setup.py\n')
178 f.write('version = "%s"\n' % version)
178 f.write('version = "%s"\n' % version)
179 f.close()
179 f.close()
180
180
181
181
182 try:
182 try:
183 from mercurial import __version__
183 from mercurial import __version__
184 version = __version__.version
184 version = __version__.version
185 except ImportError:
185 except ImportError:
186 version = 'unknown'
186 version = 'unknown'
187
187
188 class hgbuildmo(build):
188 class hgbuildmo(build):
189
189
190 description = "build translations (.mo files)"
190 description = "build translations (.mo files)"
191
191
192 def run(self):
192 def run(self):
193 if not find_executable('msgfmt'):
193 if not find_executable('msgfmt'):
194 self.warn("could not find msgfmt executable, no translations "
194 self.warn("could not find msgfmt executable, no translations "
195 "will be built")
195 "will be built")
196 return
196 return
197
197
198 podir = 'i18n'
198 podir = 'i18n'
199 if not os.path.isdir(podir):
199 if not os.path.isdir(podir):
200 self.warn("could not find %s/ directory" % podir)
200 self.warn("could not find %s/ directory" % podir)
201 return
201 return
202
202
203 join = os.path.join
203 join = os.path.join
204 for po in os.listdir(podir):
204 for po in os.listdir(podir):
205 if not po.endswith('.po'):
205 if not po.endswith('.po'):
206 continue
206 continue
207 pofile = join(podir, po)
207 pofile = join(podir, po)
208 modir = join('locale', po[:-3], 'LC_MESSAGES')
208 modir = join('locale', po[:-3], 'LC_MESSAGES')
209 mofile = join(modir, 'hg.mo')
209 mofile = join(modir, 'hg.mo')
210 mobuildfile = join('mercurial', mofile)
210 mobuildfile = join('mercurial', mofile)
211 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
211 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
212 if sys.platform != 'sunos5':
212 if sys.platform != 'sunos5':
213 # msgfmt on Solaris does not know about -c
213 # msgfmt on Solaris does not know about -c
214 cmd.append('-c')
214 cmd.append('-c')
215 self.mkpath(join('mercurial', modir))
215 self.mkpath(join('mercurial', modir))
216 self.make_file([pofile], mobuildfile, spawn, (cmd,))
216 self.make_file([pofile], mobuildfile, spawn, (cmd,))
217
217
218
218
219 # Insert hgbuildmo first so that files in mercurial/locale/ are found
219 # Insert hgbuildmo first so that files in mercurial/locale/ are found
220 # when build_py is run next.
220 # when build_py is run next.
221 build.sub_commands.insert(0, ('build_mo', None))
221 build.sub_commands.insert(0, ('build_mo', None))
222
222
223 Distribution.pure = 0
223 Distribution.pure = 0
224 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
224 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
225 "code instead of C extensions"))
225 "code instead of C extensions"))
226
226
227 class hgbuildext(build_ext):
227 class hgbuildext(build_ext):
228
228
229 def build_extension(self, ext):
229 def build_extension(self, ext):
230 try:
230 try:
231 build_ext.build_extension(self, ext)
231 build_ext.build_extension(self, ext)
232 except CCompilerError:
232 except CCompilerError:
233 if not getattr(ext, 'optional', False):
233 if not getattr(ext, 'optional', False):
234 raise
234 raise
235 log.warn("Failed to build optional extension '%s' (skipping)",
235 log.warn("Failed to build optional extension '%s' (skipping)",
236 ext.name)
236 ext.name)
237
237
238 class hgbuildpy(build_py):
238 class hgbuildpy(build_py):
239
239
240 def finalize_options(self):
240 def finalize_options(self):
241 build_py.finalize_options(self)
241 build_py.finalize_options(self)
242
242
243 if self.distribution.pure:
243 if self.distribution.pure:
244 if self.py_modules is None:
244 if self.py_modules is None:
245 self.py_modules = []
245 self.py_modules = []
246 for ext in self.distribution.ext_modules:
246 for ext in self.distribution.ext_modules:
247 if ext.name.startswith("mercurial."):
247 if ext.name.startswith("mercurial."):
248 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
248 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
249 self.distribution.ext_modules = []
249 self.distribution.ext_modules = []
250 else:
250 else:
251 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
251 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
252 raise SystemExit("Python headers are required to build Mercurial")
252 raise SystemExit("Python headers are required to build Mercurial")
253
253
254 def find_modules(self):
254 def find_modules(self):
255 modules = build_py.find_modules(self)
255 modules = build_py.find_modules(self)
256 for module in modules:
256 for module in modules:
257 if module[0] == "mercurial.pure":
257 if module[0] == "mercurial.pure":
258 if module[1] != "__init__":
258 if module[1] != "__init__":
259 yield ("mercurial", module[1], module[2])
259 yield ("mercurial", module[1], module[2])
260 else:
260 else:
261 yield module
261 yield module
262
262
263 class buildhgextindex(Command):
263 class buildhgextindex(Command):
264 description = 'generate prebuilt index of hgext (for frozen package)'
264 description = 'generate prebuilt index of hgext (for frozen package)'
265 user_options = []
265 user_options = []
266 _indexfilename = 'hgext/__index__.py'
266 _indexfilename = 'hgext/__index__.py'
267
267
268 def initialize_options(self):
268 def initialize_options(self):
269 pass
269 pass
270
270
271 def finalize_options(self):
271 def finalize_options(self):
272 pass
272 pass
273
273
274 def run(self):
274 def run(self):
275 if os.path.exists(self._indexfilename):
275 if os.path.exists(self._indexfilename):
276 os.unlink(self._indexfilename)
276 os.unlink(self._indexfilename)
277
277
278 # here no extension enabled, disabled() lists up everything
278 # here no extension enabled, disabled() lists up everything
279 code = ('import pprint; from mercurial import extensions; '
279 code = ('import pprint; from mercurial import extensions; '
280 'pprint.pprint(extensions.disabled())')
280 'pprint.pprint(extensions.disabled())')
281 out, err = runcmd([sys.executable, '-c', code], env)
281 out, err = runcmd([sys.executable, '-c', code], env)
282 if err:
282 if err:
283 raise DistutilsExecError(err)
283 raise DistutilsExecError(err)
284
284
285 f = open(self._indexfilename, 'w')
285 f = open(self._indexfilename, 'w')
286 f.write('# this file is autogenerated by setup.py\n')
286 f.write('# this file is autogenerated by setup.py\n')
287 f.write('docs = ')
287 f.write('docs = ')
288 f.write(out)
288 f.write(out)
289 f.close()
289 f.close()
290
290
291 class hginstallscripts(install_scripts):
291 class hginstallscripts(install_scripts):
292 '''
292 '''
293 This is a specialization of install_scripts that replaces the @LIBDIR@ with
293 This is a specialization of install_scripts that replaces the @LIBDIR@ with
294 the configured directory for modules. If possible, the path is made relative
294 the configured directory for modules. If possible, the path is made relative
295 to the directory for scripts.
295 to the directory for scripts.
296 '''
296 '''
297
297
298 def initialize_options(self):
298 def initialize_options(self):
299 install_scripts.initialize_options(self)
299 install_scripts.initialize_options(self)
300
300
301 self.install_lib = None
301 self.install_lib = None
302
302
303 def finalize_options(self):
303 def finalize_options(self):
304 install_scripts.finalize_options(self)
304 install_scripts.finalize_options(self)
305 self.set_undefined_options('install',
305 self.set_undefined_options('install',
306 ('install_lib', 'install_lib'))
306 ('install_lib', 'install_lib'))
307
307
308 def run(self):
308 def run(self):
309 install_scripts.run(self)
309 install_scripts.run(self)
310
310
311 if (os.path.splitdrive(self.install_dir)[0] !=
311 if (os.path.splitdrive(self.install_dir)[0] !=
312 os.path.splitdrive(self.install_lib)[0]):
312 os.path.splitdrive(self.install_lib)[0]):
313 # can't make relative paths from one drive to another, so use an
313 # can't make relative paths from one drive to another, so use an
314 # absolute path instead
314 # absolute path instead
315 libdir = self.install_lib
315 libdir = self.install_lib
316 else:
316 else:
317 common = os.path.commonprefix((self.install_dir, self.install_lib))
317 common = os.path.commonprefix((self.install_dir, self.install_lib))
318 rest = self.install_dir[len(common):]
318 rest = self.install_dir[len(common):]
319 uplevel = len([n for n in os.path.split(rest) if n])
319 uplevel = len([n for n in os.path.split(rest) if n])
320
320
321 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
321 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
322
322
323 for outfile in self.outfiles:
323 for outfile in self.outfiles:
324 fp = open(outfile, 'rb')
324 fp = open(outfile, 'rb')
325 data = fp.read()
325 data = fp.read()
326 fp.close()
326 fp.close()
327
327
328 # skip binary files
328 # skip binary files
329 if '\0' in data:
329 if '\0' in data:
330 continue
330 continue
331
331
332 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
332 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
333 fp = open(outfile, 'wb')
333 fp = open(outfile, 'wb')
334 fp.write(data)
334 fp.write(data)
335 fp.close()
335 fp.close()
336
336
337 cmdclass = {'build_mo': hgbuildmo,
337 cmdclass = {'build_mo': hgbuildmo,
338 'build_ext': hgbuildext,
338 'build_ext': hgbuildext,
339 'build_py': hgbuildpy,
339 'build_py': hgbuildpy,
340 'build_hgextindex': buildhgextindex,
340 'build_hgextindex': buildhgextindex,
341 'install_scripts': hginstallscripts}
341 'install_scripts': hginstallscripts}
342
342
343 packages = ['mercurial', 'mercurial.hgweb',
343 packages = ['mercurial', 'mercurial.hgweb',
344 'mercurial.httpclient', 'mercurial.httpclient.tests',
344 'mercurial.httpclient', 'mercurial.httpclient.tests',
345 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
345 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
346 'hgext.largefiles']
346 'hgext.largefiles']
347
347
348 pymodules = []
348 pymodules = []
349
349
350 extmodules = [
350 extmodules = [
351 Extension('mercurial.base85', ['mercurial/base85.c']),
351 Extension('mercurial.base85', ['mercurial/base85.c']),
352 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
352 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
353 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
353 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
354 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
354 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
355 Extension('mercurial.parsers', ['mercurial/parsers.c']),
355 Extension('mercurial.parsers', ['mercurial/parsers.c']),
356 ]
356 ]
357
357
358 osutil_ldflags = []
358 osutil_ldflags = []
359
359
360 if sys.platform == 'darwin':
360 if sys.platform == 'darwin':
361 osutil_ldflags += ['-framework', 'ApplicationServices']
361 osutil_ldflags += ['-framework', 'ApplicationServices']
362
362
363 # disable osutil.c under windows + python 2.4 (issue1364)
363 # disable osutil.c under windows + python 2.4 (issue1364)
364 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
364 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
365 pymodules.append('mercurial.pure.osutil')
365 pymodules.append('mercurial.pure.osutil')
366 else:
366 else:
367 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
367 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
368 extra_link_args=osutil_ldflags))
368 extra_link_args=osutil_ldflags))
369
369
370 if sys.platform.startswith('linux') and os.uname()[2] > '2.6':
370 if sys.platform.startswith('linux') and os.uname()[2] > '2.6':
371 # The inotify extension is only usable with Linux 2.6 kernels.
371 # The inotify extension is only usable with Linux 2.6 kernels.
372 # You also need a reasonably recent C library.
372 # You also need a reasonably recent C library.
373 # In any case, if it fails to build the error will be skipped ('optional').
373 # In any case, if it fails to build the error will be skipped ('optional').
374 cc = new_compiler()
374 cc = new_compiler()
375 if hasfunction(cc, 'inotify_add_watch'):
375 if hasfunction(cc, 'inotify_add_watch'):
376 inotify = Extension('hgext.inotify.linux._inotify',
376 inotify = Extension('hgext.inotify.linux._inotify',
377 ['hgext/inotify/linux/_inotify.c'],
377 ['hgext/inotify/linux/_inotify.c'],
378 ['mercurial'])
378 ['mercurial'])
379 inotify.optional = True
379 inotify.optional = True
380 extmodules.append(inotify)
380 extmodules.append(inotify)
381 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
381 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
382
382
383 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
383 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
384 'help/*.txt']}
384 'help/*.txt']}
385
385
386 def ordinarypath(p):
386 def ordinarypath(p):
387 return p and p[0] != '.' and p[-1] != '~'
387 return p and p[0] != '.' and p[-1] != '~'
388
388
389 for root in ('templates',):
389 for root in ('templates',):
390 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
390 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
391 curdir = curdir.split(os.sep, 1)[1]
391 curdir = curdir.split(os.sep, 1)[1]
392 dirs[:] = filter(ordinarypath, dirs)
392 dirs[:] = filter(ordinarypath, dirs)
393 for f in filter(ordinarypath, files):
393 for f in filter(ordinarypath, files):
394 f = os.path.join(curdir, f)
394 f = os.path.join(curdir, f)
395 packagedata['mercurial'].append(f)
395 packagedata['mercurial'].append(f)
396
396
397 datafiles = []
397 datafiles = []
398 setupversion = version
398 setupversion = version
399 extra = {}
399 extra = {}
400
400
401 if py2exeloaded:
401 if py2exeloaded:
402 extra['console'] = [
402 extra['console'] = [
403 {'script':'hg',
403 {'script':'hg',
404 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
404 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
405 'product_version':version}]
405 'product_version':version}]
406 # sub command of 'build' because 'py2exe' does not handle sub_commands
406 # sub command of 'build' because 'py2exe' does not handle sub_commands
407 build.sub_commands.insert(0, ('build_hgextindex', None))
407 build.sub_commands.insert(0, ('build_hgextindex', None))
408
408
409 if os.name == 'nt':
409 if os.name == 'nt':
410 # Windows binary file versions for exe/dll files must have the
410 # Windows binary file versions for exe/dll files must have the
411 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
411 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
412 setupversion = version.split('+', 1)[0]
412 setupversion = version.split('+', 1)[0]
413
413
414 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
414 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
415 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
415 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
416 # distutils.sysconfig
416 # distutils.sysconfig
417 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()[0]
417 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()[0]
418 # Also parse only first digit, because 3.2.1 can't be parsed nicely
418 # Also parse only first digit, because 3.2.1 can't be parsed nicely
419 if (version.startswith('Xcode') and
419 if (version.startswith('Xcode') and
420 StrictVersion(version.split()[1]) >= StrictVersion('4.0')):
420 StrictVersion(version.split()[1]) >= StrictVersion('4.0')):
421 os.environ['ARCHFLAGS'] = ''
421 os.environ['ARCHFLAGS'] = ''
422
422
423 setup(name='mercurial',
423 setup(name='mercurial',
424 version=setupversion,
424 version=setupversion,
425 author='Matt Mackall',
425 author='Matt Mackall',
426 author_email='mpm@selenic.com',
426 author_email='mpm@selenic.com',
427 url='http://mercurial.selenic.com/',
427 url='http://mercurial.selenic.com/',
428 description='Scalable distributed SCM',
428 description='Scalable distributed SCM',
429 license='GNU GPLv2+',
429 license='GNU GPLv2+',
430 scripts=scripts,
430 scripts=scripts,
431 packages=packages,
431 packages=packages,
432 py_modules=pymodules,
432 py_modules=pymodules,
433 ext_modules=extmodules,
433 ext_modules=extmodules,
434 data_files=datafiles,
434 data_files=datafiles,
435 package_data=packagedata,
435 package_data=packagedata,
436 cmdclass=cmdclass,
436 cmdclass=cmdclass,
437 options=dict(py2exe=dict(packages=['hgext', 'email']),
437 options=dict(py2exe=dict(packages=['hgext', 'email']),
438 bdist_mpkg=dict(zipdist=True,
438 bdist_mpkg=dict(zipdist=True,
439 license='COPYING',
439 license='COPYING',
440 readme='contrib/macosx/Readme.html',
440 readme='contrib/macosx/Readme.html',
441 welcome='contrib/macosx/Welcome.html')),
441 welcome='contrib/macosx/Welcome.html')),
442 **extra)
442 **extra)
General Comments 0
You need to be logged in to leave comments. Login now