##// END OF EJS Templates
osx: create dmg with installer instead of zip...
Mads Kiilerich -
r22358:198e2da3 default
parent child Browse files
Show More
@@ -1,168 +1,169 b''
1 1 # If you want to change PREFIX, do not just edit it below. The changed
2 2 # value wont get passed on to recursive make calls. You should instead
3 3 # override the variable on the command like:
4 4 #
5 5 # % make PREFIX=/opt/ install
6 6
7 7 PREFIX=/usr/local
8 8 export PREFIX
9 9 PYTHON=python
10 10 PURE=
11 11 PYFILES:=$(shell find mercurial hgext doc -name '*.py')
12 12 DOCFILES=mercurial/help/*.txt
13 13 export LANGUAGE=C
14 14 export LC_ALL=C
15 15
16 16 # Set this to e.g. "mingw32" to use a non-default compiler.
17 17 COMPILER=
18 18
19 19 help:
20 20 @echo 'Commonly used make targets:'
21 21 @echo ' all - build program and documentation'
22 22 @echo ' install - install program and man pages to $$PREFIX ($(PREFIX))'
23 23 @echo ' install-home - install with setup.py install --home=$$HOME ($(HOME))'
24 24 @echo ' local - build for inplace usage'
25 25 @echo ' tests - run all tests in the automatic test suite'
26 26 @echo ' test-foo - run only specified tests (e.g. test-merge1.t)'
27 27 @echo ' dist - run all tests and create a source tarball in dist/'
28 28 @echo ' clean - remove files created by other targets'
29 29 @echo ' (except installed files or dist source tarball)'
30 30 @echo ' update-pot - update i18n/hg.pot'
31 31 @echo
32 32 @echo 'Example for a system-wide installation under /usr/local:'
33 33 @echo ' make all && su -c "make install" && hg version'
34 34 @echo
35 35 @echo 'Example for a local installation (usable in this directory):'
36 36 @echo ' make local && ./hg version'
37 37
38 38 all: build doc
39 39
40 40 local:
41 41 $(PYTHON) setup.py $(PURE) \
42 42 build_py -c -d . \
43 43 build_ext $(COMPILER:%=-c %) -i \
44 44 build_hgexe $(COMPILER:%=-c %) -i \
45 45 build_mo
46 46 env HGRCPATH= $(PYTHON) hg version
47 47
48 48 build:
49 49 $(PYTHON) setup.py $(PURE) build $(COMPILER:%=-c %)
50 50
51 51 doc:
52 52 $(MAKE) -C doc
53 53
54 54 clean:
55 55 -$(PYTHON) setup.py clean --all # ignore errors from this command
56 56 find contrib doc hgext i18n mercurial tests \
57 57 \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';'
58 58 rm -f $(addprefix mercurial/,$(notdir $(wildcard mercurial/pure/[a-z]*.py)))
59 59 rm -f MANIFEST MANIFEST.in mercurial/__version__.py hgext/__index__.py tests/*.err
60 60 rm -rf build mercurial/locale
61 61 $(MAKE) -C doc clean
62 62
63 63 install: install-bin install-doc
64 64
65 65 install-bin: build
66 66 $(PYTHON) setup.py $(PURE) install --root="$(DESTDIR)/" --prefix="$(PREFIX)" --force
67 67
68 68 install-doc: doc
69 69 cd doc && $(MAKE) $(MFLAGS) install
70 70
71 71 install-home: install-home-bin install-home-doc
72 72
73 73 install-home-bin: build
74 74 $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --prefix="" --force
75 75
76 76 install-home-doc: doc
77 77 cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install
78 78
79 79 MANIFEST-doc:
80 80 $(MAKE) -C doc MANIFEST
81 81
82 82 MANIFEST.in: MANIFEST-doc
83 83 hg manifest | sed -e 's/^/include /' > MANIFEST.in
84 84 echo include mercurial/__version__.py >> MANIFEST.in
85 85 sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in
86 86
87 87 dist: tests dist-notests
88 88
89 89 dist-notests: doc MANIFEST.in
90 90 TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist
91 91
92 92 check: tests
93 93
94 94 tests:
95 95 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS)
96 96
97 97 test-%:
98 98 cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@
99 99
100 100 check-code:
101 101 hg manifest | xargs python contrib/check-code.py
102 102
103 103 update-pot: i18n/hg.pot
104 104
105 105 i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n/posplit i18n/hggettext
106 106 $(PYTHON) i18n/hggettext mercurial/commands.py \
107 107 hgext/*.py hgext/*/__init__.py \
108 108 mercurial/fileset.py mercurial/revset.py \
109 109 mercurial/templatefilters.py mercurial/templatekw.py \
110 110 mercurial/filemerge.py \
111 111 $(DOCFILES) > i18n/hg.pot.tmp
112 112 # All strings marked for translation in Mercurial contain
113 113 # ASCII characters only. But some files contain string
114 114 # literals like this '\037\213'. xgettext thinks it has to
115 115 # parse them even though they are not marked for translation.
116 116 # Extracting with an explicit encoding of ISO-8859-1 will make
117 117 # xgettext "parse" and ignore them.
118 118 echo $(PYFILES) | xargs \
119 119 xgettext --package-name "Mercurial" \
120 120 --msgid-bugs-address "<mercurial-devel@selenic.com>" \
121 121 --copyright-holder "Matt Mackall <mpm@selenic.com> and others" \
122 122 --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \
123 123 -d hg -p i18n -o hg.pot.tmp
124 124 $(PYTHON) i18n/posplit i18n/hg.pot.tmp
125 125 # The target file is not created before the last step. So it never is in
126 126 # an intermediate state.
127 127 mv -f i18n/hg.pot.tmp i18n/hg.pot
128 128
129 129 %.po: i18n/hg.pot
130 130 # work on a temporary copy for never having a half completed target
131 131 cp $@ $@.tmp
132 132 msgmerge --no-location --update $@.tmp $^
133 133 mv -f $@.tmp $@
134 134
135 135 # Packaging targets
136 136
137 137 osx:
138 138 @which bdist_mpkg >/dev/null || \
139 139 (echo "Missing bdist_mpkg (easy_install bdist_mpkg)"; false)
140 rm -rf dist/mercurial-*.mpkg
140 141 bdist_mpkg setup.py
141 142 mkdir -p packages/osx
143 N=`cd dist && echo mercurial-*.mpkg | sed 's,\.mpkg$$,,'` && hdiutil create -srcfolder dist/$$N.mpkg/ -scrub -volname "$$N" -ov packages/osx/$$N.dmg
142 144 rm -rf dist/mercurial-*.mpkg
143 mv dist/mercurial*macosx*.zip packages/osx
144 145
145 146 fedora:
146 147 mkdir -p packages/fedora
147 148 contrib/buildrpm
148 149 cp rpmbuild/RPMS/*/* packages/fedora
149 150 cp rpmbuild/SRPMS/* packages/fedora
150 151 rm -rf rpmbuild
151 152
152 153 docker-fedora:
153 154 mkdir -p packages/fedora
154 155 contrib/dockerrpm fedora
155 156
156 157 centos6:
157 158 mkdir -p packages/centos6
158 159 contrib/buildrpm
159 160 cp rpmbuild/RPMS/*/* packages/centos6
160 161 cp rpmbuild/SRPMS/* packages/centos6
161 162
162 163 docker-centos6:
163 164 mkdir -p packages/centos6
164 165 contrib/dockerrpm centos6
165 166
166 167 .PHONY: help all local build doc clean install install-bin install-doc \
167 168 install-home install-home-bin install-home-doc dist dist-notests tests \
168 169 update-pot fedora docker-fedora
@@ -1,592 +1,592 b''
1 1 #
2 2 # This is the mercurial setup script.
3 3 #
4 4 # 'python setup.py install', or
5 5 # 'python setup.py --help' for more options
6 6
7 7 import sys, platform
8 8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 4, 0, 'final'):
9 9 raise SystemExit("Mercurial requires Python 2.4 or later.")
10 10
11 11 if sys.version_info[0] >= 3:
12 12 def b(s):
13 13 '''A helper function to emulate 2.6+ bytes literals using string
14 14 literals.'''
15 15 return s.encode('latin1')
16 16 printf = eval('print')
17 17 libdir_escape = 'unicode_escape'
18 18 else:
19 19 libdir_escape = 'string_escape'
20 20 def b(s):
21 21 '''A helper function to emulate 2.6+ bytes literals using string
22 22 literals.'''
23 23 return s
24 24 def printf(*args, **kwargs):
25 25 f = kwargs.get('file', sys.stdout)
26 26 end = kwargs.get('end', '\n')
27 27 f.write(b(' ').join(args) + end)
28 28
29 29 # Solaris Python packaging brain damage
30 30 try:
31 31 import hashlib
32 32 sha = hashlib.sha1()
33 33 except ImportError:
34 34 try:
35 35 import sha
36 36 sha.sha # silence unused import warning
37 37 except ImportError:
38 38 raise SystemExit(
39 39 "Couldn't import standard hashlib (incomplete Python install).")
40 40
41 41 try:
42 42 import zlib
43 43 zlib.compressobj # silence unused import warning
44 44 except ImportError:
45 45 raise SystemExit(
46 46 "Couldn't import standard zlib (incomplete Python install).")
47 47
48 48 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
49 49 isironpython = False
50 50 try:
51 51 isironpython = (platform.python_implementation()
52 52 .lower().find("ironpython") != -1)
53 53 except AttributeError:
54 54 pass
55 55
56 56 if isironpython:
57 57 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
58 58 else:
59 59 try:
60 60 import bz2
61 61 bz2.BZ2Compressor # silence unused import warning
62 62 except ImportError:
63 63 raise SystemExit(
64 64 "Couldn't import standard bz2 (incomplete Python install).")
65 65
66 66 import os, subprocess, time
67 67 import re
68 68 import shutil
69 69 import tempfile
70 70 from distutils import log
71 71 from distutils.core import setup, Command, Extension
72 72 from distutils.dist import Distribution
73 73 from distutils.command.build import build
74 74 from distutils.command.build_ext import build_ext
75 75 from distutils.command.build_py import build_py
76 76 from distutils.command.install_scripts import install_scripts
77 77 from distutils.spawn import spawn, find_executable
78 78 from distutils import cygwinccompiler
79 79 from distutils.errors import CCompilerError, DistutilsExecError
80 80 from distutils.sysconfig import get_python_inc, get_config_var
81 81 from distutils.version import StrictVersion
82 82
83 83 convert2to3 = '--c2to3' in sys.argv
84 84 if convert2to3:
85 85 try:
86 86 from distutils.command.build_py import build_py_2to3 as build_py
87 87 from lib2to3.refactor import get_fixers_from_package as getfixers
88 88 except ImportError:
89 89 if sys.version_info[0] < 3:
90 90 raise SystemExit("--c2to3 is only compatible with python3.")
91 91 raise
92 92 sys.path.append('contrib')
93 93 elif sys.version_info[0] >= 3:
94 94 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
95 95
96 96 scripts = ['hg']
97 97 if os.name == 'nt':
98 98 scripts.append('contrib/win32/hg.bat')
99 99
100 100 # simplified version of distutils.ccompiler.CCompiler.has_function
101 101 # that actually removes its temporary files.
102 102 def hasfunction(cc, funcname):
103 103 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
104 104 devnull = oldstderr = None
105 105 try:
106 106 try:
107 107 fname = os.path.join(tmpdir, 'funcname.c')
108 108 f = open(fname, 'w')
109 109 f.write('int main(void) {\n')
110 110 f.write(' %s();\n' % funcname)
111 111 f.write('}\n')
112 112 f.close()
113 113 # Redirect stderr to /dev/null to hide any error messages
114 114 # from the compiler.
115 115 # This will have to be changed if we ever have to check
116 116 # for a function on Windows.
117 117 devnull = open('/dev/null', 'w')
118 118 oldstderr = os.dup(sys.stderr.fileno())
119 119 os.dup2(devnull.fileno(), sys.stderr.fileno())
120 120 objects = cc.compile([fname], output_dir=tmpdir)
121 121 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
122 122 except Exception:
123 123 return False
124 124 return True
125 125 finally:
126 126 if oldstderr is not None:
127 127 os.dup2(oldstderr, sys.stderr.fileno())
128 128 if devnull is not None:
129 129 devnull.close()
130 130 shutil.rmtree(tmpdir)
131 131
132 132 # py2exe needs to be installed to work
133 133 try:
134 134 import py2exe
135 135 py2exe.Distribution # silence unused import warning
136 136 py2exeloaded = True
137 137 # import py2exe's patched Distribution class
138 138 from distutils.core import Distribution
139 139 except ImportError:
140 140 py2exeloaded = False
141 141
142 142 def runcmd(cmd, env):
143 143 if sys.platform == 'plan9':
144 144 # subprocess kludge to work around issues in half-baked Python
145 145 # ports, notably bichued/python:
146 146 _, out, err = os.popen3(cmd)
147 147 return str(out), str(err)
148 148 else:
149 149 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
150 150 stderr=subprocess.PIPE, env=env)
151 151 out, err = p.communicate()
152 152 return out, err
153 153
154 154 def runhg(cmd, env):
155 155 out, err = runcmd(cmd, env)
156 156 # If root is executing setup.py, but the repository is owned by
157 157 # another user (as in "sudo python setup.py install") we will get
158 158 # trust warnings since the .hg/hgrc file is untrusted. That is
159 159 # fine, we don't want to load it anyway. Python may warn about
160 160 # a missing __init__.py in mercurial/locale, we also ignore that.
161 161 err = [e for e in err.splitlines()
162 162 if not e.startswith(b('not trusting file')) \
163 163 and not e.startswith(b('warning: Not importing')) \
164 164 and not e.startswith(b('obsolete feature not enabled'))]
165 165 if err:
166 166 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
167 167 printf(b('\n').join([b(' ') + e for e in err]), file=sys.stderr)
168 168 return ''
169 169 return out
170 170
171 171 version = ''
172 172
173 173 # Execute hg out of this directory with a custom environment which
174 174 # includes the pure Python modules in mercurial/pure. We also take
175 175 # care to not use any hgrc files and do no localization.
176 176 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
177 177 env = {'PYTHONPATH': os.pathsep.join(pypath),
178 178 'HGRCPATH': '',
179 179 'LANGUAGE': 'C'}
180 180 if 'LD_LIBRARY_PATH' in os.environ:
181 181 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
182 182 if 'SystemRoot' in os.environ:
183 183 # Copy SystemRoot into the custom environment for Python 2.6
184 184 # under Windows. Otherwise, the subprocess will fail with
185 185 # error 0xc0150004. See: http://bugs.python.org/issue3440
186 186 env['SystemRoot'] = os.environ['SystemRoot']
187 187
188 188 if os.path.isdir('.hg'):
189 189 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
190 190 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
191 191 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
192 192 if numerictags: # tag(s) found
193 193 version = numerictags[-1]
194 194 if hgid.endswith('+'): # propagate the dirty status to the tag
195 195 version += '+'
196 196 else: # no tag found
197 197 cmd = [sys.executable, 'hg', 'parents', '--template',
198 198 '{latesttag}+{latesttagdistance}-']
199 199 version = runhg(cmd, env) + hgid
200 200 if version.endswith('+'):
201 201 version += time.strftime('%Y%m%d')
202 202 elif os.path.exists('.hg_archival.txt'):
203 203 kw = dict([[t.strip() for t in l.split(':', 1)]
204 204 for l in open('.hg_archival.txt')])
205 205 if 'tag' in kw:
206 206 version = kw['tag']
207 207 elif 'latesttag' in kw:
208 208 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
209 209 else:
210 210 version = kw.get('node', '')[:12]
211 211
212 212 if version:
213 213 f = open("mercurial/__version__.py", "w")
214 214 f.write('# this file is autogenerated by setup.py\n')
215 215 f.write('version = "%s"\n' % version)
216 216 f.close()
217 217
218 218
219 219 try:
220 220 from mercurial import __version__
221 221 version = __version__.version
222 222 except ImportError:
223 223 version = 'unknown'
224 224
225 225 class hgbuild(build):
226 226 # Insert hgbuildmo first so that files in mercurial/locale/ are found
227 227 # when build_py is run next.
228 228 sub_commands = [('build_mo', None),
229 229
230 230 # We also need build_ext before build_py. Otherwise, when 2to3 is
231 231 # called (in build_py), it will not find osutil & friends,
232 232 # thinking that those modules are global and, consequently, making
233 233 # a mess, now that all module imports are global.
234 234
235 235 ('build_ext', build.has_ext_modules),
236 236 ] + build.sub_commands
237 237
238 238 class hgbuildmo(build):
239 239
240 240 description = "build translations (.mo files)"
241 241
242 242 def run(self):
243 243 if not find_executable('msgfmt'):
244 244 self.warn("could not find msgfmt executable, no translations "
245 245 "will be built")
246 246 return
247 247
248 248 podir = 'i18n'
249 249 if not os.path.isdir(podir):
250 250 self.warn("could not find %s/ directory" % podir)
251 251 return
252 252
253 253 join = os.path.join
254 254 for po in os.listdir(podir):
255 255 if not po.endswith('.po'):
256 256 continue
257 257 pofile = join(podir, po)
258 258 modir = join('locale', po[:-3], 'LC_MESSAGES')
259 259 mofile = join(modir, 'hg.mo')
260 260 mobuildfile = join('mercurial', mofile)
261 261 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
262 262 if sys.platform != 'sunos5':
263 263 # msgfmt on Solaris does not know about -c
264 264 cmd.append('-c')
265 265 self.mkpath(join('mercurial', modir))
266 266 self.make_file([pofile], mobuildfile, spawn, (cmd,))
267 267
268 268
269 269 class hgdist(Distribution):
270 270 pure = 0
271 271
272 272 global_options = Distribution.global_options + \
273 273 [('pure', None, "use pure (slow) Python "
274 274 "code instead of C extensions"),
275 275 ('c2to3', None, "(experimental!) convert "
276 276 "code with 2to3"),
277 277 ]
278 278
279 279 def has_ext_modules(self):
280 280 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
281 281 # too late for some cases
282 282 return not self.pure and Distribution.has_ext_modules(self)
283 283
284 284 class hgbuildext(build_ext):
285 285
286 286 def build_extension(self, ext):
287 287 try:
288 288 build_ext.build_extension(self, ext)
289 289 except CCompilerError:
290 290 if not getattr(ext, 'optional', False):
291 291 raise
292 292 log.warn("Failed to build optional extension '%s' (skipping)",
293 293 ext.name)
294 294
295 295 class hgbuildpy(build_py):
296 296 if convert2to3:
297 297 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
298 298 getfixers("hgfixes")))
299 299
300 300 def finalize_options(self):
301 301 build_py.finalize_options(self)
302 302
303 303 if self.distribution.pure:
304 304 if self.py_modules is None:
305 305 self.py_modules = []
306 306 for ext in self.distribution.ext_modules:
307 307 if ext.name.startswith("mercurial."):
308 308 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
309 309 self.distribution.ext_modules = []
310 310 else:
311 311 h = os.path.join(get_python_inc(), 'Python.h')
312 312 if not os.path.exists(h):
313 313 raise SystemExit('Python headers are required to build '
314 314 'Mercurial but weren\'t found in %s' % h)
315 315
316 316 def find_modules(self):
317 317 modules = build_py.find_modules(self)
318 318 for module in modules:
319 319 if module[0] == "mercurial.pure":
320 320 if module[1] != "__init__":
321 321 yield ("mercurial", module[1], module[2])
322 322 else:
323 323 yield module
324 324
325 325 class buildhgextindex(Command):
326 326 description = 'generate prebuilt index of hgext (for frozen package)'
327 327 user_options = []
328 328 _indexfilename = 'hgext/__index__.py'
329 329
330 330 def initialize_options(self):
331 331 pass
332 332
333 333 def finalize_options(self):
334 334 pass
335 335
336 336 def run(self):
337 337 if os.path.exists(self._indexfilename):
338 338 f = open(self._indexfilename, 'w')
339 339 f.write('# empty\n')
340 340 f.close()
341 341
342 342 # here no extension enabled, disabled() lists up everything
343 343 code = ('import pprint; from mercurial import extensions; '
344 344 'pprint.pprint(extensions.disabled())')
345 345 out, err = runcmd([sys.executable, '-c', code], env)
346 346 if err:
347 347 raise DistutilsExecError(err)
348 348
349 349 f = open(self._indexfilename, 'w')
350 350 f.write('# this file is autogenerated by setup.py\n')
351 351 f.write('docs = ')
352 352 f.write(out)
353 353 f.close()
354 354
355 355 class buildhgexe(build_ext):
356 356 description = 'compile hg.exe from mercurial/exewrapper.c'
357 357
358 358 def build_extensions(self):
359 359 if os.name != 'nt':
360 360 return
361 361 if isinstance(self.compiler, HackedMingw32CCompiler):
362 362 self.compiler.compiler_so = self.compiler.compiler # no -mdll
363 363 self.compiler.dll_libraries = [] # no -lmsrvc90
364 364 hv = sys.hexversion
365 365 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
366 366 f = open('mercurial/hgpythonlib.h', 'wb')
367 367 f.write('/* this file is autogenerated by setup.py */\n')
368 368 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
369 369 f.close()
370 370 objects = self.compiler.compile(['mercurial/exewrapper.c'],
371 371 output_dir=self.build_temp)
372 372 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
373 373 target = os.path.join(dir, 'hg')
374 374 self.compiler.link_executable(objects, target,
375 375 libraries=[],
376 376 output_dir=self.build_temp)
377 377
378 378 class hginstallscripts(install_scripts):
379 379 '''
380 380 This is a specialization of install_scripts that replaces the @LIBDIR@ with
381 381 the configured directory for modules. If possible, the path is made relative
382 382 to the directory for scripts.
383 383 '''
384 384
385 385 def initialize_options(self):
386 386 install_scripts.initialize_options(self)
387 387
388 388 self.install_lib = None
389 389
390 390 def finalize_options(self):
391 391 install_scripts.finalize_options(self)
392 392 self.set_undefined_options('install',
393 393 ('install_lib', 'install_lib'))
394 394
395 395 def run(self):
396 396 install_scripts.run(self)
397 397
398 398 if (os.path.splitdrive(self.install_dir)[0] !=
399 399 os.path.splitdrive(self.install_lib)[0]):
400 400 # can't make relative paths from one drive to another, so use an
401 401 # absolute path instead
402 402 libdir = self.install_lib
403 403 else:
404 404 common = os.path.commonprefix((self.install_dir, self.install_lib))
405 405 rest = self.install_dir[len(common):]
406 406 uplevel = len([n for n in os.path.split(rest) if n])
407 407
408 408 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
409 409
410 410 for outfile in self.outfiles:
411 411 fp = open(outfile, 'rb')
412 412 data = fp.read()
413 413 fp.close()
414 414
415 415 # skip binary files
416 416 if b('\0') in data:
417 417 continue
418 418
419 419 data = data.replace(b('@LIBDIR@'), libdir.encode(libdir_escape))
420 420 fp = open(outfile, 'wb')
421 421 fp.write(data)
422 422 fp.close()
423 423
424 424 cmdclass = {'build': hgbuild,
425 425 'build_mo': hgbuildmo,
426 426 'build_ext': hgbuildext,
427 427 'build_py': hgbuildpy,
428 428 'build_hgextindex': buildhgextindex,
429 429 'install_scripts': hginstallscripts,
430 430 'build_hgexe': buildhgexe,
431 431 }
432 432
433 433 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
434 434 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
435 435 'hgext.largefiles']
436 436
437 437 pymodules = []
438 438
439 439 common_depends = ['mercurial/util.h']
440 440
441 441 extmodules = [
442 442 Extension('mercurial.base85', ['mercurial/base85.c'],
443 443 depends=common_depends),
444 444 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
445 445 depends=common_depends),
446 446 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
447 447 depends=common_depends),
448 448 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
449 449 depends=common_depends),
450 450 Extension('mercurial.parsers', ['mercurial/dirs.c',
451 451 'mercurial/parsers.c',
452 452 'mercurial/pathencode.c'],
453 453 depends=common_depends),
454 454 ]
455 455
456 456 osutil_ldflags = []
457 457
458 458 if sys.platform == 'darwin':
459 459 osutil_ldflags += ['-framework', 'ApplicationServices']
460 460
461 461 # disable osutil.c under windows + python 2.4 (issue1364)
462 462 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
463 463 pymodules.append('mercurial.pure.osutil')
464 464 else:
465 465 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
466 466 extra_link_args=osutil_ldflags,
467 467 depends=common_depends))
468 468
469 469 # the -mno-cygwin option has been deprecated for years
470 470 Mingw32CCompiler = cygwinccompiler.Mingw32CCompiler
471 471
472 472 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
473 473 def __init__(self, *args, **kwargs):
474 474 Mingw32CCompiler.__init__(self, *args, **kwargs)
475 475 for i in 'compiler compiler_so linker_exe linker_so'.split():
476 476 try:
477 477 getattr(self, i).remove('-mno-cygwin')
478 478 except ValueError:
479 479 pass
480 480
481 481 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
482 482
483 483 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
484 484 'help/*.txt']}
485 485
486 486 def ordinarypath(p):
487 487 return p and p[0] != '.' and p[-1] != '~'
488 488
489 489 for root in ('templates',):
490 490 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
491 491 curdir = curdir.split(os.sep, 1)[1]
492 492 dirs[:] = filter(ordinarypath, dirs)
493 493 for f in filter(ordinarypath, files):
494 494 f = os.path.join(curdir, f)
495 495 packagedata['mercurial'].append(f)
496 496
497 497 datafiles = []
498 498 setupversion = version
499 499 extra = {}
500 500
501 501 if py2exeloaded:
502 502 extra['console'] = [
503 503 {'script':'hg',
504 504 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
505 505 'product_version':version}]
506 506 # sub command of 'build' because 'py2exe' does not handle sub_commands
507 507 build.sub_commands.insert(0, ('build_hgextindex', None))
508 508
509 509 if os.name == 'nt':
510 510 # Windows binary file versions for exe/dll files must have the
511 511 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
512 512 setupversion = version.split('+', 1)[0]
513 513
514 514 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
515 515 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
516 516 if version:
517 517 version = version[0]
518 518 xcode4 = (version.startswith('Xcode') and
519 519 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
520 520 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
521 521 else:
522 522 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
523 523 # installed, but instead with only command-line tools. Assume
524 524 # that only happens on >= Lion, thus no PPC support.
525 525 xcode4 = True
526 526 xcode51 = False
527 527
528 528 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
529 529 # distutils.sysconfig
530 530 if xcode4:
531 531 os.environ['ARCHFLAGS'] = ''
532 532
533 533 # XCode 5.1 changes clang such that it now fails to compile if the
534 534 # -mno-fused-madd flag is passed, but the version of Python shipped with
535 535 # OS X 10.9 Mavericks includes this flag. This causes problems in all
536 536 # C extension modules, and a bug has been filed upstream at
537 537 # http://bugs.python.org/issue21244. We also need to patch this here
538 538 # so Mercurial can continue to compile in the meantime.
539 539 if xcode51:
540 540 cflags = get_config_var('CFLAGS')
541 541 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
542 542 os.environ['CFLAGS'] = (
543 543 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
544 544
545 545 setup(name='mercurial',
546 546 version=setupversion,
547 547 author='Matt Mackall and many others',
548 548 author_email='mercurial@selenic.com',
549 549 url='http://mercurial.selenic.com/',
550 550 download_url='http://mercurial.selenic.com/release/',
551 551 description=('Fast scalable distributed SCM (revision control, version '
552 552 'control) system'),
553 553 long_description=('Mercurial is a distributed SCM tool written in Python.'
554 554 ' It is used by a number of large projects that require'
555 555 ' fast, reliable distributed revision control, such as '
556 556 'Mozilla.'),
557 557 license='GNU GPLv2 or any later version',
558 558 classifiers=[
559 559 'Development Status :: 6 - Mature',
560 560 'Environment :: Console',
561 561 'Intended Audience :: Developers',
562 562 'Intended Audience :: System Administrators',
563 563 'License :: OSI Approved :: GNU General Public License (GPL)',
564 564 'Natural Language :: Danish',
565 565 'Natural Language :: English',
566 566 'Natural Language :: German',
567 567 'Natural Language :: Italian',
568 568 'Natural Language :: Japanese',
569 569 'Natural Language :: Portuguese (Brazilian)',
570 570 'Operating System :: Microsoft :: Windows',
571 571 'Operating System :: OS Independent',
572 572 'Operating System :: POSIX',
573 573 'Programming Language :: C',
574 574 'Programming Language :: Python',
575 575 'Topic :: Software Development :: Version Control',
576 576 ],
577 577 scripts=scripts,
578 578 packages=packages,
579 579 py_modules=pymodules,
580 580 ext_modules=extmodules,
581 581 data_files=datafiles,
582 582 package_data=packagedata,
583 583 cmdclass=cmdclass,
584 584 distclass=hgdist,
585 585 options={'py2exe': {'packages': ['hgext', 'email']},
586 'bdist_mpkg': {'zipdist': True,
586 'bdist_mpkg': {'zipdist': False,
587 587 'license': 'COPYING',
588 588 'readme': 'contrib/macosx/Readme.html',
589 589 'welcome': 'contrib/macosx/Welcome.html',
590 590 },
591 591 },
592 592 **extra)
General Comments 0
You need to be logged in to leave comments. Login now