/// <summary> /// Parse the package model parameters and generate VS projects. /// 1. Parse -a value /// 2. Parse the DSC file to get all the related INF files. The related INF files are ONLY those in the DSC file folder or sub folders. aka. {PkgName}\/.*\.inf /// Note that duplicated INF files should be removed. /// 3. For each INF file obtained from step 2, do: /// Parse the [Packages] section to locate the Include paths based on the -a value. /// Create an empty solution in a well-known location Workspace\VS2013\PkgName. http://stackoverflow.com/questions/8790528/create-a-visual-studio-project-programmatically /// Create an empty VC project for the INF. /// Configure the VC project's C/C++ Include path. /// Recursively use "add existing item" to add all files in [Sources] section of INF file into the VS project. /// </summary> /// <param name="pkgDataModel"></param> public void ImportPackage(PkgDataModel pkgDataModel) { String vs2013PkgSolutionFolderName = String.Join("_", pkgDataModel.PkgName, pkgDataModel.DscFileName, pkgDataModel.Arch); String vs2013PkgSoutionFolderFullPath = Path.Combine(pkgDataModel.Workspace, "VS2013", vs2013PkgSolutionFolderName); if (!Directory.Exists(vs2013PkgSoutionFolderFullPath)) { Directory.CreateDirectory(vs2013PkgSoutionFolderFullPath); } this.pkgDataModel = pkgDataModel; var infs = LocateINFsInDSC(); StringBuilder sourcesSectionContentBuilder = new StringBuilder(); StringBuilder fileListBuilder = new StringBuilder(); StringBuilder vcxprojFileBuilder = new StringBuilder(); StringBuilder solutionFileBuilder = new StringBuilder(); StringBuilder solutionProjectPart1 = new StringBuilder(); StringBuilder solutionProjectPart2 = new StringBuilder(); StringBuilder solutionProjectPart1Collection = new StringBuilder(); StringBuilder solutionProjectPart2Collection = new StringBuilder(); // one INF, one project foreach (var inf in infs) { //To make the project name more user friendly, let's reverse the string order. String projName = String.Join("_", inf.Split(pathSeperatorInINF).Reverse().ToArray()); //inf.Substring(inf.LastIndexOf(pathSeperatorInINF) + 1, inf.LastIndexOf('.') - inf.LastIndexOf(pathSeperatorInINF) - 1); vcxprojFileBuilder.Clear(); vcxprojFileBuilder.Append(Resources.VCXPROJTemplate); String infFolderFullPath = Path.Combine(pkgDataModel.Workspace, inf.Substring(0, inf.LastIndexOf(pathSeperatorInINF))).Replace(pathSeperatorInINF, pathSeperatorWindows); String infFullPath = Path.Combine(pkgDataModel.Workspace, inf).Replace(pathSeperatorInINF, pathSeperatorWindows); String infFileContent = File.ReadAllText(infFullPath).ToLower(); //Detect source files in INF [Sources], [Sources.common], [Sources.ARCH] section. Only need to cover .c, .h. Other files has no cross reference. Such as: X86MemoryFence.c | MSFT sourcesSectionContentBuilder.Clear(); sourcesSectionContentBuilder.AppendLine(GetSectionContentFromSingleINF("[sources]", infFileContent)); sourcesSectionContentBuilder.AppendLine(GetSectionContentFromSingleINF("[sources.common]", infFileContent)); sourcesSectionContentBuilder.AppendLine(GetSectionContentFromSingleINF("[sources." + pkgDataModel.Arch + "]", infFileContent)); //.c GetFileListFromSingleINF(fileListBuilder, @".*\.c", infFolderFullPath, sourcesSectionContentBuilder.ToString(), Resources.CFileTemplate, @"__SM_C_FILE__"); vcxprojFileBuilder.Replace("__SM_C_FILES__", fileListBuilder.ToString()); //.h GetFileListFromSingleINF(fileListBuilder, @".*\.h", infFolderFullPath, sourcesSectionContentBuilder.ToString(), Resources.HFileTemplate, @"__SM_H_FILE__"); vcxprojFileBuilder.Replace("__SM_H_FILES__", fileListBuilder.ToString()); //Fill in the project GUID and project name. String projGUID = Guid.NewGuid().ToString(); vcxprojFileBuilder.Replace("__SM_PROJECT_GUID__", projGUID); vcxprojFileBuilder.Replace("__SM_PROJECT_ROOTNS__", projName); //Detect include paths var includePaths4SingleINF = DetectIncluePaths4SingleINF(inf); String additionalIncludePaths = String.Concat(includePaths4SingleINF); vcxprojFileBuilder.Replace("__SM_ADDITIONAL_INCLUDE_DIRS_DEBUG__", additionalIncludePaths); vcxprojFileBuilder.Replace("__SM_ADDITIONAL_INCLUDE_DIRS_RELEASE__", additionalIncludePaths); //Output vcxproj file. String vcxprojFileFolder = Path.Combine(vs2013PkgSoutionFolderFullPath, "Modules"); if (!Directory.Exists(vcxprojFileFolder)) { Directory.CreateDirectory(vcxprojFileFolder); } String vcxprojFileFullPath = Path.Combine(vcxprojFileFolder, projName + ".vcxproj"); File.WriteAllText(vcxprojFileFullPath, vcxprojFileBuilder.ToString()); solutionProjectPart1.Clear(); solutionProjectPart1.Append(Resources.SolutionTemplateProjectPart1); solutionProjectPart1.Replace("__SM_PROJECT_NAME__", projName); solutionProjectPart1.Replace("__SM_PROJECT_FILE_PATH__", vcxprojFileFullPath); solutionProjectPart1.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart1Collection.AppendLine(solutionProjectPart1.ToString()); solutionProjectPart2.Clear(); solutionProjectPart2.Append(Resources.SolutionTemplateProjectPart2); solutionProjectPart2.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart2Collection.AppendLine(solutionProjectPart2.ToString()); } solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart1); solutionFileBuilder.AppendLine(solutionProjectPart1Collection.ToString()); solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart2); solutionFileBuilder.AppendLine(solutionProjectPart2Collection.ToString()); solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart3); //Output .sln file. String ws = pkgDataModel.Workspace; String slnFileName = pkgDataModel.PkgName + ".sln"; String slnFileFullPath = Path.Combine(vs2013PkgSoutionFolderFullPath, slnFileName); File.WriteAllText(slnFileFullPath, solutionFileBuilder.ToString()); MessageBox.Show(@"Done!"); }
public void ImportPackage(PkgDataModel pkgDataModel) { this.pkgDataModel = pkgDataModel; String vs2013PkgSolutionFolderName = String.Join("_", pkgDataModel.PkgName, pkgDataModel.DscFileName, pkgDataModel.Arch); String vs2013PkgSoutionFolderFullPath = Path.Combine(pkgDataModel.Workspace, "VS2013", vs2013PkgSolutionFolderName); if (!Directory.Exists(vs2013PkgSoutionFolderFullPath)) { Directory.CreateDirectory(vs2013PkgSoutionFolderFullPath); } var infs = GetInfsLocatedWithinASinglePkgFromDscFileComponentsSection(); StringBuilder sourcesSectionContentBuilder = new StringBuilder(); StringBuilder fileListBuilder = new StringBuilder(); StringBuilder vcxprojFileBuilder = new StringBuilder(); StringBuilder solutionFileBuilder = new StringBuilder(); StringBuilder solutionProjectPart1 = new StringBuilder(); StringBuilder solutionProjectPart2 = new StringBuilder(); StringBuilder solutionProjectPart1Collection = new StringBuilder(); StringBuilder solutionProjectPart2Collection = new StringBuilder(); StringBuilder moduleBuildBatch = new StringBuilder(); // one INF, one project foreach (var inf in infs) { //To make the project name more user friendly, let's reverse the string order. String projName = String.Join("_", inf.Split(pathSeperatorInINF).Reverse().ToArray()); //inf.Substring(inf.LastIndexOf(pathSeperatorInINF) + 1, inf.LastIndexOf('.') - inf.LastIndexOf(pathSeperatorInINF) - 1); vcxprojFileBuilder.Clear(); vcxprojFileBuilder.Append(Resources.VCXPROJTemplate); String infFolderFullPath = Path.Combine(pkgDataModel.Workspace, inf.Substring(0, inf.LastIndexOf(pathSeperatorInINF))).Replace(pathSeperatorInINF, pathSeperatorWindows); String infFolderRelative2Workspace = inf.Substring(0, inf.LastIndexOf(pathSeperatorInINF)); String infFullPath = Path.Combine(pkgDataModel.Workspace, inf).Replace(pathSeperatorInINF, pathSeperatorWindows); String infBaseName = GetDefinesValue("BASE_NAME",infFullPath); String infFileName = inf.Substring(inf.LastIndexOf(pathSeperatorInINF) + 1, inf.LastIndexOf(".inf") - inf.LastIndexOf(pathSeperatorInINF) - 1); //String infFileContent = File.ReadAllText(infFullPath).ToLower(); //Detect source files in INF [Sources], [Sources.common], [Sources.ARCH] section. Only need to cover .c, .h. Such as: X86MemoryFence.c | MSFT. Other files have no cross reference. sourcesSectionContentBuilder.Clear(); var sourcesSectionContentInLines = GetSourcesSectionContentFromSingleINFFile(infFullPath); //.c GetFileListFromSingleINF(fileListBuilder, "c", infFolderFullPath, sourcesSectionContentInLines, Resources.CFileTemplate, @"__SM_C_FILE__"); vcxprojFileBuilder.Replace("__SM_C_FILES__", fileListBuilder.ToString()); //.h GetFileListFromSingleINF(fileListBuilder, "h", infFolderFullPath, sourcesSectionContentInLines, Resources.HFileTemplate, @"__SM_H_FILE__"); vcxprojFileBuilder.Replace("__SM_H_FILES__", fileListBuilder.ToString()); //.inf vcxprojFileBuilder.Replace("__SM_INF_FILE__", infFullPath); //Fill in the project GUID and project name. String projGUID = Guid.NewGuid().ToString().ToUpper(); vcxprojFileBuilder.Replace("__SM_PROJECT_GUID__", projGUID); vcxprojFileBuilder.Replace("__SM_PROJECT_ROOTNS__", projName); //Detect include paths var includePaths4SingleINF = DetectIncluePaths4SingleINF(infFolderFullPath, infFullPath); String additionalIncludePaths = String.Join(";", includePaths4SingleINF); vcxprojFileBuilder.Replace("__SM_ADDITIONAL_INCLUDE_DIRS__", additionalIncludePaths); //Add "additional options" for /FIAutoGen.h and /FI(ModuleName)StrDefs.h (Refer to the tools_def.txt) String additionalOptions = GetAdditionalOptions(sourcesSectionContentInLines, infFileName, infFolderRelative2Workspace); vcxprojFileBuilder.Replace("__SM_ADDITIONAL_OPTIONS__", additionalOptions); //Output vcxproj file. String vcxprojFileFolder = Path.Combine(vs2013PkgSoutionFolderFullPath, "Modules"); if (!Directory.Exists(vcxprojFileFolder)) { Directory.CreateDirectory(vcxprojFileFolder); } String vcxprojFileName = projName + ".vcxproj"; String vcxprojFileFullPath = Path.Combine(vcxprojFileFolder, vcxprojFileName); File.WriteAllText(vcxprojFileFullPath, vcxprojFileBuilder.ToString()); String vcxprojFileRelativePath = @".\Modules\" + vcxprojFileName; solutionProjectPart1.Clear(); solutionProjectPart1.Append(Resources.SolutionTemplateProjectPart1); solutionProjectPart1.Replace("__SM_PROJECT_NAME__", projName); solutionProjectPart1.Replace("__SM_PROJECT_FILE_PATH__", vcxprojFileRelativePath); solutionProjectPart1.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart1Collection.AppendLine(solutionProjectPart1.ToString()); solutionProjectPart2.Clear(); solutionProjectPart2.Append(Resources.SolutionTemplateProjectPart2); solutionProjectPart2.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart2Collection.AppendLine(solutionProjectPart2.ToString()); //Generate build batch for each module INF moduleBuildBatch.Clear(); moduleBuildBatch.Append(Resources.EDKIIModuleBuildBatch); String vsCommonToolsDir = Environment.GetEnvironmentVariable("VS120COMNTOOLS"); if (vsCommonToolsDir.Length <= 0) throw new Exception("Please install Visual Studio 2013 first!"); moduleBuildBatch.Replace("__SM_ARCH__", pkgDataModel.Arch); moduleBuildBatch.Replace("__SM_DSC_FILE_FULLPATH__", pkgDataModel.DscFileFullPath); moduleBuildBatch.Replace("__SM_TOOLCHAIN__", pkgDataModel.Toolchain); moduleBuildBatch.Replace("__SM_VS_COMMON_TOOLS_DIR__", vsCommonToolsDir); String moduleBuildBatchFullpath = Path.Combine(vcxprojFileFolder, "BuildModule.bat"); File.WriteAllText(moduleBuildBatchFullpath, moduleBuildBatch.ToString()); } //Generate a dummy .vcxproj for pacakge build { String dummyPackageBuildProjName = "BuildPackageDummyProject"; String dummyPackageBuildProjRelativePath = @".\Modules\" + dummyPackageBuildProjName + ".vcxproj"; String dummyPackageBuildProjFullPath = Path.Combine(vs2013PkgSoutionFolderFullPath, "Modules", dummyPackageBuildProjName + ".vcxproj"); String projGUID = Guid.NewGuid().ToString().ToUpper(); vcxprojFileBuilder.Clear(); vcxprojFileBuilder.Append(Resources.VCXPROJTemplateForPkgBuildProject); vcxprojFileBuilder.Replace("__SM_BUILD_PACKAGE_BAT_FILE__", @".\BuildPackage.bat"); vcxprojFileBuilder.Replace("__SM_PROJECT_GUID__", projGUID); vcxprojFileBuilder.Replace("__SM_PROJECT_ROOTNS__", dummyPackageBuildProjName); File.WriteAllText(dummyPackageBuildProjFullPath, vcxprojFileBuilder.ToString()); solutionProjectPart1.Clear(); solutionProjectPart1.Append(Resources.SolutionTemplateProjectPart1); solutionProjectPart1.Replace("__SM_PROJECT_NAME__", dummyPackageBuildProjName); solutionProjectPart1.Replace("__SM_PROJECT_FILE_PATH__", dummyPackageBuildProjRelativePath); solutionProjectPart1.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart1Collection.AppendLine(solutionProjectPart1.ToString()); solutionProjectPart2.Clear(); solutionProjectPart2.Append(Resources.SolutionTemplateProjectPart2); solutionProjectPart2.Replace("__SM_PROJECT_GUID__", projGUID); solutionProjectPart2Collection.AppendLine(solutionProjectPart2.ToString()); //Generate package build batch for the dummy project moduleBuildBatch.Clear(); //just reuse the moduleBuildBatch string builder. moduleBuildBatch.Append(Resources.EDKIIPackageBuildBatch); String vsCommonToolsDir = Environment.GetEnvironmentVariable("VS120COMNTOOLS"); if (vsCommonToolsDir.Length <= 0) throw new Exception("Please install Visual Studio 2013 first!"); moduleBuildBatch.Replace("__SM_ARCH__", pkgDataModel.Arch); moduleBuildBatch.Replace("__SM_DSC_FILE_FULLPATH__", pkgDataModel.DscFileFullPath); moduleBuildBatch.Replace("__SM_TOOLCHAIN__", pkgDataModel.Toolchain); moduleBuildBatch.Replace("__SM_VS_COMMON_TOOLS_DIR__", vsCommonToolsDir); String packageBuildBatchFullpath = Path.Combine(vs2013PkgSoutionFolderFullPath, "Modules", "BuildPackage.bat"); File.WriteAllText(packageBuildBatchFullpath, moduleBuildBatch.ToString()); } StringBuilder solutionItemsFolderBuilder = new StringBuilder(); solutionItemsFolderBuilder.Clear(); solutionItemsFolderBuilder.AppendLine(Resources.SolutionTemplateSolutionItemsFolderPart); //solution items: dsc and dec solutionItemsFolderBuilder.Replace("__SM_DSC_FILE__", String.Format("{0}={0}", pkgDataModel.DscFileFullPath)); solutionItemsFolderBuilder.Replace("__SM_DEC_FILES__", GetDECFiles()); solutionItemsFolderBuilder.Replace("__SM_SOLUTION_ITEMS_GUID__", Guid.NewGuid().ToString().ToUpper()); solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart1); solutionFileBuilder.AppendLine(solutionProjectPart1Collection.ToString()); solutionFileBuilder.AppendLine(solutionItemsFolderBuilder.ToString()); solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart2); solutionFileBuilder.AppendLine(solutionProjectPart2Collection.ToString()); solutionFileBuilder.AppendLine(Resources.SolutionTemplateFixedPart3); //Output .sln file. String ws = pkgDataModel.Workspace; String slnFileName = pkgDataModel.PkgName + ".sln"; String slnFileFullPath = Path.Combine(vs2013PkgSoutionFolderFullPath, slnFileName); File.WriteAllText(slnFileFullPath, solutionFileBuilder.ToString()); MessageBox.Show(@"Solution and projects files created successfully!"); }
public MyControl() { InitializeComponent(); pkgDataModel = new PkgDataModel(); }