Beispiel #1
0
	def write_makefile(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)

		# In post generate, we create a top level "Makefile", which contains targets for each of
		# the sub make files -- which is what "generate" does for each product.

		# The top-level Makefile can be used to make each product:
		# e.g. make squirrel


		context = context_list[0]
		product = context.product

		root = context.abs_root

		#
		# Preprocess step to create data for each product
		#

		# create a list of obj dirs
		objdirs = []

		# create a list of lib/bin dirs.
		bindirs = []

		# create a list of targets.
		targets = []

		# product names which can be used manually on the commandline
		product_names = []

		architectures, configurations = buildfile.get_layout_params(product)
		makefile_parameters = get_parameters(architectures, configurations)

		phony_targets = [
			"all",
			"clean"
		]

		target_clean_rules = []
		for context in context_list:
			mk = VariableContext()
			mk.inherit(context)
			mk.product_root = context.get("product_root", expand=False)
			mk.object_root = context.get("object_root", expand=False)
			mk.update(architecture="${arch}", configuration="${config}")

			if mk.object_root not in objdirs:
				objdirs.append(mk.object_root)

			if mk.product_root not in bindirs:
				bindirs.append(mk.product_root)

			# add product name
			product_names.append(context.product.name)

			# convert the dependencies for this product into a list
			# of MakefileTargets
			dependencies = []
			for instance in context.ordered_dependencies:
				dependencies.append(MakefileArrayList(name=instance.name))

			# setup targets
			makefile_path = makefile_name_from_product(context.product)
			target = MakefileTarget(name=context.product.name,
				rules=[
					"$(SILENT) $(MAKE) --no-print-directory -C %s -f %s" % (context.base_to_project_relative, makefile_path)
				],
				dependencies = dependencies)


			clean_rule = "$(SILENT) $(MAKE) --no-print-directory -C %s -f %s clean" % (context.base_to_project_relative, makefile_path)
			target_clean_rules.append(clean_rule)

			targets.append(target)

		# variables the makefile accepts as parameters.
		variables = ["arch", "config", "verbose"]

		# script variables
		script_vars = {
			"objdir" : objdirs,
			"bindir" : bindirs,
			"targets" : [t.get_output_name() for t in targets]
		}


		clean = MakefileTarget(name="clean", rules=target_clean_rules)

		#
		# Write out the actual Makefile with data from above.
		#
		makefile_path = os.path.join(root, "Makefile")
		handle = filemanager.create(makefile_path)
		writer = FileWriter(handle)

		#
		# Write the header of the Makefile
		makefile_write_header(writer)

		#
		# export all variables
		#
		for parameter in makefile_parameters:
			parameter.write(writer)

		# setup variables used by this script
		for key, value in script_vars.iteritems():
			writer.writeln("%s=%s" % (key.upper(), " ".join(value)))
		writer.writeln()

		phony_targets.extend(product_names)

		# write phony and all targets
		writer.writeln(".PHONY: %s" % " ".join(phony_targets))
		writer.writeln()

		writer.writeln("all: %s" % " ".join(product_names))
		writer.writeln()

		# write actual targets, which call the product's own makefile
		for t in targets:
			t.write(writer)

		# write clean target
		clean.write(writer)