2 # gen_vcnet.py -- generate Microsoft Visual C++.NET projects
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
,
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
,
28 if vcproj
and not os
.path
.exists(vcproj
):
29 dspproj
= gen_win
.WinGeneratorBase
.get_external_project(self
, target
,
31 if os
.path
.exists(dspproj
):
36 def write_project(self
, target
, fname
):
37 "Write a Project (.vcproj)"
39 if isinstance(target
, gen_base
.TargetExe
):
42 elif isinstance(target
, gen_base
.TargetJava
):
44 elif isinstance(target
, gen_base
.TargetLib
):
45 if target
.msvc_static
:
49 elif isinstance(target
, gen_base
.TargetProject
):
51 elif isinstance(target
, gen_base
.TargetI18N
):
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
)
67 'target_type' : config_type
,
68 # 'target_number' : targval,
69 'rootpath' : self
.rootpath
,
70 'platforms' : self
.platforms
,
72 'includes' : self
.get_win_includes(target
),
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
))
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
99 myhash
= hash.hexdigest()
100 except AttributeError:
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],
109 def getguid(self
, path
):
110 "Try to get a project's guid from its project file"
113 line
= proj
.readline()
115 l
= string
.lower(line
)
116 pos
= string
.find(l
, 'projectguid="{')
118 guid
= line
[pos
+13:pos
+13+38]
120 line
= proj
.readline()
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()
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
:
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.
153 proj_path
= self
.get_external_project(target
, 'vcproj')
154 if proj_path
is not None:
155 guid
= self
.getguid(proj_path
)
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
:
165 # These aren't working yet
166 if isinstance(target
, gen_base
.TargetProject
) and target
.cmd
:
169 fname
= self
.get_external_project(target
, 'vcproj')
171 fname
= os
.path
.join(self
.projfilesdir
,
172 "%s_vcnet.vcproj" % target
.proj_name
)
173 self
.write_project(target
, fname
)
176 fname
= '"%s"' % fname
179 if not isinstance(target
, gen_base
.TargetI18N
):
180 depends
= self
.adjust_win_depends(target
, name
)
183 for i
in range(len(depends
)):
184 deplist
.append(gen_win
.ProjectItem(guid
=guids
[depends
[i
].name
],
188 gen_win
.ProjectItem(name
=target
.name
,
189 path
=string
.replace(fname
, os
.sep
, '\\'),
190 guid
=guids
[target
.name
],
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
))
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()
212 'version': self
.vsnet_version
,
215 'platforms' : self
.platforms
,
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
)
222 self
.write_with_template('subversion_vcnet.sln', 'vcnet_sln.ezt', data
)
225 # compatibility with older Pythons: