Example #1
0
	def generate(self, **kwargs):
		executor = kwargs.get("executor", None)
		buildfile = kwargs.get("buildfile", None)
		filemanager = kwargs.get("filemanager", None)
		target_platform = kwargs.get("target_platform", None)
		context_list = kwargs.get("context_list", None)

		for context in context_list:
			architectures, configurations = buildfile.get_layout_params(context.product)

			# get the full project path for this
			full_project_path = os.path.join(context.abs_project_root, ("%s.vcxproj" % context.product.name))

			# create the project and open a FileWriter object.
			handle = filemanager.create(full_project_path)
			writer = FileWriter(handle)
			document = Document()

			settings = VSSettings(
				document=document,
				version=self.requested_version,
				settings=self.driver_schema
			)

			# establish the root project node
			properties = {
				"DefaultTargets": settings.get("DefaultTargets"),
				"ToolsVersion": settings.get("ToolsVersion"),
				# this resource was moved by microsoft; but is required for VS to load the project.
				"xmlns": "http://schemas.microsoft.com/developer/msbuild/2003"
			}
			project = Project(settings, properties)
			document.appendChild(project.node)

			#
			# setup the project configurations item group
			#
			item_group = ItemGroup(settings, {"Label" : "ProjectConfigurations"})
			project.node.appendChild(item_group.node)


			#
			add_project_configurations(settings, item_group, architectures, configurations)


			#
			# Globals property group
			#

			project_guid = "{%s}" % str(uuid.uuid4()).upper()
			# the ProjectGuid is different between VS2010 and VS2013. (probably other versions as well, need to figure these out eventually.)
			global_props = OrderedDict([
				("ProjectGuid", project_guid),
				#("Keyword", "Win32Proj"),
				("RootNamespace", context.product.name)
			])

			# Starting with Visual Studio 2017, there's a new key, WindowsTargetPlatformVersion
			if self.latest_kit_version is not None:
				# prefer the latest Windows Kit version, if we found one.
				global_props['WindowsTargetPlatformVersion'] = self.latest_kit_version
			elif settings.get('WindowsTargetPlatformVersion') is not None:
				# As a fallback, use the value we were specifying in the config.
				global_props['WindowsTargetPlatformVersion'] = '10.0.17134.0'

			global_property_group = PropertyGroup(settings, {"Label" : "Globals"}, text_nodes=global_props)
			project.node.appendChild(global_property_group.node)

			#
			# Import default project properties
			#
			default_properties_import = Import(settings, OrderedDict([
				("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props")
				]))
			project.add(default_properties_import)

			#
			# Configuration property groups
			#

			add_project_groups(settings, project, context, architectures, configurations)

			#
			# Import Cpp props
			#
			cpp_props_import = Import(settings, {
					"Project": "$(VCTargetsPath)\\Microsoft.Cpp.props"
				})
			project.add(cpp_props_import)

			#
			# Extension Settings import group
			#
			extension_settings = ImportGroup(settings, {"Label" : "ExtensionSettings"})
			project.add(extension_settings)

			#
			# Property Sheets import group for each configuration
			#
			add_configuration_property_sheets(settings, project, context.product, architectures, configurations)


			#
			# UserMacros property group
			#
			user_macros_group = PropertyGroup(settings, OrderedDict([
				("Label", "UserMacros")
				]))
			project.add(user_macros_group)

			#
			# PropertyGroups for each configuration
			#
			add_configuration_linker_properties(settings, project, context, architectures, configurations)

			#
			# ItemDefinitionGroups for each platform
			#
			add_configuration_definition_groups(settings, self.driver_schema, project, context, architectures, configurations)

			#
			# ItemGroup for files
			#
			# <ItemGroup>
			#   <ClCompile Include="..\src\common.c" />
			# ...
			# ...
			#   <ClInclude Include="..\include\common.h" />


			# this doesn't work as-is. It adds duplicates to the list, unfortunately.
			# source_group = ItemGroup(settings, {})
			# for architecture in architectures:
			# 	for configuration in configurations:
			# 		params = context.get_layout(architecture=architecture, configuration=configuration)

			# 		sources = make_paths_relative_to_project(context, params.sources)

			# 		for path in sources:
			# 			#logging.info("source: %s" % path)
			# 			# make path relative to project
			# 			source_group.add(ClCompile(settings, {"Include": path}))
			#			project.add(source_group)
			#	 		break

			source_group = ItemGroup(settings, {})
			include_group = ItemGroup(settings, {})
			params = context.get_layout(architecture=architectures[0], configuration=configurations[0])

			params.sources = make_paths_relative_to_project(context, params.sources)

			self.add_compiled_sources(settings, params.sources, source_group, include_group)
			project.add(source_group)
			project.add(include_group)

			"""
			source_group = ItemGroup(settings, {})
			sources = []
			for path in sources:
				compile_source = ClCompile(settings, {"Include": path})
				source_group.add(compile_source)

			project.add(source_group)

			includes_group = ItemGroup(settings, {})
			includes = []
			for path in includes:
				include = ClInclude(settings, {"Include": path})
				includes_group.add(include)
			project.add(includes_group)
			"""

			#
			# Project targets import
			#
			target_import = Import(settings, {"Project": "$(VCTargetsPath)\\Microsoft.cpp.targets"})
			project.add(target_import)

			#
			# Import Group for extension targets
			#
			extension_targets_import = ImportGroup(settings, {"Label" : "ExtensionTargets"})
			project.add(extension_targets_import)

			writer.get_file().write(settings.document.toprettyxml(indent=INDENT, encoding="utf-8"))
			writer.close()

			#
			# write project filters
			filter_list = self.collect_filters(params.sources)
			if filter_list:
				full_filters_path = os.path.join(context.abs_project_root, ("%s.vcxproj.filters" % context.product.name))
				filter_file_handle = filemanager.create(full_filters_path)
				filter_writer = FileWriter(filter_file_handle)

				document = Document()
				settings = VSSettings(
					document=document,
					version=self.requested_version,
					settings=self.driver_schema
				)

				properties = {
					"ToolsVersion": "4.0",
					# this resource was moved by microsoft; but is required for VS to load the project.
					"xmlns": "http://schemas.microsoft.com/developer/msbuild/2003"
				}
				project = Project(settings, properties)
				document.appendChild(project.node)

				source_group = ItemGroup(settings, {})
				include_group = ItemGroup(settings, {})

				self.add_compiled_sources(settings, params.sources, source_group, include_group, filters=True)
				project.add(source_group)
				project.add(include_group)

				filter_group = ItemGroup(settings, {})

				# generate uuids for each filter.
				for filter_name in filter_list:
					filter_guid = "{%s}" % str(uuid.uuid4()).upper()
					filter_props = {
						"Include": filter_name
					}
					filter_id = {
						"UniqueIdentifier": filter_guid
					}
					filter_node = Filter(settings, filter_props, filter_id)
					filter_group.add(filter_node)

				project.add(filter_group)

				filter_writer.get_file().write(settings.document.toprettyxml(indent=INDENT, encoding="utf-8"))
				filter_writer.close()

		self.generate_solution(**kwargs)