| # |
| # gen_vcnet.py -- generate Microsoft Visual C++.NET projects |
| # |
| |
| import os |
| import md5 |
| import string |
| |
| import gen_base |
| import gen_win |
| import ezt |
| |
| |
| class Generator(gen_win.WinGeneratorBase): |
| "Generate a Visual C++.NET project" |
| |
| def __init__(self, fname, verfname, options): |
| gen_win.WinGeneratorBase.__init__(self, fname, verfname, options, |
| 'vcnet-vcproj') |
| |
| def default_output(self, oname): |
| return 'subversion_vcnet.sln' |
| |
| def quote(self, str): |
| return '"%s"' % str |
| |
| def write_project(self, target, fname): |
| "Write a Project (.vcproj)" |
| |
| if isinstance(target, gen_base.TargetExe): |
| #EXE |
| config_type=1 |
| elif isinstance(target, gen_base.TargetJava): |
| config_type=1 |
| elif isinstance(target, gen_base.TargetLib): |
| if target.msvc_static: |
| config_type=4 |
| else: |
| config_type=2 |
| elif isinstance(target, gen_base.TargetProject): |
| config_type=1 |
| elif isinstance(target, gen_base.TargetI18N): |
| config_type=4 |
| else: |
| raise gen_base.GenError("Cannot create project for %s" % target.name) |
| |
| target.output_name = self.get_output_name(target) |
| target.output_dir = self.get_output_dir(target) |
| target.intermediate_dir = self.get_intermediate_dir(target) |
| |
| configs = self.get_configs(target) |
| |
| sources = self.get_proj_sources(False, target) |
| |
| data = { |
| 'target' : target, |
| 'target_type' : config_type, |
| # 'target_number' : targval, |
| 'rootpath' : self.rootpath, |
| 'platforms' : self.platforms, |
| 'configs' : configs, |
| 'includes' : self.get_win_includes(target), |
| 'sources' : sources, |
| 'default_platform' : self.platforms[0], |
| 'default_config' : configs[0].name, |
| 'def_file' : self.get_def_file(target), |
| 'is_exe' : ezt.boolean(isinstance(target, gen_base.TargetExe)), |
| 'is_external' : ezt.boolean((isinstance(target, gen_base.TargetProject) |
| or isinstance(target, gen_base.TargetI18N)) |
| and target.cmd), |
| 'is_utility' : ezt.boolean(isinstance(target, |
| gen_base.TargetProject)), |
| 'instrument_apr_pools' : self.instrument_apr_pools, |
| 'instrument_purify_quantify' : self.instrument_purify_quantify, |
| } |
| |
| self.write_with_template(fname, 'vcnet_vcproj.ezt', data) |
| |
| def makeguid(self, data): |
| "Generate a windows style GUID" |
| ### blah. this function can generate invalid GUIDs. leave it for now, |
| ### but we need to fix it. we can wrap the apr UUID functions, or |
| ### implement this from scratch using the algorithms described in |
| ### http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt |
| |
| hash = md5.md5(data) |
| try: |
| myhash = hash.hexdigest() |
| except AttributeError: |
| # Python 1.5.2 |
| myhash = string.join(map(lambda x: '%02x' % ord(x), hash.digest()), '') |
| |
| guid = string.upper("{%s-%s-%s-%s-%s}" % (myhash[0:8], myhash[8:12], |
| myhash[12:16], myhash[16:20], |
| myhash[20:32])) |
| return guid |
| |
| def move_proj_file(self, path, name): |
| dest_file = os.path.join(path, name) |
| source_file = os.path.join('build', 'win32', name + '.in') |
| self.write_file_if_changed(dest_file, open(source_file, 'rb').read()) |
| |
| def write(self, oname): |
| "Write a Solution (.sln)" |
| |
| # apr doesn't supply vcproj files, so move our pre-defined ones |
| # over if they don't match |
| self.move_proj_file(self.apr_path, 'libapr.vcproj') |
| self.move_proj_file(self.apr_iconv_path, 'libapriconv.vcproj') |
| self.move_proj_file(os.path.join(self.apr_iconv_path,'ccs'), |
| 'libapriconv_ccs_modules.vcproj') |
| self.move_proj_file(os.path.join(self.apr_iconv_path,'ces'), |
| 'libapriconv_ces_modules.vcproj') |
| self.move_proj_file(self.apr_util_path, 'libaprutil.vcproj') |
| self.move_proj_file(os.path.join(self.apr_util_path,'uri'), |
| 'gen_uri_delims.vcproj') |
| self.move_proj_file(os.path.join(self.apr_util_path,'xml', 'expat', |
| 'lib'), 'xml.vcproj') |
| |
| install_targets = self.get_install_targets() |
| |
| targets = [ ] |
| |
| guids = { } |
| |
| # VC.NET uses GUIDs to refer to projects. generate them up front |
| # because we need them already assigned on the dependencies for |
| # each target we work with. |
| for target in install_targets: |
| # These aren't working yet |
| if isinstance(target, gen_base.TargetProject) and target.cmd: |
| continue |
| guids[target.name] = self.makeguid(target.name) |
| |
| self.gen_proj_names(install_targets) |
| |
| # Traverse the targets and generate the project files |
| for target in install_targets: |
| name = target.name |
| # These aren't working yet |
| if isinstance(target, gen_base.TargetProject) and target.cmd: |
| continue |
| |
| fname = self.get_external_project(target, 'vcproj') |
| if fname is None: |
| fname = os.path.join(self.projfilesdir, |
| "%s_vcnet.vcproj" % target.proj_name) |
| self.write_project(target, fname) |
| |
| if '-' in fname: |
| fname = '"%s"' % fname |
| |
| depends = [ ] |
| if not isinstance(target, gen_base.TargetI18N): |
| depends = self.adjust_win_depends(target, name) |
| |
| deplist = [ ] |
| for i in range(len(depends)): |
| deplist.append(gen_win.ProjectItem(guid=guids[depends[i].name], |
| index=i, |
| )) |
| targets.append( |
| gen_win.ProjectItem(name=target.name, |
| path=string.replace(fname, os.sep, '\\'), |
| guid=guids[target.name], |
| depends=deplist, |
| )) |
| |
| targets.sort(lambda x, y: cmp(x.name, y.name)) |
| |
| configs = [ ] |
| for i in range(len(self.configs)): |
| ### this is different from write_project |
| configs.append(gen_win.ProjectItem(name=self.configs[i], index=i)) |
| |
| # sort the values for output stability. |
| guidvals = guids.values() |
| guidvals.sort() |
| |
| data = { |
| 'targets' : targets, |
| 'configs' : configs, |
| 'platforms' : self.platforms, |
| 'guids' : guidvals, |
| } |
| |
| self.write_with_template(oname, 'vcnet_sln.ezt', data) |
| |
| |
| # compatibility with older Pythons: |
| try: |
| True |
| except NameError: |
| True = 1 |
| False = 0 |