##// END OF EJS Templates
wix: move library.zip and all *.pyd into a lib/ folder...
Steve Borho -
r25409:95e042d7 default
parent child Browse files
Show More
@@ -1,31 +1,35 b''
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
3 3
4 4 <?include guids.wxi ?>
5 5 <?include defines.wxi ?>
6 6
7 7 <Fragment>
8 8 <DirectoryRef Id="INSTALLDIR" FileSource="$(var.SourceDir)">
9 9 <Component Id="distOutput" Guid="$(var.dist.guid)" Win64='$(var.IsX64)'>
10 <File Name="python27.dll" KeyPath="yes" />
11 </Component>
12 <Directory Id="libdir" Name="lib" FileSource="$(var.SourceDir)/lib">
13 <Component Id="libOutput" Guid="$(var.lib.guid)" Win64='$(var.IsX64)'>
10 14 <File Name="library.zip" KeyPath="yes" />
11 15 <File Name="mercurial.base85.pyd" />
12 16 <File Name="mercurial.bdiff.pyd" />
13 17 <File Name="mercurial.diffhelpers.pyd" />
14 18 <File Name="mercurial.mpatch.pyd" />
15 19 <File Name="mercurial.osutil.pyd" />
16 20 <File Name="mercurial.parsers.pyd" />
17 21 <File Name="pyexpat.pyd" />
18 <File Name="python27.dll" />
19 22 <File Name="bz2.pyd" />
20 23 <File Name="select.pyd" />
21 24 <File Name="unicodedata.pyd" />
22 25 <File Name="_ctypes.pyd" />
23 26 <File Name="_elementtree.pyd" />
24 27 <File Name="_hashlib.pyd" />
25 28 <File Name="_socket.pyd" />
26 29 <File Name="_ssl.pyd" />
27 30 </Component>
31 </Directory>
28 32 </DirectoryRef>
29 33 </Fragment>
30 34
31 35 </Wix>
@@ -1,50 +1,51 b''
1 1 <Include>
2 2 <!-- These are component GUIDs used for Mercurial installers.
3 3 YOU MUST CHANGE ALL GUIDs below when copying this file
4 4 and replace 'Mercurial' in this notice with the name of
5 5 your project. Component GUIDs have global namespace! -->
6 6
7 7 <!-- contrib.wxs -->
8 8 <?define contrib.guid = {4E11FFC2-E2F7-482A-8460-9394B5489F02} ?>
9 9 <?define contrib.vim.guid = {BB04903A-652D-4C4F-9590-2BD07A2304F2} ?>
10 10
11 11 <!-- dist.wxs -->
12 <?define dist.guid = {C3B634A4-1B05-4A40-94A9-38EE853CF693} ?>
12 <?define dist.guid = {CE405FE6-CD1E-4873-9C9A-7683AE5A3D90} ?>
13 <?define lib.guid = {91D53B14-E924-432A-ACA2-65F9B3F7C56A} ?>
13 14
14 15 <!-- doc.wxs -->
15 16 <?define doc.hg.1.html.guid = {AAAA3FDA-EDC5-4220-B59D-D342722358A2} ?>
16 17 <?define doc.hgignore.5.html.guid = {AA9118C4-F3A0-4429-A5F4-5A1906B2D67F} ?>
17 18 <?define doc.hgrc.5.html = {E0CEA1EB-FA01-408c-844B-EE5965165BAE} ?>
18 19 <?define doc.style.css = {172F8262-98E0-4711-BD39-4DAE0D77EF05} ?>
19 20
20 21 <!-- help.wxs -->
21 22 <?define helpFolder.guid = {9FA957DB-6DFE-44f2-AD03-293B2791CF17} ?>
22 23
23 24 <!-- i18n.wxs -->
24 25 <?define i18nFolder.guid = {1BF8026D-CF7C-4174-AEE6-D6B7BF119248} ?>
25 26
26 27 <!-- templates.wxs -->
27 28 <?define templates.root.guid = {437FD55C-7756-4EA0-87E5-FDBE75DC8595} ?>
28 29 <?define templates.atom.guid = {D30E14A5-8AF0-4268-8B00-00BEE9E09E39} ?>
29 30 <?define templates.coal.guid = {B63CCAAB-4EAF-43b4-901E-4BD13F5B78FC} ?>
30 31 <?define templates.gitweb.guid = {827334AF-1EFD-421B-962C-5660A068F612} ?>
31 32 <?define templates.json.guid = {F535BE7A-EC34-46E0-B9BE-013F3DBAFB19} ?>
32 33 <?define templates.monoblue.guid = {8060A1E4-BD4C-453E-92CB-9536DC44A9E3} ?>
33 34 <?define templates.paper.guid = {61AB1DE9-645F-46ED-8AF8-0CF02267FFBB} ?>
34 35 <?define templates.raw.guid = {834DF8D7-9784-43A6-851D-A96CE1B3575B} ?>
35 36 <?define templates.rss.guid = {9338FA09-E128-4B1C-B723-1142DBD09E14} ?>
36 37 <?define templates.spartan.guid = {80222625-FA8F-44b1-86CE-1781EF375D09} ?>
37 38 <?define templates.static.guid = {6B3D7C24-98DA-4B67-9F18-35F77357B0B4} ?>
38 39
39 40 <!-- mercurial.wxs -->
40 41 <?define ProductUpgradeCode = {A1CC6134-E945-4399-BE36-EB0017FDF7CF} ?>
41 42
42 43 <?define ComponentMainExecutableGUID = {D102B8FA-059B-4ACC-9FA3-8C78C3B58EEF} ?>
43 44
44 45 <?define ReadMe.guid = {56A8E372-991D-4DCA-B91D-93D775974CF5} ?>
45 46 <?define COPYING.guid = {B7801DBA-1C49-4BF4-91AD-33C65F5C7895} ?>
46 47 <?define mercurial.rc.guid = {1D5FAEEE-7E6E-43B1-9F7F-802714316B15} ?>
47 48 <?define mergetools.rc.guid = {E8A1DC29-FF40-4B5F-BD12-80B9F7BF0CCD} ?>
48 49 <?define ProgramMenuDir.guid = {D5A63320-1238-489B-B68B-CF053E9577CA} ?>
49 50
50 51 </Include>
@@ -1,161 +1,162 b''
1 1 <?xml version='1.0' encoding='windows-1252'?>
2 2 <Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
3 3
4 4 <!-- Copyright 2010 Steve Borho <steve@borho.org>
5 5
6 6 This software may be used and distributed according to the terms of the
7 7 GNU General Public License version 2 or any later version. -->
8 8
9 9 <?include guids.wxi ?>
10 10 <?include defines.wxi ?>
11 11
12 12 <?if $(var.Platform) = "x64" ?>
13 13 <?define PFolder = ProgramFiles64Folder ?>
14 14 <?else?>
15 15 <?define PFolder = ProgramFilesFolder ?>
16 16 <?endif?>
17 17
18 18 <Product Id='*'
19 19 Name='Mercurial $(var.Version) ($(var.Platform))'
20 20 UpgradeCode='$(var.ProductUpgradeCode)'
21 21 Language='1033' Codepage='1252' Version='$(var.Version)'
22 22 Manufacturer='Matt Mackall and others'>
23 23
24 24 <Package Id='*'
25 25 Keywords='Installer'
26 26 Description="Mercurial distributed SCM (version $(var.Version))"
27 27 Comments='$(var.Comments)'
28 28 Platform='$(var.Platform)'
29 29 Manufacturer='Matt Mackall and others'
30 30 InstallerVersion='300' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
31 31
32 32 <Media Id='1' Cabinet='mercurial.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'
33 33 CompressionLevel='high' />
34 34 <Property Id='DiskPrompt' Value="Mercurial $(var.Version) Installation [1]" />
35 35
36 36 <Condition Message='Mercurial MSI installers require Windows XP or higher'>
37 37 VersionNT >= 501
38 38 </Condition>
39 39
40 40 <Property Id="INSTALLDIR">
41 41 <ComponentSearch Id='SearchForMainExecutableComponent'
42 42 Guid='$(var.ComponentMainExecutableGUID)' />
43 43 </Property>
44 44
45 45 <!--Property Id='ARPCOMMENTS'>any comments</Property-->
46 46 <Property Id='ARPCONTACT'>mercurial@selenic.com</Property>
47 47 <Property Id='ARPHELPLINK'>http://mercurial.selenic.com/wiki/</Property>
48 48 <Property Id='ARPURLINFOABOUT'>http://mercurial.selenic.com/about/</Property>
49 49 <Property Id='ARPURLUPDATEINFO'>http://mercurial.selenic.com/downloads/</Property>
50 50 <Property Id='ARPHELPTELEPHONE'>http://mercurial.selenic.com/wiki/Support</Property>
51 51 <Property Id='ARPPRODUCTICON'>hgIcon.ico</Property>
52 52
53 53 <Property Id='INSTALLEDMERCURIALPRODUCTS' Secure='yes'></Property>
54 54 <Property Id='REINSTALLMODE'>amus</Property>
55 55
56 56 <!--Auto-accept the license page-->
57 57 <Property Id='LicenseAccepted'>1</Property>
58 58
59 59 <Directory Id='TARGETDIR' Name='SourceDir'>
60 60 <Directory Id='$(var.PFolder)' Name='PFiles'>
61 61 <Directory Id='INSTALLDIR' Name='Mercurial'>
62 62 <Component Id='MainExecutable' Guid='$(var.ComponentMainExecutableGUID)' Win64='$(var.IsX64)'>
63 63 <File Id='hgEXE' Name='hg.exe' Source='dist\hg.exe' KeyPath='yes' />
64 64 <Environment Id="Environment" Name="PATH" Part="last" System="yes"
65 65 Permanent="no" Value="[INSTALLDIR]" Action="set" />
66 66 </Component>
67 67 <Component Id='ReadMe' Guid='$(var.ReadMe.guid)' Win64='$(var.IsX64)'>
68 68 <File Id='ReadMe' Name='ReadMe.html' Source='contrib\win32\ReadMe.html'
69 69 KeyPath='yes'/>
70 70 </Component>
71 71 <Component Id='COPYING' Guid='$(var.COPYING.guid)' Win64='$(var.IsX64)'>
72 72 <File Id='COPYING' Name='COPYING.rtf' Source='contrib\wix\COPYING.rtf'
73 73 KeyPath='yes'/>
74 74 </Component>
75 75
76 76 <Directory Id='HGRCD' Name='hgrc.d'>
77 77 <Component Id='mercurial.rc' Guid='$(var.mercurial.rc.guid)' Win64='$(var.IsX64)'>
78 78 <File Id='mercurial.rc' Name='Mercurial.rc' Source='contrib\win32\mercurial.ini'
79 79 ReadOnly='yes' KeyPath='yes'/>
80 80 </Component>
81 81 <Component Id='mergetools.rc' Guid='$(var.mergetools.rc.guid)' Win64='$(var.IsX64)'>
82 82 <File Id='mergetools.rc' Name='MergeTools.rc' Source='mercurial\default.d\mergetools.rc'
83 83 ReadOnly='yes' KeyPath='yes'/>
84 84 </Component>
85 85 </Directory>
86 86
87 87 </Directory>
88 88 </Directory>
89 89
90 90 <Directory Id="ProgramMenuFolder" Name="Programs">
91 91 <Directory Id="ProgramMenuDir" Name="Mercurial $(var.Version)">
92 92 <Component Id="ProgramMenuDir" Guid="$(var.ProgramMenuDir.guid)" Win64='$(var.IsX64)'>
93 93 <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
94 94 <RegistryValue Root='HKCU' Key='Software\Mercurial\InstallDir' Type='string'
95 95 Value='[INSTALLDIR]' KeyPath='yes' />
96 96 <Shortcut Id='UrlShortcut' Directory='ProgramMenuDir' Name='Mercurial Web Site'
97 97 Target='[ARPHELPLINK]' Icon="hgIcon.ico" IconIndex='0' />
98 98 </Component>
99 99 </Directory>
100 100 </Directory>
101 101
102 102 <?if $(var.Platform) = "x86" ?>
103 103 <Merge Id='VCRuntime' DiskId='1' Language='1033'
104 104 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
105 105 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
106 106 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
107 107 <?else?>
108 108 <Merge Id='VCRuntime' DiskId='1' Language='1033'
109 109 SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x64_msm.msm' />
110 110 <Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
111 111 SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x64_msm.msm' />
112 112 <?endif?>
113 113 </Directory>
114 114
115 115 <Feature Id='Complete' Title='Mercurial' Description='The complete package'
116 116 Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR' >
117 117 <Feature Id='MainProgram' Title='Program' Description='Mercurial command line app'
118 118 Level='1' Absent='disallow' >
119 119 <ComponentRef Id='MainExecutable' />
120 120 <ComponentRef Id='distOutput' />
121 <ComponentRef Id='libOutput' />
121 122 <ComponentRef Id='ProgramMenuDir' />
122 123 <ComponentRef Id='ReadMe' />
123 124 <ComponentRef Id='COPYING' />
124 125 <ComponentRef Id='mercurial.rc' />
125 126 <ComponentRef Id='mergetools.rc' />
126 127 <ComponentRef Id='helpFolder' />
127 128 <ComponentGroupRef Id='templatesFolder' />
128 129 <MergeRef Id='VCRuntime' />
129 130 <MergeRef Id='VCRuntimePolicy' />
130 131 </Feature>
131 132 <Feature Id='Locales' Title='Translations' Description='Translations' Level='1'>
132 133 <ComponentGroupRef Id='localeFolder' />
133 134 <ComponentRef Id='i18nFolder' />
134 135 </Feature>
135 136 <Feature Id='Documentation' Title='Documentation' Description='HTML man pages' Level='1'>
136 137 <ComponentGroupRef Id='docFolder' />
137 138 </Feature>
138 139 <Feature Id='Misc' Title='Miscellaneous' Description='Contributed scripts' Level='1'>
139 140 <ComponentGroupRef Id='contribFolder' />
140 141 </Feature>
141 142 </Feature>
142 143
143 144 <UIRef Id="WixUI_FeatureTree" />
144 145 <UIRef Id="WixUI_ErrorProgressText" />
145 146
146 147 <WixVariable Id="WixUILicenseRtf" Value="contrib\wix\COPYING.rtf" />
147 148
148 149 <Icon Id="hgIcon.ico" SourceFile="contrib/win32/mercurial.ico" />
149 150
150 151 <Upgrade Id='$(var.ProductUpgradeCode)'>
151 152 <UpgradeVersion
152 153 IncludeMinimum='yes' Minimum='0.0.0' IncludeMaximum='no' OnlyDetect='no'
153 154 Property='INSTALLEDMERCURIALPRODUCTS' />
154 155 </Upgrade>
155 156
156 157 <InstallExecuteSequence>
157 158 <RemoveExistingProducts After='InstallInitialize'/>
158 159 </InstallExecuteSequence>
159 160
160 161 </Product>
161 162 </Wix>
@@ -1,646 +1,648 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, 6, 0, 'final'):
9 9 raise SystemExit("Mercurial requires Python 2.6 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 ispypy = "PyPy" in sys.version
67 67
68 68 import os, stat, subprocess, time
69 69 import re
70 70 import shutil
71 71 import tempfile
72 72 from distutils import log
73 73 from distutils.core import setup, Command, Extension
74 74 from distutils.dist import Distribution
75 75 from distutils.command.build import build
76 76 from distutils.command.build_ext import build_ext
77 77 from distutils.command.build_py import build_py
78 78 from distutils.command.install_lib import install_lib
79 79 from distutils.command.install_scripts import install_scripts
80 80 from distutils.spawn import spawn, find_executable
81 81 from distutils import file_util
82 82 from distutils.errors import CCompilerError, DistutilsExecError
83 83 from distutils.sysconfig import get_python_inc, get_config_var
84 84 from distutils.version import StrictVersion
85 85
86 86 convert2to3 = '--c2to3' in sys.argv
87 87 if convert2to3:
88 88 try:
89 89 from distutils.command.build_py import build_py_2to3 as build_py
90 90 from lib2to3.refactor import get_fixers_from_package as getfixers
91 91 except ImportError:
92 92 if sys.version_info[0] < 3:
93 93 raise SystemExit("--c2to3 is only compatible with python3.")
94 94 raise
95 95 sys.path.append('contrib')
96 96 elif sys.version_info[0] >= 3:
97 97 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
98 98
99 99 scripts = ['hg']
100 100 if os.name == 'nt':
101 101 scripts.append('contrib/win32/hg.bat')
102 102
103 103 # simplified version of distutils.ccompiler.CCompiler.has_function
104 104 # that actually removes its temporary files.
105 105 def hasfunction(cc, funcname):
106 106 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
107 107 devnull = oldstderr = None
108 108 try:
109 109 fname = os.path.join(tmpdir, 'funcname.c')
110 110 f = open(fname, 'w')
111 111 f.write('int main(void) {\n')
112 112 f.write(' %s();\n' % funcname)
113 113 f.write('}\n')
114 114 f.close()
115 115 # Redirect stderr to /dev/null to hide any error messages
116 116 # from the compiler.
117 117 # This will have to be changed if we ever have to check
118 118 # for a function on Windows.
119 119 devnull = open('/dev/null', 'w')
120 120 oldstderr = os.dup(sys.stderr.fileno())
121 121 os.dup2(devnull.fileno(), sys.stderr.fileno())
122 122 objects = cc.compile([fname], output_dir=tmpdir)
123 123 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
124 124 return True
125 125 except Exception:
126 126 return False
127 127 finally:
128 128 if oldstderr is not None:
129 129 os.dup2(oldstderr, sys.stderr.fileno())
130 130 if devnull is not None:
131 131 devnull.close()
132 132 shutil.rmtree(tmpdir)
133 133
134 134 # py2exe needs to be installed to work
135 135 try:
136 136 import py2exe
137 137 py2exe.Distribution # silence unused import warning
138 138 py2exeloaded = True
139 139 # import py2exe's patched Distribution class
140 140 from distutils.core import Distribution
141 141 except ImportError:
142 142 py2exeloaded = False
143 143
144 144 def runcmd(cmd, env):
145 145 if (sys.platform == 'plan9'
146 146 and (sys.version_info[0] == 2 and sys.version_info[1] < 7)):
147 147 # subprocess kludge to work around issues in half-baked Python
148 148 # ports, notably bichued/python:
149 149 _, out, err = os.popen3(cmd)
150 150 return str(out), str(err)
151 151 else:
152 152 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
153 153 stderr=subprocess.PIPE, env=env)
154 154 out, err = p.communicate()
155 155 return out, err
156 156
157 157 def runhg(cmd, env):
158 158 out, err = runcmd(cmd, env)
159 159 # If root is executing setup.py, but the repository is owned by
160 160 # another user (as in "sudo python setup.py install") we will get
161 161 # trust warnings since the .hg/hgrc file is untrusted. That is
162 162 # fine, we don't want to load it anyway. Python may warn about
163 163 # a missing __init__.py in mercurial/locale, we also ignore that.
164 164 err = [e for e in err.splitlines()
165 165 if not e.startswith(b('not trusting file')) \
166 166 and not e.startswith(b('warning: Not importing')) \
167 167 and not e.startswith(b('obsolete feature not enabled'))]
168 168 if err:
169 169 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
170 170 printf(b('\n').join([b(' ') + e for e in err]), file=sys.stderr)
171 171 return ''
172 172 return out
173 173
174 174 version = ''
175 175
176 176 # Execute hg out of this directory with a custom environment which
177 177 # includes the pure Python modules in mercurial/pure. We also take
178 178 # care to not use any hgrc files and do no localization.
179 179 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
180 180 env = {'PYTHONPATH': os.pathsep.join(pypath),
181 181 'HGRCPATH': '',
182 182 'LANGUAGE': 'C'}
183 183 if 'LD_LIBRARY_PATH' in os.environ:
184 184 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
185 185 if 'SystemRoot' in os.environ:
186 186 # Copy SystemRoot into the custom environment for Python 2.6
187 187 # under Windows. Otherwise, the subprocess will fail with
188 188 # error 0xc0150004. See: http://bugs.python.org/issue3440
189 189 env['SystemRoot'] = os.environ['SystemRoot']
190 190
191 191 if os.path.isdir('.hg'):
192 192 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
193 193 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
194 194 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
195 195 if numerictags: # tag(s) found
196 196 version = numerictags[-1]
197 197 if hgid.endswith('+'): # propagate the dirty status to the tag
198 198 version += '+'
199 199 else: # no tag found
200 200 ltagcmd = [sys.executable, 'hg', 'parents', '--template',
201 201 '{latesttag}']
202 202 ltag = runhg(ltagcmd, env)
203 203 changessincecmd = [sys.executable, 'hg', 'log', '-T', 'x\n', '-r',
204 204 "only(.,'%s')" % ltag]
205 205 changessince = len(runhg(changessincecmd, env).splitlines())
206 206 version = '%s+%s-%s' % (ltag, changessince, hgid)
207 207 if version.endswith('+'):
208 208 version += time.strftime('%Y%m%d')
209 209 elif os.path.exists('.hg_archival.txt'):
210 210 kw = dict([[t.strip() for t in l.split(':', 1)]
211 211 for l in open('.hg_archival.txt')])
212 212 if 'tag' in kw:
213 213 version = kw['tag']
214 214 elif 'latesttag' in kw:
215 215 if 'changessincelatesttag' in kw:
216 216 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
217 217 else:
218 218 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
219 219 else:
220 220 version = kw.get('node', '')[:12]
221 221
222 222 if version:
223 223 f = open("mercurial/__version__.py", "w")
224 224 f.write('# this file is autogenerated by setup.py\n')
225 225 f.write('version = "%s"\n' % version)
226 226 f.close()
227 227
228 228
229 229 try:
230 230 from mercurial import __version__
231 231 version = __version__.version
232 232 except ImportError:
233 233 version = 'unknown'
234 234
235 235 class hgbuild(build):
236 236 # Insert hgbuildmo first so that files in mercurial/locale/ are found
237 237 # when build_py is run next.
238 238 sub_commands = [('build_mo', None),
239 239
240 240 # We also need build_ext before build_py. Otherwise, when 2to3 is
241 241 # called (in build_py), it will not find osutil & friends,
242 242 # thinking that those modules are global and, consequently, making
243 243 # a mess, now that all module imports are global.
244 244
245 245 ('build_ext', build.has_ext_modules),
246 246 ] + build.sub_commands
247 247
248 248 class hgbuildmo(build):
249 249
250 250 description = "build translations (.mo files)"
251 251
252 252 def run(self):
253 253 if not find_executable('msgfmt'):
254 254 self.warn("could not find msgfmt executable, no translations "
255 255 "will be built")
256 256 return
257 257
258 258 podir = 'i18n'
259 259 if not os.path.isdir(podir):
260 260 self.warn("could not find %s/ directory" % podir)
261 261 return
262 262
263 263 join = os.path.join
264 264 for po in os.listdir(podir):
265 265 if not po.endswith('.po'):
266 266 continue
267 267 pofile = join(podir, po)
268 268 modir = join('locale', po[:-3], 'LC_MESSAGES')
269 269 mofile = join(modir, 'hg.mo')
270 270 mobuildfile = join('mercurial', mofile)
271 271 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
272 272 if sys.platform != 'sunos5':
273 273 # msgfmt on Solaris does not know about -c
274 274 cmd.append('-c')
275 275 self.mkpath(join('mercurial', modir))
276 276 self.make_file([pofile], mobuildfile, spawn, (cmd,))
277 277
278 278
279 279 class hgdist(Distribution):
280 280 pure = ispypy
281 281
282 282 global_options = Distribution.global_options + \
283 283 [('pure', None, "use pure (slow) Python "
284 284 "code instead of C extensions"),
285 285 ('c2to3', None, "(experimental!) convert "
286 286 "code with 2to3"),
287 287 ]
288 288
289 289 def has_ext_modules(self):
290 290 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
291 291 # too late for some cases
292 292 return not self.pure and Distribution.has_ext_modules(self)
293 293
294 294 class hgbuildext(build_ext):
295 295
296 296 def build_extension(self, ext):
297 297 try:
298 298 build_ext.build_extension(self, ext)
299 299 except CCompilerError:
300 300 if not getattr(ext, 'optional', False):
301 301 raise
302 302 log.warn("Failed to build optional extension '%s' (skipping)",
303 303 ext.name)
304 304
305 305 class hgbuildpy(build_py):
306 306 if convert2to3:
307 307 fixer_names = sorted(set(getfixers("lib2to3.fixes") +
308 308 getfixers("hgfixes")))
309 309
310 310 def finalize_options(self):
311 311 build_py.finalize_options(self)
312 312
313 313 if self.distribution.pure:
314 314 if self.py_modules is None:
315 315 self.py_modules = []
316 316 for ext in self.distribution.ext_modules:
317 317 if ext.name.startswith("mercurial."):
318 318 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
319 319 self.distribution.ext_modules = []
320 320 else:
321 321 h = os.path.join(get_python_inc(), 'Python.h')
322 322 if not os.path.exists(h):
323 323 raise SystemExit('Python headers are required to build '
324 324 'Mercurial but weren\'t found in %s' % h)
325 325
326 326 def find_modules(self):
327 327 modules = build_py.find_modules(self)
328 328 for module in modules:
329 329 if module[0] == "mercurial.pure":
330 330 if module[1] != "__init__":
331 331 yield ("mercurial", module[1], module[2])
332 332 else:
333 333 yield module
334 334
335 335 class buildhgextindex(Command):
336 336 description = 'generate prebuilt index of hgext (for frozen package)'
337 337 user_options = []
338 338 _indexfilename = 'hgext/__index__.py'
339 339
340 340 def initialize_options(self):
341 341 pass
342 342
343 343 def finalize_options(self):
344 344 pass
345 345
346 346 def run(self):
347 347 if os.path.exists(self._indexfilename):
348 348 f = open(self._indexfilename, 'w')
349 349 f.write('# empty\n')
350 350 f.close()
351 351
352 352 # here no extension enabled, disabled() lists up everything
353 353 code = ('import pprint; from mercurial import extensions; '
354 354 'pprint.pprint(extensions.disabled())')
355 355 out, err = runcmd([sys.executable, '-c', code], env)
356 356 if err:
357 357 raise DistutilsExecError(err)
358 358
359 359 f = open(self._indexfilename, 'w')
360 360 f.write('# this file is autogenerated by setup.py\n')
361 361 f.write('docs = ')
362 362 f.write(out)
363 363 f.close()
364 364
365 365 class buildhgexe(build_ext):
366 366 description = 'compile hg.exe from mercurial/exewrapper.c'
367 367
368 368 def build_extensions(self):
369 369 if os.name != 'nt':
370 370 return
371 371 if isinstance(self.compiler, HackedMingw32CCompiler):
372 372 self.compiler.compiler_so = self.compiler.compiler # no -mdll
373 373 self.compiler.dll_libraries = [] # no -lmsrvc90
374 374 hv = sys.hexversion
375 375 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
376 376 f = open('mercurial/hgpythonlib.h', 'wb')
377 377 f.write('/* this file is autogenerated by setup.py */\n')
378 378 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
379 379 f.close()
380 380 objects = self.compiler.compile(['mercurial/exewrapper.c'],
381 381 output_dir=self.build_temp)
382 382 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
383 383 target = os.path.join(dir, 'hg')
384 384 self.compiler.link_executable(objects, target,
385 385 libraries=[],
386 386 output_dir=self.build_temp)
387 387
388 388 class hginstalllib(install_lib):
389 389 '''
390 390 This is a specialization of install_lib that replaces the copy_file used
391 391 there so that it supports setting the mode of files after copying them,
392 392 instead of just preserving the mode that the files originally had. If your
393 393 system has a umask of something like 027, preserving the permissions when
394 394 copying will lead to a broken install.
395 395
396 396 Note that just passing keep_permissions=False to copy_file would be
397 397 insufficient, as it might still be applying a umask.
398 398 '''
399 399
400 400 def run(self):
401 401 realcopyfile = file_util.copy_file
402 402 def copyfileandsetmode(*args, **kwargs):
403 403 src, dst = args[0], args[1]
404 404 dst, copied = realcopyfile(*args, **kwargs)
405 405 if copied:
406 406 st = os.stat(src)
407 407 # Persist executable bit (apply it to group and other if user
408 408 # has it)
409 409 if st[stat.ST_MODE] & stat.S_IXUSR:
410 410 setmode = int('0755', 8)
411 411 else:
412 412 setmode = int('0644', 8)
413 413 m = stat.S_IMODE(st[stat.ST_MODE])
414 414 m = (m & ~int('0777', 8)) | setmode
415 415 os.chmod(dst, m)
416 416 file_util.copy_file = copyfileandsetmode
417 417 try:
418 418 install_lib.run(self)
419 419 finally:
420 420 file_util.copy_file = realcopyfile
421 421
422 422 class hginstallscripts(install_scripts):
423 423 '''
424 424 This is a specialization of install_scripts that replaces the @LIBDIR@ with
425 425 the configured directory for modules. If possible, the path is made relative
426 426 to the directory for scripts.
427 427 '''
428 428
429 429 def initialize_options(self):
430 430 install_scripts.initialize_options(self)
431 431
432 432 self.install_lib = None
433 433
434 434 def finalize_options(self):
435 435 install_scripts.finalize_options(self)
436 436 self.set_undefined_options('install',
437 437 ('install_lib', 'install_lib'))
438 438
439 439 def run(self):
440 440 install_scripts.run(self)
441 441
442 442 if (os.path.splitdrive(self.install_dir)[0] !=
443 443 os.path.splitdrive(self.install_lib)[0]):
444 444 # can't make relative paths from one drive to another, so use an
445 445 # absolute path instead
446 446 libdir = self.install_lib
447 447 else:
448 448 common = os.path.commonprefix((self.install_dir, self.install_lib))
449 449 rest = self.install_dir[len(common):]
450 450 uplevel = len([n for n in os.path.split(rest) if n])
451 451
452 452 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
453 453
454 454 for outfile in self.outfiles:
455 455 fp = open(outfile, 'rb')
456 456 data = fp.read()
457 457 fp.close()
458 458
459 459 # skip binary files
460 460 if b('\0') in data:
461 461 continue
462 462
463 463 data = data.replace(b('@LIBDIR@'), libdir.encode(libdir_escape))
464 464 fp = open(outfile, 'wb')
465 465 fp.write(data)
466 466 fp.close()
467 467
468 468 cmdclass = {'build': hgbuild,
469 469 'build_mo': hgbuildmo,
470 470 'build_ext': hgbuildext,
471 471 'build_py': hgbuildpy,
472 472 'build_hgextindex': buildhgextindex,
473 473 'install_lib': hginstalllib,
474 474 'install_scripts': hginstallscripts,
475 475 'build_hgexe': buildhgexe,
476 476 }
477 477
478 478 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
479 479 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf',
480 480 'hgext.largefiles']
481 481
482 482 pymodules = []
483 483
484 484 common_depends = ['mercurial/util.h']
485 485
486 486 osutil_ldflags = []
487 487
488 488 if sys.platform == 'darwin':
489 489 osutil_ldflags += ['-framework', 'ApplicationServices']
490 490
491 491 extmodules = [
492 492 Extension('mercurial.base85', ['mercurial/base85.c'],
493 493 depends=common_depends),
494 494 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
495 495 depends=common_depends),
496 496 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
497 497 depends=common_depends),
498 498 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
499 499 depends=common_depends),
500 500 Extension('mercurial.parsers', ['mercurial/dirs.c',
501 501 'mercurial/manifest.c',
502 502 'mercurial/parsers.c',
503 503 'mercurial/pathencode.c'],
504 504 depends=common_depends),
505 505 Extension('mercurial.osutil', ['mercurial/osutil.c'],
506 506 extra_link_args=osutil_ldflags,
507 507 depends=common_depends),
508 508 ]
509 509
510 510 try:
511 511 from distutils import cygwinccompiler
512 512
513 513 # the -mno-cygwin option has been deprecated for years
514 514 compiler = cygwinccompiler.Mingw32CCompiler
515 515
516 516 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
517 517 def __init__(self, *args, **kwargs):
518 518 compiler.__init__(self, *args, **kwargs)
519 519 for i in 'compiler compiler_so linker_exe linker_so'.split():
520 520 try:
521 521 getattr(self, i).remove('-mno-cygwin')
522 522 except ValueError:
523 523 pass
524 524
525 525 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
526 526 except ImportError:
527 527 # the cygwinccompiler package is not available on some Python
528 528 # distributions like the ones from the optware project for Synology
529 529 # DiskStation boxes
530 530 class HackedMingw32CCompiler(object):
531 531 pass
532 532
533 533 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
534 534 'help/*.txt',
535 535 'default.d/*.rc',
536 536 'dummycert.pem']}
537 537
538 538 def ordinarypath(p):
539 539 return p and p[0] != '.' and p[-1] != '~'
540 540
541 541 for root in ('templates',):
542 542 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
543 543 curdir = curdir.split(os.sep, 1)[1]
544 544 dirs[:] = filter(ordinarypath, dirs)
545 545 for f in filter(ordinarypath, files):
546 546 f = os.path.join(curdir, f)
547 547 packagedata['mercurial'].append(f)
548 548
549 549 datafiles = []
550 550 setupversion = version
551 551 extra = {}
552 552
553 553 if py2exeloaded:
554 554 extra['console'] = [
555 555 {'script':'hg',
556 556 'copyright':'Copyright (C) 2005-2015 Matt Mackall and others',
557 557 'product_version':version}]
558 558 # sub command of 'build' because 'py2exe' does not handle sub_commands
559 559 build.sub_commands.insert(0, ('build_hgextindex', None))
560 # put dlls in sub directory so that they won't pollute PATH
561 extra['zipfile'] = 'lib/library.zip'
560 562
561 563 if os.name == 'nt':
562 564 # Windows binary file versions for exe/dll files must have the
563 565 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
564 566 setupversion = version.split('+', 1)[0]
565 567
566 568 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
567 569 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
568 570 if version:
569 571 version = version[0]
570 572 if sys.version_info[0] == 3:
571 573 version = version.decode('utf-8')
572 574 xcode4 = (version.startswith('Xcode') and
573 575 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
574 576 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
575 577 else:
576 578 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
577 579 # installed, but instead with only command-line tools. Assume
578 580 # that only happens on >= Lion, thus no PPC support.
579 581 xcode4 = True
580 582 xcode51 = False
581 583
582 584 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
583 585 # distutils.sysconfig
584 586 if xcode4:
585 587 os.environ['ARCHFLAGS'] = ''
586 588
587 589 # XCode 5.1 changes clang such that it now fails to compile if the
588 590 # -mno-fused-madd flag is passed, but the version of Python shipped with
589 591 # OS X 10.9 Mavericks includes this flag. This causes problems in all
590 592 # C extension modules, and a bug has been filed upstream at
591 593 # http://bugs.python.org/issue21244. We also need to patch this here
592 594 # so Mercurial can continue to compile in the meantime.
593 595 if xcode51:
594 596 cflags = get_config_var('CFLAGS')
595 597 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
596 598 os.environ['CFLAGS'] = (
597 599 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
598 600
599 601 setup(name='mercurial',
600 602 version=setupversion,
601 603 author='Matt Mackall and many others',
602 604 author_email='mercurial@selenic.com',
603 605 url='http://mercurial.selenic.com/',
604 606 download_url='http://mercurial.selenic.com/release/',
605 607 description=('Fast scalable distributed SCM (revision control, version '
606 608 'control) system'),
607 609 long_description=('Mercurial is a distributed SCM tool written in Python.'
608 610 ' It is used by a number of large projects that require'
609 611 ' fast, reliable distributed revision control, such as '
610 612 'Mozilla.'),
611 613 license='GNU GPLv2 or any later version',
612 614 classifiers=[
613 615 'Development Status :: 6 - Mature',
614 616 'Environment :: Console',
615 617 'Intended Audience :: Developers',
616 618 'Intended Audience :: System Administrators',
617 619 'License :: OSI Approved :: GNU General Public License (GPL)',
618 620 'Natural Language :: Danish',
619 621 'Natural Language :: English',
620 622 'Natural Language :: German',
621 623 'Natural Language :: Italian',
622 624 'Natural Language :: Japanese',
623 625 'Natural Language :: Portuguese (Brazilian)',
624 626 'Operating System :: Microsoft :: Windows',
625 627 'Operating System :: OS Independent',
626 628 'Operating System :: POSIX',
627 629 'Programming Language :: C',
628 630 'Programming Language :: Python',
629 631 'Topic :: Software Development :: Version Control',
630 632 ],
631 633 scripts=scripts,
632 634 packages=packages,
633 635 py_modules=pymodules,
634 636 ext_modules=extmodules,
635 637 data_files=datafiles,
636 638 package_data=packagedata,
637 639 cmdclass=cmdclass,
638 640 distclass=hgdist,
639 641 options={'py2exe': {'packages': ['hgext', 'email']},
640 642 'bdist_mpkg': {'zipdist': False,
641 643 'license': 'COPYING',
642 644 'readme': 'contrib/macosx/Readme.html',
643 645 'welcome': 'contrib/macosx/Welcome.html',
644 646 },
645 647 },
646 648 **extra)
General Comments 0
You need to be logged in to leave comments. Login now