/// <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!");
        }
Example #3
0
 public MyControl()
 {
     InitializeComponent();
     pkgDataModel = new PkgDataModel();
 }