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