Make a status test pass against old servers.
[svn.git] / build / generator / gen_vcnet_vcproj.py
blob3b3c7b8cbaa942da43f8f5c196645cc902be97ae
2 # gen_vcnet.py -- generate Microsoft Visual C++.NET projects
5 import os
6 import md5
7 import string
9 import gen_base
10 import gen_win
11 import ezt
14 class Generator(gen_win.WinGeneratorBase):
15 "Generate a Visual C++.NET project"
17 def __init__(self, fname, verfname, options):
18 gen_win.WinGeneratorBase.__init__(self, fname, verfname, options,
19 'vcnet-vcproj')
21 def quote(self, str):
22 return '"%s"' % str
24 def get_external_project(self, target, proj_ext):
25 "Link project files: prefer vcproj's, but if don't exist, try dsp's."
26 vcproj = gen_win.WinGeneratorBase.get_external_project(self, target,
27 proj_ext)
28 if vcproj and not os.path.exists(vcproj):
29 dspproj = gen_win.WinGeneratorBase.get_external_project(self, target,
30 'dsp')
31 if os.path.exists(dspproj):
32 return dspproj
34 return vcproj
36 def write_project(self, target, fname):
37 "Write a Project (.vcproj)"
39 if isinstance(target, gen_base.TargetExe):
40 #EXE
41 config_type=1
42 elif isinstance(target, gen_base.TargetJava):
43 config_type=1
44 elif isinstance(target, gen_base.TargetLib):
45 if target.msvc_static:
46 config_type=4
47 else:
48 config_type=2
49 elif isinstance(target, gen_base.TargetProject):
50 config_type=1
51 elif isinstance(target, gen_base.TargetI18N):
52 config_type=4
53 else:
54 raise gen_base.GenError("Cannot create project for %s" % target.name)
56 target.output_name = self.get_output_name(target)
57 target.output_pdb = self.get_output_pdb(target)
58 target.output_dir = self.get_output_dir(target)
59 target.intermediate_dir = self.get_intermediate_dir(target)
61 configs = self.get_configs(target)
63 sources = self.get_proj_sources(False, target)
65 data = {
66 'target' : target,
67 'target_type' : config_type,
68 # 'target_number' : targval,
69 'rootpath' : self.rootpath,
70 'platforms' : self.platforms,
71 'configs' : configs,
72 'includes' : self.get_win_includes(target),
73 'sources' : sources,
74 'default_platform' : self.platforms[0],
75 'default_config' : configs[0].name,
76 'def_file' : self.get_def_file(target),
77 'is_exe' : ezt.boolean(isinstance(target, gen_base.TargetExe)),
78 'is_external' : ezt.boolean((isinstance(target, gen_base.TargetProject)
79 or isinstance(target, gen_base.TargetI18N))
80 and target.cmd),
81 'is_utility' : ezt.boolean(isinstance(target,
82 gen_base.TargetProject)),
83 'instrument_apr_pools' : self.instrument_apr_pools,
84 'instrument_purify_quantify' : self.instrument_purify_quantify,
85 'version' : self.vsnet_proj_ver,
88 self.write_with_template(fname, 'vcnet_vcproj.ezt', data)
90 def makeguid(self, data):
91 "Generate a windows style GUID"
92 ### blah. this function can generate invalid GUIDs. leave it for now,
93 ### but we need to fix it. we can wrap the apr UUID functions, or
94 ### implement this from scratch using the algorithms described in
95 ### http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
97 hash = md5.md5(data)
98 try:
99 myhash = hash.hexdigest()
100 except AttributeError:
101 # Python 1.5.2
102 myhash = string.join(map(lambda x: '%02x' % ord(x), hash.digest()), '')
104 guid = string.upper("{%s-%s-%s-%s-%s}" % (myhash[0:8], myhash[8:12],
105 myhash[12:16], myhash[16:20],
106 myhash[20:32]))
107 return guid
109 def getguid(self, path):
110 "Try to get a project's guid from its project file"
111 try:
112 proj = open(path)
113 line = proj.readline()
114 while len(line) > 0:
115 l = string.lower(line)
116 pos = string.find(l, 'projectguid="{')
117 if pos >= 0:
118 guid = line[pos+13:pos+13+38]
119 return guid
120 line = proj.readline()
121 proj.close()
122 except IOError:
123 return None
125 def write(self):
126 "Write a Solution (.sln)"
128 # apr doesn't supply vcproj files, the user must convert them
129 # manually before loading the generated solution
130 self.move_proj_file(os.path.join('build', 'win32'), 'svn_config.vcproj')
131 self.move_proj_file(os.path.join('build', 'win32'), 'svn_locale.vcproj')
132 self.write_zlib_project_file('zlib.vcproj')
133 self.write_neon_project_file('neon.vcproj')
134 self.write_serf_project_file('serf.vcproj')
136 install_targets = self.get_install_targets()
138 targets = [ ]
140 guids = { }
142 # VC.NET uses GUIDs to refer to projects. Get them up front
143 # because we need them already assigned on the dependencies for
144 # each target we work with.
145 for target in install_targets:
146 # These aren't working yet
147 if isinstance(target, gen_base.TargetProject) and target.cmd:
148 continue
149 # If there is a GUID in an external project, then use it
150 # rather than generating our own that won't match and will
151 # cause dependency failures.
152 guid = None
153 proj_path = self.get_external_project(target, 'vcproj')
154 if proj_path is not None:
155 guid = self.getguid(proj_path)
156 if guid is None:
157 guid = self.makeguid(target.name)
158 guids[target.name] = guid
160 self.gen_proj_names(install_targets)
162 # Traverse the targets and generate the project files
163 for target in install_targets:
164 name = target.name
165 # These aren't working yet
166 if isinstance(target, gen_base.TargetProject) and target.cmd:
167 continue
169 fname = self.get_external_project(target, 'vcproj')
170 if fname is None:
171 fname = os.path.join(self.projfilesdir,
172 "%s_vcnet.vcproj" % target.proj_name)
173 self.write_project(target, fname)
175 if '-' in fname:
176 fname = '"%s"' % fname
178 depends = [ ]
179 if not isinstance(target, gen_base.TargetI18N):
180 depends = self.adjust_win_depends(target, name)
182 deplist = [ ]
183 for i in range(len(depends)):
184 deplist.append(gen_win.ProjectItem(guid=guids[depends[i].name],
185 index=i,
187 targets.append(
188 gen_win.ProjectItem(name=target.name,
189 path=string.replace(fname, os.sep, '\\'),
190 guid=guids[target.name],
191 depends=deplist,
194 # the path name in the .sln template is already enclosed with ""
195 # therefore, remove them from the path itself
196 for target in targets:
197 target.path = string.rstrip(target.path, '"')
198 target.path = string.lstrip(target.path, '"')
200 targets.sort(lambda x, y: cmp(x.name, y.name))
202 configs = [ ]
203 for i in range(len(self.configs)):
204 ### this is different from write_project
205 configs.append(gen_win.ProjectItem(name=self.configs[i], index=i))
207 # sort the values for output stability.
208 guidvals = guids.values()
209 guidvals.sort()
211 data = {
212 'version': self.vsnet_version,
213 'targets' : targets,
214 'configs' : configs,
215 'platforms' : self.platforms,
216 'guids' : guidvals,
219 if self.vsnet_version == '10.00' or self.vsnet_version == '9.00':
220 self.write_with_template('subversion_vcnet.sln', 'vc2005_sln.ezt', data)
221 else:
222 self.write_with_template('subversion_vcnet.sln', 'vcnet_sln.ezt', data)
225 # compatibility with older Pythons:
226 try:
227 True
228 except NameError:
229 True = 1
230 False = 0