/* * Input: A Component, and a CustomInstruction that needs to be attached to this Component. * Output: True if the instruction was identified and we attempted to take action, False if we do not know how to carry out the merge. * */ public static bool MergeInstructionWithComponent(Component cp, CustomInstruction cinstr, Makefile mkfile) { if (cinstr.isCl()) { ClInstruction clInstr = (ClInstruction)cinstr; string target = ""; foreach (string clFile in clInstr.clFiles) { if (clFile.EndsWith(".c", StringComparison.CurrentCultureIgnoreCase) || clFile.EndsWith(".cpp", StringComparison.CurrentCultureIgnoreCase)) { cp.SourceFiles.Add(Path.GetFileNameWithoutExtension(clFile)); } if (clFile.Contains(".obj")) target = clFile; } foreach (string clLib in clInstr.clLibs) { cp.Link.Libs.Add(clLib); } if (cp.CompilerFlags == null) cp.CompilerFlags = new CompileFlags(mkfile); cp.CompilerFlags.ParseString(clInstr.clOptionsLiteral); foreach (string linkOption in clInstr.linkerOptions) { cp.Link.Options.Add(new KeyValuePair<string, string>(target, linkOption)); } mkfile.GenerateSourceFileNames(cp); return true; } else if (cinstr.isRc()) { RcInstruction rcInstr = (RcInstruction)cinstr; cp.SourceFiles.Add(rcInstr.rcScript); RcFlags rcFlags = new RcFlags(mkfile); rcFlags.ParseString(rcInstr.instruction_literal); cp.CustomFlags.Add(rcInstr.rcScript, rcFlags); mkfile.GenerateSourceFileNames(cp); } else { //We cannot identify the instruction, we will assume that it must be added as a prebuild step to the component. cp.PostBuildInstructions.Add(cinstr); } return false; }
/* * Given: * A Cl (command line compile) instruction with a /link flag- a single instruction that has been parsed before, and a CustomComponent that has this compile instruction * Output: * A Component that can generate a project. * Note that we want to point to source files (.c, .h) instead of linking against things that are not in our current project. * */ public static Component resolveClInstructionIntoComponent(ClInstruction clInstruction, CustomComponent rule, Makefile mkfile) { Component result = new Component(rule.Output); result.IsCustomLinkStep = true; string target = ""; //If the compile instruction has a /link flag, then it should ultimately become its own project. if (clInstruction.hasLinkFlags()) { foreach (string file in clInstruction.clFiles) { if (file.EndsWith(".c", StringComparison.CurrentCultureIgnoreCase) || file.EndsWith(".cpp", StringComparison.CurrentCultureIgnoreCase)) { result.SourceFiles.Add(Path.GetFileNameWithoutExtension(file)); } else if (file.Contains("lib")) { result.Link.Libs.Add(file); } else if (file.Contains("obj")) { result.Link.Objs.Add(file); target = file; } } CompileFlags flags = new CompileFlags(mkfile); flags.ParseString(clInstruction.clOptionsLiteral); result.CompilerFlags = flags; if (clInstruction.LinkOptionsLiteral_Words.Count > 0) { MakefileUtil.ParseLinkFlags(mkfile, clInstruction.LinkOptionsLiteral_Words, result); } } string extension = Path.GetExtension(rule.Output).Replace(".", ""); result.Type = extension; if (result.Name == "") result.setName(rule.Output); if (result.Link.Output == "") result.Link.Output = Path.GetFileName(rule.Output); return result; }
/* * Given: * A CustomComponent that creates a .dll. This CustomComponent should have a link instruction. * Output: * A Component that can be used to generate a project for this .dll * * */ public static Component generateComponentFromRule(CustomComponent rule, Makefile mkfile) { Component result = new Component(rule.Name); result.Owner = mkfile; List<CustomInstruction> preBuildInstrs = new List<CustomInstruction>(); List<CustomInstruction> postBuildInstrs = new List<CustomInstruction>(); bool afterLinkInstruction = false; foreach (string instr in rule.CustomInstructions) { CustomInstruction cinstr = new CustomInstruction(instr); if (cinstr.isNmake()) { LinkInstruction linkInstr = new LinkInstruction(cinstr); result = resolveLinkInstruction(linkInstr,rule,mkfile); afterLinkInstruction = true; } else if (cinstr.isCl()) { ClInstruction compileInstruction = new ClInstruction(cinstr); foreach (string sourceFile in compileInstruction.clFiles) result.SourceFileNames.Add(sourceFile); } else if (!afterLinkInstruction) { preBuildInstrs.Add(cinstr); } else { postBuildInstrs.Add(cinstr); } } result.PreBuildInstructions = preBuildInstrs; result.PostBuildInstructions = postBuildInstrs; return result; }