def prebuild_commands_for_dependency(self, architecture, configuration, target_platform, product_context, dependency_context): prebuild_commands = [] dc = VariableContext() dc.inherit(dependency_context) dc.update(architecture="${CURRENT_ARCH}") dc.dependency_product_root = dependency_context.get("abs_product_root", expand=False) tc = VariableContext() tc.inherit(product_context) tc.update(architecture="${CURRENT_ARCH}") tc.toplevel_product_root = product_context.get("abs_product_root", expand=False) dependency_path = os.path.join(dc.dependency_product_root, target_platform.get_full_product_path(dependency_context.product)) #logging.info("dependency_path = %s" % dependency_path) output_root = os.path.dirname(os.path.join(tc.toplevel_product_root, target_platform.get_full_product_path(product_context.product))) #logging.info("output_root = %s" % output_root) product = dependency_context.product if product.output == ProductType.DynamicLibrary: # 1. Must copy the dylib to application's bundle path # 2. Must run install_name_tool to fix rpath frameworks_path = Path.absolute(os.path.join(output_root, os.path.pardir, "Frameworks")) #logging.info("frameworks_path = %s" % frameworks_path) # Assume this was already created. md = Makedirs(path=frameworks_path) prebuild_commands.append(md.commandline()) # copy the dynamic library to the Frameworks path for the toplevel product. cp = Copy(src=dependency_path, dst=frameworks_path) prebuild_commands.append(cp.commandline()) dependency_basename = os.path.basename(dependency_path) new_output_path = os.path.join(frameworks_path, dependency_basename) #logging.info("new_output_path: %s" % new_output_path) #else: # logging.info("Unknown product: %s, %s" % (product.output, product.name)) #logging.info("COMMANDS: ") #logging.info("\n".join(prebuild_commands)) return prebuild_commands
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) # TODO@apetrone: Should be able to pass the language type to # target_platform.compiler.get_command(). # base variables base_variables = { "CC" : target_platform.compiler.get_command(), "CXX" : "g++", "RM" : "rm -rf", "AR": "ar", "LD": "ld", "MAKE": "make", "MKDIR" : "mkdir -p" } for context in context_list: # fetch architecture and configurations architectures, configurations = buildfile.get_layout_params(context.product) makefile_parameters = get_parameters(architectures, configurations) arch_eq = MakefileIfEq(condition="$(arch),%s" % architectures[0], ifeq=["TARGET_ARCH = %s" % self.arch_to_flag(architectures[0])]) makefile_parameters.append(arch_eq) product_make = makefile_name_from_product(context.product) product_makefile_path = os.path.join(context.abs_project_root, product_make) handle = filemanager.create(product_makefile_path) writer = FileWriter(handle) product_name = context.product.name output = context.product.get("output") main_params = context.params_list[0] for configuration in configurations: product = context.get_layout(architectures[0], configuration) arch = VariableContext() arch.inherit(product) arch.update(architecture="${arch}", configuration="${config}") arch.object_root = product.get("object_root", expand=False) variables = deepcopy(base_variables) """ driver_data = product.driver for k,v in driver_data.iteritems(): if v: if type(v) is list: variables[k].extend(v) elif type(v) is dict: variables[k].update(v) elif type(v) is str or type(v) is unicode: variables[k] = v """ cppflags = self.driver_schema["cppflags"][:] cppflags.append("$(TARGET_ARCH)") cppflags.extend(product.cflags[:]) lower_cppflags = [flag.lower() for flag in cppflags] cxxflags = self.driver_schema["cxxflags"][:] cxxflags.append("$(CPPFLAGS)") cxxflags.extend(product.cxxflags[:]) ldflags = self.driver_schema["ldflags"][:] ldflags.append("$(TARGET_ARCH)") ldflags.extend(product.linkflags[:]) lower_ldflags = [flag.lower() for flag in ldflags] if output == ProductType.DynamicLibrary: if "-fpic" not in lower_cppflags: cppflags.append("-fPIC") if "-fpic" not in lower_ldflags: ldflags.append("-fPIC") if "-shared" not in lower_ldflags: ldflags.append("-shared") if product.defines: for flag in product.defines: cppflags.append("-D%s" % flag) includes = make_paths_relative_to_project(context, product.includes) for path in includes: cppflags.append("-I%s" % path) if product.libdirs: for path in product.libdirs: ldflags.append("-L%s" % path) links = product.links if product.links else [] ldflags.extend(links) values = [] for key,value in variables.iteritems(): values.append("%s = %s" % (key, value)) products_path = arch.abs_product_root or " " if arch.abs_product_root: products_path = ("%s/" % arch.abs_product_root) values.append("BINDIR = %s" % products_path) objdir = "${ROOT_PATH}/%s" % (arch.object_root) values.append("OBJDIR = %s" % objdir) values.append("TARGET = $(BINDIR)%s" % (target_platform.get_full_product_name(context.product))) values.append("CPPFLAGS = %s" % (" ".join(cppflags))) values.append("CXXFLAGS = %s" % (" ".join(cxxflags))) values.append("LDFLAGS = %s" % (" ".join(ldflags))) layout_condition = MakefileIfEq(condition="$(config),%s" % configuration, ifeq=values) makefile_parameters.append(layout_condition) # # Write the header of the Makefile makefile_write_header(writer) # discard all built-in make targets. writer.writeln(".SUFFIXES:") writer.writeln() # write out variables for parameter in makefile_parameters: parameter.write(writer) # write out phony targets writer.writeln(".PHONY: all clean help") writer.writeln() writer.writeln("ROOT_PATH=%s" % context.abs_root) writer.writeln() objects = MakefileArrayList(varname="OBJECTS") objdir_rules = [ "@echo Creating $(OBJDIR)", "$(SILENT) $(MKDIR) $(OBJDIR)" ] vpaths = MakefileArrayList(varname="VPATH") # organize sources into vobjects and objects. self.organize_sources(main_params.sources, context, vpaths, objects) vpaths.write(writer) writer.writeln() objects.write(writer) writer.writeln() writer.writeln("DEPENDS = $(OBJECTS:.o=.d)") writer.writeln() bindir = MakefileTarget(pattern="$(BINDIR)", rules=[ "@echo Creating $(BINDIR)", "$(SILENT) $(MKDIR) $(BINDIR)" ]) objdir = MakefileTarget(pattern="$(OBJDIR)", rules=objdir_rules) # prefix the commands with $(SILENT) -- the user probably doesn't want # to see these being executed. prebuild_commands = ["$(SILENT) %s" % x for x in product.prebuild_commands] postbuild_commands = ["$(SILENT) %s" % x for x in product.postbuild_commands] prebuild = MakefileTarget(name="prebuild", rules=prebuild_commands) if prebuild_commands else None postbuild = MakefileTarget(name="postbuild", rules=postbuild_commands) if postbuild_commands else None help = MakefileTarget(name="help", rules=[ "@echo Building project $(arch) - $(config)" ]) # get the appropriate linker linker = self.__class__.language_to_linker[product.determine_language()] # list of linkable products. linked_products = [ProductType.Application, ProductType.Commandline, ProductType.DynamicLibrary] if product.context.product.output in linked_products: target0 = MakefileTarget(pattern="$(TARGET)", rules=[ "@echo Linking %s" % product_name, "$(SILENT) $(%s) -o $(TARGET) $(OBJECTS) $(LDFLAGS)" % linker ], dependencies=[ objects ]) elif product.context.product.output == ProductType.StaticLibrary: # "r": replace or insert files into the archive # "s": act as ranlib; i.e. generate an archive index # "c": don't warn if the library had to be created # "v": verbose flags = ["r", "s", "c"] verbose = False if verbose: flags.append("v") target0 = MakefileTarget(pattern="$(TARGET)", rules=[ "@echo Creating Static Library for: %s..." % product_name, "$(SILENT) $(AR) %s $(TARGET) $(OBJECTS)" % ("".join(flags)) ], dependencies=[objects]) else: raise Exception("Unknown or unsupported ProductType: %s for product: %s" % (product.context.product.output, product.context.product.name)) c_file = MakefileTarget(pattern="%.c", rules=[]) compiling_rule = "@echo Compiling \"$<\" ..." c_target = MakefileTarget(pattern="$(OBJDIR)/%.o", rules=[ compiling_rule, "$(SILENT) $(CC) $(CPPFLAGS) -o \"$@\" -c \"$<\"" ], dependencies=[ c_file ]) cc_file = MakefileTarget(pattern="%.cc", rules=[]) cc_target = MakefileTarget(pattern="$(OBJDIR)/%.o", rules=[ compiling_rule, "$(SILENT) $(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"" ], dependencies=[ cc_file ]) cpp_file = MakefileTarget(pattern="%.cpp", rules=[]) cpp_target = MakefileTarget(pattern="$(OBJDIR)/%.o", rules=[ compiling_rule, "$(SILENT) $(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"" ], dependencies=[ cpp_file ]) # Here we construct the all_deps dynamically # because we want to omit the prebuild targets if they don't # contribute anything. all_deps = [bindir, objdir] if prebuild: all_deps.append(prebuild) all_deps.append(target0) if postbuild: all_deps.append(postbuild) all_target = MakefileTarget(name="all", rules=[ "@:", "@echo Done.", ], dependencies=all_deps) clean_target = MakefileTarget(name="clean", rules=[ "$(SILENT) $(RM) $(TARGET)", "$(SILENT) $(RM) $(OBJECTS)", "$(SILENT) $(RM) $(DEPENDS)" ]) new_targets = [all_target, help] if prebuild: new_targets.append(prebuild) if postbuild: new_targets.append(postbuild) new_targets.extend([target0, objdir, bindir, c_target, cc_target, cpp_target, clean_target]) # add targets for each target in our pegasus script for target in new_targets: target.write(writer) writer.writeln("-include $(DEPENDS)") writer.close() self.write_makefile(**kwargs) return None
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)
def prebuild_commands_for_dependency(self, architecture, configuration, target_platform, product_context, dependency_context): prebuild_commands = [] dc = VariableContext() dc.inherit(dependency_context) dc.update(architecture="${arch}", configuration="${config}") dc.dependency_product_root = dependency_context.get("abs_product_root", expand=False) tc = VariableContext() tc.inherit(product_context) tc.update(architecture="${arch}", configuration="${config}") tc.toplevel_product_root = product_context.get("abs_product_root", expand=False) dependency_path = os.path.join(dc.dependency_product_root, target_platform.get_full_product_path(dependency_context.product)) output_root = os.path.dirname(os.path.join(tc.toplevel_product_root, target_platform.get_full_product_path(product_context.product))) expected_types = [ProductType.Application, ProductType.Commandline, ProductType.DynamicLibrary] if dependency_context.product.output == ProductType.DynamicLibrary \ and (product_context.product.output in expected_types): # Copy the .so to top-level Application's product_root. cp = Copy(src=dependency_path, dst=output_root) prebuild_commands.append(cp.commandline()) elif dependency_context.product.output == ProductType.StaticLibrary: pass elif dependency_context.product.output == ProductType.DynamicLibrary \ and (product_context.product.output == ProductType.StaticLibrary): pass else: raise Exception("GNUMake: prebuild_commands_for_dependency\ I'm not sure what to do here.\ type is: %s" % product_context.product.output) return prebuild_commands