public void CompareTo(Package actual) { Test(this.Name, actual.Name, "Package name"); Test(this.ID, actual.ID, "Package ID"); Test(this.Kind, actual.Kind, "Package kind"); Test(this.Path, actual.Path, "Package path"); Test(this.Language, actual.Language, "Package language"); Test(this.ScriptName, actual.ScriptName, "Package script name"); Test(this.Compiler, actual.Compiler, "Package compiler"); this.Config.CompareTo(actual.Config); this.File.CompareTo(actual.File); }
public void CompareTo(Package actual) { Test(this.Name, actual.Name, "Package name"); Test(this.ID, actual.ID, "Package ID"); Test(this.Kind, actual.Kind, "Package kind"); Test(this.Path, actual.Path, "Package path"); Test(this.Language, actual.Language, "Package language"); Test(this.ScriptName, actual.ScriptName, "Package script name"); Test(this.Compiler, actual.Compiler, "Package compiler"); Test(this.DefFile, actual.DefFile, "Exports .def file"); Test(this.HasAppConfigRule, actual.HasAppConfigRule, "App.config build rule"); this.Config.CompareTo(actual.Config); this.File.CompareTo(actual.File); }
public override void Parse(Project project, string filename) { /* File header */ Begin(filename + ".workspace"); Match("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"); Match("<CodeBlocks_workspace_file>"); Match("\t<Workspace title=\"" + project.Name + "\">"); Hashtable packageDependencies = new Hashtable(); while (!Match("\t</Workspace>", true)) { string[] matches = Regex("\t\t<Project filename=\"(.+?)\"(.*)>"); Package package = new Package(); project.Package.Add(package); package.Name = Path.GetFileNameWithoutExtension(matches[0]); package.Path = Path.GetDirectoryName(matches[0]); package.ScriptName = Path.GetFileName(matches[0]); ArrayList deps = new ArrayList(); while (!Match("\t\t</Project>", true)) { matches = Regex("\t\t\t<Depends filename=\"(.+?)\" />"); deps.Add(Path.GetFileNameWithoutExtension(matches[0])); } packageDependencies.Add(package, deps.ToArray(typeof(string))); } Match("</CodeBlocks_workspace_file>"); foreach (Package package in project.Package) { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); ParseCpp(project, package, filename); foreach (Configuration cfg in package.Config) cfg.Dependencies = (string[])packageDependencies[package]; } }
private void ParseUserFile(Project project, Package package, string filename) { Begin(filename + ".user"); Match("<VisualStudioProject>"); Match("\t<CSHARP>"); Match("\t\t<Build>"); string[] matches = Regex("\t\t\t<Settings ReferencePath = \"(.+)\" >"); matches = matches[0].Split(';'); string[] libpaths = new string[matches.Length - 1]; /* VS.NET stores reference directories as absolute paths, so I need * to do some ugly trickery here */ string[] bindir = matches[matches.Length - 1].Split('\\'); for (int i = 0; i < matches.Length - 1; ++i) { string[] thisdir = matches[i].Split('\\'); int j = 0; while (j < bindir.Length && j < thisdir.Length && bindir[j] == thisdir[j]) ++j; string path = ""; for (int k = j + 1; k < bindir.Length; ++k) path += "..\\"; for (int k = j; k < thisdir.Length; ++k) path += thisdir[k] + '\\'; libpaths[i] = path.Substring(0, path.Length - 1); libpaths[i] = libpaths[i].Replace("/", "\\"); } foreach (Configuration config in package.Config) { config.LibPaths = libpaths; Match("\t\t\t\t<Config"); Match("\t\t\t\t\tName = \"" + config.Name + "\""); Match("\t\t\t\t\tEnableASPDebugging = \"false\""); Match("\t\t\t\t\tEnableASPXDebugging = \"false\""); Match("\t\t\t\t\tEnableUnmanagedDebugging = \"false\""); Match("\t\t\t\t\tEnableSQLServerDebugging = \"false\""); Match("\t\t\t\t\tRemoteDebugEnabled = \"false\""); Match("\t\t\t\t\tRemoteDebugMachine = \"\""); Match("\t\t\t\t\tStartAction = \"Project\""); Match("\t\t\t\t\tStartArguments = \"\""); Match("\t\t\t\t\tStartPage = \"\""); Match("\t\t\t\t\tStartProgram = \"\""); Match("\t\t\t\t\tStartURL = \"\""); Match("\t\t\t\t\tStartWorkingDirectory = \"\""); Match("\t\t\t\t\tStartWithIE = \"false\""); Match("\t\t\t\t/>"); } Match("\t\t\t</Settings>"); Match("\t\t</Build>"); Match("\t\t<OtherProjectSettings"); Match("\t\t\tCopyProjectDestinationFolder = \"\""); Match("\t\t\tCopyProjectUncPath = \"\""); Match("\t\t\tCopyProjectOption = \"0\""); Match("\t\t\tProjectView = \"ProjectFiles\""); Match("\t\t\tProjectTrust = \"0\""); Match("\t\t/>"); Match("\t</CSHARP>"); Match("</VisualStudioProject>"); }
private void ParseCs(Project project, Package package, string filename) { string kind = null; Begin(filename); Match("<VisualStudioProject>"); Match("\t<CSHARP"); string[] matches = Regex("\t\tProjectType = \"([A-Za-z]+)\""); if (matches[0] == "Web") kind = "aspnet"; Match("\t\tProductVersion = \"7.10.3077\""); Match("\t\tSchemaVersion = \"2.0\""); matches = Regex("\t\tProjectGuid = \"{([0-9A-F-]+)}\""); if (matches[0] != package.ID) throw new FormatException("Solution and project GUIDs don't match"); Match("\t>"); Match("\t\t<Build>"); Match("\t\t\t<Settings"); Match("\t\t\t\tApplicationIcon = \"\""); Match("\t\t\t\tAssemblyKeyContainerName = \"\""); matches = Regex("\t\t\t\tAssemblyName = \"(.+)\""); string target = matches[0]; Match("\t\t\t\tAssemblyOriginatorKeyFile = \"\""); Match("\t\t\t\tDefaultClientScript = \"JScript\""); Match("\t\t\t\tDefaultHTMLPageLayout = \"Grid\""); Match("\t\t\t\tDefaultTargetSchema = \"IE50\""); Match("\t\t\t\tDelaySign = \"false\""); matches = Regex("\t\t\t\tOutputType = \"([A-Za-z]+)\""); if (kind == null) { switch (matches[0]) { case "Exe": kind = "exe"; break; case "WinExe": kind = "winexe"; break; case "Library": kind = "dll"; break; default: throw new FormatException("Unexpected value: OutputType = \"" + matches[0] + "\""); } } else if (matches[0] != "Library") { throw new FormatException("Output type must be 'library' for ASP.NET applications"); } Match("\t\t\t\tPreBuildEvent = \"\""); Match("\t\t\t\tPostBuildEvent = \"\""); Match("\t\t\t\tRootNamespace = \"" + target + "\""); Match("\t\t\t\tRunPostBuildEvent = \"OnBuildSuccess\""); Match("\t\t\t\tStartupObject = \"\""); Match("\t\t\t>"); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); config.Target = target; Match("\t\t\t\t<Config"); Match("\t\t\t\t\tName = \"" + config.Name + "\""); matches = Regex("\t\t\t\t\tAllowUnsafeBlocks = \"(true|false)\""); if (matches[0] == "true") buildFlags.Add("unsafe"); Match("\t\t\t\t\tBaseAddress = \"285212672\""); Match("\t\t\t\t\tCheckForOverflowUnderflow = \"false\""); Match("\t\t\t\t\tConfigurationOverrideFile = \"\""); matches = Regex("\t\t\t\t\tDefineConstants = \"(.*)\""); config.Defines = matches[0].Split(';'); if (config.Defines[0] == String.Empty) config.Defines = new string[]{}; Match("\t\t\t\t\tDocumentationFile = \"\""); matches = Regex("\t\t\t\t\tDebugSymbols = \"(true|false)\""); if (matches[0] == "false") buildFlags.Add("no-symbols"); Match("\t\t\t\t\tFileAlignment = \"4096\""); Match("\t\t\t\t\tIncrementalBuild = \"false\""); Match("\t\t\t\t\tNoStdLib = \"false\""); Match("\t\t\t\t\tNoWarn = \"\""); matches = Regex("\t\t\t\t\tOptimize = \"([a-z]+)\""); if (matches[0] == "true") buildFlags.Add("optimize"); matches = Regex("\t\t\t\t\tOutputPath = \"(.+)\""); config.BinDir = matches[0]; config.OutDir = matches[0]; Match("\t\t\t\t\tRegisterForComInterop = \"false\""); Match("\t\t\t\t\tRemoveIntegerChecks = \"false\""); matches = Regex("\t\t\t\t\tTreatWarningsAsErrors = \"(true|false)\""); if (matches[0] == "true") buildFlags.Add("fatal-warnings"); Match("\t\t\t\t\tWarningLevel = \"4\""); Match("\t\t\t\t/>"); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } Match("\t\t\t</Settings>"); ArrayList links = new ArrayList(); ArrayList lddep = new ArrayList(); Match("\t\t\t<References>"); while (!Match("\t\t\t</References>", true)) { Match("\t\t\t\t<Reference"); matches = Regex("\t\t\t\t\tName = \"(.+)\""); string name = matches[0]; links.Add(name); matches = Regex("\t\t\t\t\tProject = \"(.+)\"", true); if (matches != null) { string dep = matches[0]; matches = Regex("\t\t\t\t\tPackage = \"(.+)\""); dep += matches[0]; lddep.Add(dep); } else { Match("\t\t\t\t\tAssemblyName = \"" + name + "\""); } Match("\t\t\t\t/>"); } foreach (Configuration config in package.Config) { config.Kind = kind; config.Links = (string[])links.ToArray(typeof(string)); config.LinkDeps = (string[])lddep.ToArray(typeof(string)); } Match("\t\t</Build>"); Match("\t\t<Files>"); Match("\t\t\t<Include>"); while (!Match("\t\t\t</Include>", true)) { Match("\t\t\t\t<File"); matches = Regex("\t\t\t\t\tRelPath = \"(.+)\""); string name = matches[0]; matches = Regex("\t\t\t\t\tDependentUpon = \"(.+)\"", true); string depends = (matches != null) ? matches[0] : null; matches = Regex("\t\t\t\t\tSubType = \"(.+)\"", true); string subtype = (matches != null) ? matches[0].ToLower() : null; matches = Regex("\t\t\t\t\tBuildAction = \"(.+)\""); package.File.Add(name, subtype, matches[0], depends); Match("\t\t\t\t/>"); } Match("\t\t</Files>"); Match("\t</CSHARP>"); Match("</VisualStudioProject>"); if (kind != "aspnet") ParseUserFile(project, package, filename); }
public override void Parse(Project project, string filename) { /* File header */ Begin(filename + ".sln"); Match("Microsoft Visual Studio Solution File, Format Version 8.00"); /* Package entries - VS "projects" */ string[] matches; Hashtable packageDependencies = new Hashtable(); do { matches = Regex("Project\\(\"{([0-9A-F-]+)}\"\\) = \"(.+)\", \"(.+)\", \"{([0-9A-F-]+)}\"", true); if (matches != null) { Package package = new Package(); project.Package.Add(package); package.Name = matches[1]; package.ID = matches[3]; package.Path = Path.GetDirectoryName(matches[2]); package.ScriptName = Path.GetFileName(matches[2]); switch (matches[0]) { case "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942": package.Language = "c++"; break; case "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC": package.Language = "c#"; break; } /* Collect package dependencies, I'll sort them out after * I finish parsing the scripts below */ Match("\tProjectSection(ProjectDependencies) = postProject"); ArrayList deps = new ArrayList(); while (!Match("\tEndProjectSection", true)) { matches = Regex("\t\t{([0-9A-F-]+)} = {([0-9A-F-]+)}"); if (matches[0] != matches[1]) throw new FormatException("GUID mismatch in ProjectDependencies block, should be the same"); deps.Add(matches[0]); } packageDependencies[package.ID] = deps; Match("EndProject"); } } while (matches != null); Match("Global"); /* Read the list of configurations */ Match("\tGlobalSection(SolutionConfiguration) = preSolution"); do { matches = Regex("\t\t(.+)[ ]=[ ](.+)", true); if (matches != null) { if (matches[0] != matches[1]) throw new FormatException("Configuration name mismatch: " + matches[0] + " != " + matches[1]); project.Configuration.Add(matches[0]); } } while (matches != null); foreach (Package package in project.Package) package.Config.Add(project); Match("\tEndGlobalSection"); /* Read the list of package configurations */ Match("\tGlobalSection(ProjectConfiguration) = postSolution"); foreach (Package package in project.Package) { string arch = (package.Language == "c++") ? "Win32" : ".NET"; foreach (string config in project.Configuration) { string pattern = "\t\t{" + package.ID + "}." + config + ".ActiveCfg = " + config + "|" + arch; Match(pattern); pattern = "\t\t{" + package.ID + "}." + config + ".Build.0 = " + config + "|" + arch; Match(pattern); } } Match("\tEndGlobalSection"); Match("\tGlobalSection(ExtensibilityGlobals) = postSolution"); Match("\tEndGlobalSection"); Match("\tGlobalSection(ExtensibilityAddIns) = postSolution"); Match("\tEndGlobalSection"); Match("EndGlobal"); foreach (Package package in project.Package) { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); switch (package.Language) { case "c++": ParseCpp(project, package, filename); break; case "c#": ParseCs(project, package, filename); break; default: throw new NotImplementedException("Loading of " + package.Language + " packages not implemented"); } } /* Now sort out the inter-package dependencies */ foreach (Package package in project.Package) { ArrayList deps = (ArrayList)packageDependencies[package.ID]; string[] deplist = new string[deps.Count]; for (int i = 0; i < deps.Count; ++i) { foreach (Package p2 in project.Package) { if (p2.ID == (string)deps[i]) deplist[i] = p2.Name; } } foreach (Configuration config in package.Config) config.Dependencies = deplist; } }
public override void Parse(Project project, string filename) { Begin(filename + ".mds"); string[] matches = Regex("<Combine name=\"(.+)\" fileversion=\"2.0\">"); project.Name = matches[0]; matches = Regex(" <Configurations active=\"(.+)\">"); string active = matches[0]; // Parse configurations while (!Match(" </Configurations>", true)) { matches = Regex(" <Configuration name=\"(.+)\" ctype=\"CombineConfiguration\">"); Configuration config = new Configuration(); config.Name = matches[0]; project.Configuration.Add(matches[0]); int i = 0; while (!Match(" </Configuration>", true)) { matches = Regex(" <Entry build=\"True\" name=\"(.+?)\" configuration=\"" + active + "\" />"); if (i == project.Package.Count) { Package package = new Package(); package.Name = matches[0]; project.Package.Add(package); } else { if (project.Package[i].Name != matches[0]) throw new FormatException("Package name should be " + project.Package[i] + ", is " + matches[0]); } } } foreach (Package package in project.Package) { foreach (string name in project.Configuration) { Configuration config = new Configuration(); config.Name = name; package.Config.Add(config); } } // Parse startup entries Match(" <StartMode startupentry=\"" + project.Package[0].Name + "\" single=\"True\">"); foreach (Package package in project.Package) { Match(" <Execute type=\"None\" entry=\"" + package.Name + "\" />"); } Match(" </StartMode>"); // Parse project entries Match(" <Entries>"); foreach (Package package in project.Package) { matches = Regex(" <Entry filename=\"(.+)\" />"); /* Pull out directory, but keep the path separators intact (no translation) */ package.Path = matches[0].Substring(0, Path.GetDirectoryName(matches[0]).Length); package.ScriptName = Path.GetFileName(matches[0]); } Match(" </Entries>"); Match("</Combine>"); foreach (Package package in project.Package) { string pkgfilename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); ParsePackage(project, package, pkgfilename); /* SHARPDEV_DEPENDENCY_BUG: Dependencies are set correctly here! */ #if SHARPDEV_DEPENDENCY_BUG Console.WriteLine(package.Name + ": "); foreach (Configuration config in package.Config) { Console.WriteLine(" " + config.Name + ": " + config.Dependencies.Length); } #endif } }
private void ParseCs(Project project, Package package, string filename) { string kind = package.Kind; Begin(filename); Match("<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"); Match(" <PropertyGroup>"); string[] matches; matches = Regex(" <Configuration Condition=\" '\\$\\(Configuration\\)' == '' \\\">(.+)</Configuration>"); string defaultConfigName = matches[0]; Match(" <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>"); Match(" <ProductVersion>8.0.50727</ProductVersion>"); Match(" <SchemaVersion>2.0</SchemaVersion>"); Match(" <ProjectGuid>{" + package.ID + "}</ProjectGuid>"); matches = Regex(" <OutputType>(.+)</OutputType>"); if (kind == null) { switch (matches[0]) { case "Exe": kind = "exe"; break; case "WinExe": kind = "winexe"; break; case "Library": kind = "dll"; break; default: throw new FormatException("Unexpected value: OutputType = \"" + matches[0] + "\""); } } else if (matches[0] != "Library") { throw new FormatException("Output type must be 'library' for ASP.NET applications"); } Match(" <AppDesignerFolder>Properties</AppDesignerFolder>"); matches = Regex("<RootNamespace>(.+)</RootNamespace>"); string target = matches[0]; Match(" <AssemblyName>" + target + "</AssemblyName>"); Match(" </PropertyGroup>"); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); config.Kind = kind; config.Target = target; Match(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == '" + config.Name + "|AnyCPU' \">"); if (!Match(" <DebugSymbols>true</DebugSymbols>", true)) { buildFlags.Add("no-symbols"); Match(" <DebugType>pdbonly</DebugType>"); } else { Match(" <DebugType>full</DebugType>"); } matches = Regex(" <Optimize>(true|false)</Optimize>"); if (matches[0] == "true") buildFlags.Add("optimize"); matches = Regex(" <OutputPath>(.*)\\\\</OutputPath>"); config.BinDir = matches[0]; config.OutDir = matches[0]; matches = Regex(" <DefineConstants>(.*)</DefineConstants>"); config.Defines = matches[0].Split(';'); if (config.Defines[0] == String.Empty) config.Defines = new string[] { }; Match(" <ErrorReport>prompt</ErrorReport>"); Match(" <WarningLevel>4</WarningLevel>"); if (Match(" <AllowUnsafeBlocks>true</AllowUnsafeBlocks>", true)) buildFlags.Add("unsafe"); if (Match(" <TreatWarningsAsErrors>true</TreatWarningsAsErrors>", true)) buildFlags.Add("fatal-warnings"); Match(" </PropertyGroup>"); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } ArrayList links = new ArrayList(); Match(" <ItemGroup>"); while (!Match(" </ItemGroup>", true)) { matches = Regex(" <Reference Include=\"(.+)\" />", true); if (matches != null) { string name = matches[0]; links.Add(name); } matches = Regex(" <ProjectReference Include=\"(.+)\">", true); if (matches != null) { matches = Regex(" <Project>{([0-9A-F-]+)}</Project>"); matches = Regex(" <Name>(.+)</Name>"); Match(" </ProjectReference>"); string name = matches[0]; links.Add(name); } } foreach (Configuration config in package.Config) { config.Links = (string[])links.ToArray(typeof(string)); } Match(" <ItemGroup>"); while (!Match(" </ItemGroup>", true)) { matches = Regex(" <(.+) Include=\"(.+)\"(>| />)"); string action = matches[0]; string name = matches[1]; string endtag = matches[2]; string subtype = ""; string depends = ""; if (action == "Compile" && endtag == ">") { subtype = "code"; while (!Match(" </Compile>", true)) { matches = Regex(" <SubType>(.+)</SubType>", true); if (matches != null) subtype = matches[0]; if (Match(" <AutoGen>True</AutoGen>", true)) subtype = "autogen"; matches = Regex(" <DependentUpon>(.+)</DependentUpon>", true); if (matches != null) depends = matches[0]; } } else { subtype = "code"; } if (action == "EmbeddedResource" && endtag == ">") { while (!Match(" </EmbeddedResource>", true)) { matches = Regex(" <SubType>(.+)</SubType>", true); if (matches != null) subtype = matches[0]; matches = Regex(" <DependentUpon>(.+)</DependentUpon>", true); if (matches != null) depends = matches[0]; if (Match(" <Generator>ResXFileCodeGenerator</Generator>", true)) { subtype = "autogen"; Match(" <LastGenOutput>" + Path.GetFileNameWithoutExtension(name) + ".Designer.cs</LastGenOutput>"); } } } if (action == "Content") { Match(" <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>"); Match(" </Content>"); } package.File.Add(name, subtype, action, depends); } Match(" <Import Project=\"$(MSBuildBinPath)\\Microsoft.CSharp.targets\" />"); Match(" <!-- To modify your build process, add your task inside one of the targets below and uncomment it. "); Match(" Other similar extension points exist, see Microsoft.Common.targets."); Match(" <Target Name=\"BeforeBuild\">"); Match(" </Target>"); Match(" <Target Name=\"AfterBuild\">"); Match(" </Target>"); Match(" -->"); Match("</Project>"); if (kind != "aspnet") ParseUserFile(project, package, filename); }
private void ParseCpp(Project project, Package package, string filename) { Begin(filename); Match("<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"); Match("<VisualStudioProject"); Match("\tProjectType=\"Visual C++\""); Match("\tVersion=\"8.00\""); Match("\tName=\"" + package.Name + "\""); string[] matches = Regex("\tProjectGUID=\"{([A-F0-9-]+)}\""); if (matches[0] != package.ID) throw new FormatException("Solution (" + package.ID + ") and project (" + matches[0] + ") GUIDs don't match"); Match("\tRootNamespace=\"" + package.Name + "\""); Match("\tKeyword=\"Win32Proj\""); Match("\t>"); Match("\t<Platforms>"); Match("\t\t<Platform"); Match("\t\t\tName=\"Win32\""); Match("\t\t/>"); Match("\t</Platforms>"); Match("\t<ToolFiles>"); Match("\t</ToolFiles>"); Match("\t<Configurations>"); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); Match("\t\t<Configuration"); Match("\t\t\tName=\"" + config.Name + "|Win32\""); matches = Regex("\t\t\tOutputDirectory=\"(.+)\""); config.OutDir = matches[0]; matches = Regex("\t\t\tIntermediateDirectory=\"(.+)\""); config.ObjDir = matches[0]; matches = Regex("\t\t\tConfigurationType=\"([0-9])\""); switch (int.Parse(matches[0])) { case 1: config.Kind = "exe"; break; case 2: config.Kind = "dll"; break; case 4: config.Kind = "lib"; break; default: throw new FormatException("Unrecognized value: ConfigurationType=\"" + matches[0] + "\""); } if (config.Kind == "lib") config.LibDir = config.OutDir; else config.BinDir = config.OutDir; matches = Regex("\t\t\tCharacterSet=\"([1-2])\""); if (matches[0] == "1") buildFlags.Add("unicode"); Match("\t\t\t>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCPreBuildEventTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCCustomBuildTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCXMLDataGeneratorTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCMIDLTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCCLCompilerTool\""); matches = Regex("\t\t\t\tAdditionalOptions=\"(.+)\"", true); config.BuildOptions = (matches != null) ? matches[0] : String.Empty; matches = Regex("\t\t\t\tOptimization=\"([0-9])\""); int optimization = int.Parse(matches[0]); switch (optimization) { case 0: break; case 1: buildFlags.Add("optimize-size"); break; case 2: buildFlags.Add("optimize-speed"); break; case 3: buildFlags.Add("optimize"); break; default: throw new FormatException("Unrecognized value: Optimization=\"" + matches[0] + "\""); } if (Match("\t\t\t\tOmitFramePointers=\"true\"", true)) buildFlags.Add("no-frame-pointer"); matches = Regex("\t\t\t\tAdditionalIncludeDirectories=\"(.+)\"", true); config.IncludePaths = (matches != null) ? matches[0].Split(';') : new string[] { }; matches = Regex("\t\t\t\tPreprocessorDefinitions=\"(.+)\"", true); config.Defines = (matches != null) ? matches[0].Split(';') : new string[] { }; if (optimization == 0) Match("\t\t\t\tMinimalRebuild=\"true\""); if (Match("\t\t\t\tExceptionHandling=\"false\"", true)) buildFlags.Add("no-exceptions"); if (optimization > 0) Match("\t\t\t\tStringPooling=\"true\"", true); if (optimization == 0) Match("\t\t\t\tBasicRuntimeChecks=\"3\"", true); if (optimization == 0) matches = Regex("\t\t\t\tRuntimeLibrary=\"(1|3)\""); else matches = Regex("\t\t\t\tRuntimeLibrary=\"(0|2)\""); if (matches[0] == "0" || matches[0] == "1") config.LinkFlags = new string[] { "static-runtime" }; Match("\t\t\t\tEnableFunctionLevelLinking=\"true\""); if (Match("\t\t\t\tRuntimeTypeInfo=\"false\"", true)) buildFlags.Add("no-rtti"); matches = Regex("\t\t\t\tUsePrecompiledHeader=\"([0-9])\""); if (matches[0] != "0") throw new FormatException("Expected UsePrecompiledHeader to be 0, got " + matches[0]); matches = Regex("\t\t\t\tWarningLevel=\"([3-4])\""); if (matches[0] == "4") buildFlags.Add("extra-warnings"); if (Match("\t\t\t\tWarnAsError=\"true\"", true)) buildFlags.Add("fatal-warnings"); matches = Regex("\t\t\t\tDetect64BitPortabilityProblems=\"(true|false)\""); if (matches[0] == "false") buildFlags.Add("no-64bit-checks"); matches = Regex("\t\t\t\tDebugInformationFormat=\"([0-9])\""); if (matches[0] == "0") buildFlags.Add("no-symbols"); else if (matches[0] != "4") throw new FormatException("Unexpected value: DebugInformationFormat=\"" + matches[0] + "\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCManagedResourceCompilerTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); if (config.IncludePaths.Length == 0) { Match("\t\t\t\tName=\"VCResourceCompilerTool\""); } else { Match("\t\t\t\tName=\"VCResourceCompilerTool\""); matches = Regex("\t\t\t\tAdditionalIncludeDirectories=\"(.+)\""); if (config.IncludePaths.Length != matches[0].Split(';').Length) throw new FormatException("Resource compiler getting different include paths"); } Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCPreLinkEventTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); if (config.Kind == "lib") { Match("\t\t\t\tName=\"VCLibrarianTool\""); matches = Regex("\t\t\t\tOutputFile=\"\\$\\(OutDir\\)/(.+)\""); config.Target = matches[0]; } else { Match("\t\t\t\tName=\"VCLinkerTool\""); matches = Regex("\t\t\t\tAdditionalDependencies=\"(.+)\"", true); if (matches != null) config.Links = matches[0].Split(' '); if (Match("\t\t\t\tIgnoreImportLibrary=\"true\"", true)) buildFlags.Add("no-import-lib"); matches = Regex("\t\t\t\tOutputFile=\"\\$\\(OutDir\\)/(.+)\""); config.Target = matches[0]; Match("\t\t\t\tLinkIncremental=\"" + (optimization == 0 ? 2 : 1) + "\""); matches = Regex("\t\t\t\tAdditionalLibraryDirectories=\"(.+)\""); matches = matches[0].Split(';'); config.LibDir = matches[0]; if (config.LibDir != config.OutDir) config.BinDir = config.OutDir; config.LibPaths = new string[matches.Length - 1]; for (int i = 0; i < matches.Length - 1; ++i) config.LibPaths[i] = matches[i + 1]; matches = Regex("\t\t\t\tModuleDefinitionFile=\"(.+)\"", true); if (matches != null) package.DefFile = matches[0]; string expected = buildFlags.Contains("no-symbols") ? "false" : "true"; Match("\t\t\t\tGenerateDebugInformation=\"" + expected + "\""); if (!buildFlags.Contains("no-symbols")) Match("\t\t\t\tProgramDatabaseFile=\"$(OutDir)/" + Path.GetFileNameWithoutExtension(config.Target) + ".pdb\""); matches = Regex("\t\t\t\tSubSystem=\"([0-9])\""); if (config.Kind == "exe" && matches[0] == "2") config.Kind = "winexe"; if (optimization > 0) { Match("\t\t\t\tOptimizeReferences=\"2\""); Match("\t\t\t\tEnableCOMDATFolding=\"2\""); } if (config.Kind == "exe" || config.Kind == "winexe") { if (!Match("\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"", true)) buildFlags.Add("no-main"); } else { matches = Regex("\t\t\t\tImportLibrary=\"(.+)\""); config.ImportLib = matches[0]; } Match("\t\t\t\tTargetMachine=\"1\""); } Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCALinkTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCManifestTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCXDCMakeTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCBscMakeTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCFxCopTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCAppVerifierTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCWebDeploymentTool\""); Match("\t\t\t/>"); Match("\t\t\t<Tool"); Match("\t\t\t\tName=\"VCPostBuildEventTool\""); Match("\t\t\t/>"); Match("\t\t</Configuration>"); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } Match("\t</Configurations>"); Match("\t<References>"); Match("\t</References>"); Match("\t<Files>"); string indent = "\t"; string folder = ""; while (!Match("\t</Files>", true)) { if (Match(indent + "\t<Filter", true)) { indent += "\t"; matches = Regex(indent + "\tName=\"(.+)\""); folder = Path.Combine(folder, matches[0]); Match(indent + "\tFilter=\"\""); Match(indent + "\t>"); } else if (Match(indent + "</Filter>", true)) { indent = indent.Substring(0, indent.Length - 1); folder = Path.GetDirectoryName(folder); } else { Match(indent + "\t<File"); matches = Regex(indent + "\t\tRelativePath=\"(.+)\">"); package.File.Add(matches[0]); Match(indent + "\t</File>"); /* Make sure file appears in the correct folder */ filename = matches[0]; if (filename.StartsWith(".\\")) filename = filename.Substring(2); while (filename.StartsWith("..\\")) filename = filename.Substring(3); if (Path.GetDirectoryName(filename) != folder) throw new FormatException("File '" + matches[0] + "' is in folder '" + folder + "'"); } } if (indent != "\t") throw new FormatException("Unclosed entity in <Files> block"); Match("\t<Globals>"); Match("\t</Globals>"); Match("</VisualStudioProject>"); }
private void ParseCpp(Project project, Package package, string filename) { Begin(filename); Match("# Microsoft Developer Studio Project File - Name=\"" + package.Name + "\" - Package Owner=<4>"); Match("# Microsoft Developer Studio Generated Build File, Format Version 6.00"); Match("# ** DO NOT EDIT **"); Match(""); string[] matches = Regex("# TARGTYPE (.+)"); switch (matches[0]) { case "\"Win32 (x86) Application\" 0x0101": package.Kind = "winexe"; break; case "\"Win32 (x86) Console Application\" 0x0103": package.Kind = "exe"; break; case "\"Win32 (x86) Dynamic-Link Library\" 0x0102": package.Kind = "dll"; break; case "\"Win32 (x86) Static Library\" 0x0104": package.Kind = "lib"; break; default: throw new FormatException("Unrecognized target type: '" + matches[0] + "'"); } string baseKind = matches[0].Substring(0, matches[0].Length - 7); Match(""); matches = Regex("CFG=" + package.Name + " - (.+)"); string defaultConfig = matches[0]; Match("!MESSAGE This is not a valid makefile. To build this project using NMAKE,"); Match("!MESSAGE use the Export Makefile command and run"); Match("!MESSAGE "); Match("!MESSAGE NMAKE /f \"" + package.Name + ".mak\"."); Match("!MESSAGE "); Match("!MESSAGE You can specify a configuration when running NMAKE"); Match("!MESSAGE by defining the macro CFG on the command line. For example:"); Match("!MESSAGE "); Match("!MESSAGE NMAKE /f \"" + package.Name + ".mak\" CFG=\"" + package.Name + " - " + defaultConfig + "\""); Match("!MESSAGE "); Match("!MESSAGE Possible choices for configuration are:"); Match("!MESSAGE "); baseKind = baseKind.Replace("(", "\\("); baseKind = baseKind.Replace(")", "\\)"); while (!Match("!MESSAGE ", true)) { matches = Regex("!MESSAGE \"" + package.Name + " - ([^\"]+)\" \\(based on " + baseKind + "\\)"); Configuration config = new Configuration(); config.Name = matches[0]; config.Dependencies = new string[0]; package.Config.Add(config); } Match(""); /* Verify configurations */ if (project.Configuration.Count == 0) { foreach (Configuration config in package.Config) project.Configuration.Add(config.Name); } else { foreach (Configuration config in package.Config) if (!project.Configuration.Contains(config.Name)) throw new FormatException("Config '" + config.Name + "' not found in project"); } Match("# Begin Project"); Match("# PROP AllowPerConfigDependencies 0"); Match("# PROP Scc_ProjName \"\""); Match("# PROP Scc_LocalPath \"\""); Match("CPP=cl.exe"); if (package.Kind != "lib") Match("MTL=midl.exe"); Match("RSC=rc.exe"); Match(""); bool first = true; foreach (Configuration config in package.Config) { ArrayList bldflags = new ArrayList(); ArrayList lnkflags = new ArrayList(); ArrayList defines = new ArrayList(); ArrayList incpaths = new ArrayList(); ArrayList links = new ArrayList(); ArrayList libpaths = new ArrayList(); string cond = (first) ? "!IF" : "!ELSEIF"; first = false; Match(cond + " \"$(CFG)\" == \"" + package.Name + " - " + config.Name + "\""); Match(""); Match("# PROP BASE Use_MFC 0"); matches = Regex("# PROP BASE Use_Debug_Libraries ([0-1])"); string useDebugLib = matches[0]; matches = Regex("# PROP BASE Output_Dir \"(.+)\""); config.OutDir = matches[0]; config.BinDir = matches[0]; config.LibDir = matches[0]; matches = Regex("# PROP BASE Intermediate_Dir \"(.+)\""); config.ObjDir = matches[0]; Match("# PROP BASE Target_Dir \"\""); Match("# PROP Use_MFC 0"); Match("# PROP Use_Debug_Libraries " + useDebugLib); Match("# PROP Output_Dir \"" + config.OutDir + "\""); Match("# PROP Intermediate_Dir \"" + config.ObjDir + "\""); if (Match("# PROP Ignore_Export_Lib 1", true)) bldflags.Add("no-import-lib"); Match("# PROP Target_Dir \"\""); matches = Regex("# ADD BASE CPP /nologo (.+)"); string flags = matches[0]; matches = flags.Split(' '); int i = 0; if (matches[i] == "/MTd" || matches[i] == "/MT") { lnkflags.Add("static-runtime"); } else { Expect(matches[i], "/MDd", "/MD"); } ++i; if (matches[i] == "/W4") { bldflags.Add("extra-warnings"); } else { Expect(matches[i], "/W3"); } ++i; if (matches[i] == "/WX") { bldflags.Add("fatal-warnings"); ++i; } if (matches[i] == "/Gm") { ++i; } if (matches[i] == "/GR") { ++i; } else { bldflags.Add("no-rtti"); } if (matches[i] == "/GX") { ++i; } else { bldflags.Add("no-exceptions"); } if (matches[i] == "/ZI") { ++i; } else { bldflags.Add("no-symbols"); } if (matches[i] == "/O1") { bldflags.Add("optimize-size"); } else if (matches[i] == "/O2") { bldflags.Add("optimize"); } else { Expect(matches[i], "/Od"); } ++i; if (matches[i] == "/Oy") { bldflags.Add("no-frame-pointer"); ++i; } while (matches[i] == "/I") { incpaths.Add(matches[++i].Trim('\"')); ++i; } while (matches[i] == "/D") { defines.Add(matches[++i].Trim('\"')); ++i; } Expect(matches[i], "/YX"); Expect(matches[++i], "/FD"); if (matches[++i] == "/GZ") ++i; Expect(matches[i++], "/c"); config.BuildOptions = String.Empty; while (i < matches.Length) config.BuildOptions += " " + matches[i++]; config.BuildOptions = config.BuildOptions.Trim(); Match("# ADD CPP /nologo " + flags); string debugSymbol = bldflags.Contains("no-symbols") ? "NDEBUG" : "_DEBUG"; bool hasMtl = Match("# ADD BASE MTL /nologo /D \"" + debugSymbol + "\" /mktyplib203 /win32", true); if (hasMtl) Match("# ADD MTL /nologo /D \"" + debugSymbol + "\" /mktyplib203 /win32"); ArrayList resDefines = new ArrayList(); ArrayList resPaths = new ArrayList(); matches = Regex("# ADD BASE RSC /l 0x409 (.+)"); while (matches[0].Length > 0) { if (matches[0].StartsWith("/d") || matches[0].StartsWith("/i")) { int split = matches[0].IndexOf('"', 4); string value = matches[0].Substring(4, split - 4); if (matches[0].StartsWith("/d")) resDefines.Add(value); else resPaths.Add(value); matches[0] = matches[0].Substring(split + 1).TrimStart(); } else { config.ResOptions = matches[0]; matches[0] = ""; } } config.ResDefines = (string[])resDefines.ToArray(typeof(string)); config.ResPaths = (string[])resPaths.ToArray(typeof(string)); string rsc = "# ADD RSC /l 0x409"; foreach (string symbol in resDefines) rsc += " /d \"" + symbol + "\""; foreach (string symbol in resPaths) rsc += " /i \"" + symbol + "\""; if (config.ResOptions != null) rsc += " " + config.ResOptions; Match(rsc); Match("BSC32=bscmake.exe"); Match("# ADD BASE BSC32 /nologo"); Match("# ADD BSC32 /nologo"); if (Match("LINK32=link.exe -lib", true)) { config.Kind = "lib"; Match("# ADD BASE LIB32 /nologo"); matches = Regex("# ADD LIB32 /nologo /out:\"(.+)\"", true); if (matches != null) { config.Target = matches[0]; } else { Match("# ADD LIB32 /nologo"); } } else { Match("LINK32=link.exe"); matches = Regex("# ADD BASE LINK32 (.+)"); flags = matches[0]; matches = flags.Split(' '); i = 0; while (i < matches.Length && matches[i][0] != '/') links.Add(matches[i++]); Expect(matches[i++], "/nologo"); bool noMain = true; if (matches[i] == "/entry:\"mainCRTStartup\"") { noMain = false; ++i; } if (matches[i] == "/subsystem:windows") { config.Kind = "winexe"; } else if (matches[i] == "/subsystem:console") { config.Kind = "exe"; } else if (matches[i] == "/dll") { config.Kind = "dll"; } else { throw new FormatException("Unexpected subsystem flag: " + matches[i]); } ++i; if (hasMtl && config.Kind != "winexe" && config.Kind != "dll") throw new FormatException("Found unexpected MTL block"); if ((config.Kind == "winexe" || config.Kind == "exe") && noMain) bldflags.Add("no-main"); if (!bldflags.Contains("no-symbols")) { Expect(matches[i++], "/incremental:yes"); Expect(matches[i++], "/debug"); } Expect(matches[i++], "/machine:I386"); if (config.Kind == "dll") { config.ImportLib = matches[i].Substring(9, matches[i].Length - 10); ++i; } config.Target = matches[i].Substring(6, matches[i].Length - 7); if (config.Target.StartsWith(config.OutDir)) config.Target = config.Target.Substring(config.OutDir.Length + 1); ++i; if (!bldflags.Contains("no-symbols")) Expect(matches[i++], "/pdbtype:sept"); config.LibDir = matches[i].Substring(10, matches[i].Length - 11); ++i; while (i < matches.Length && matches[i].StartsWith("/libpath:")) { libpaths.Add(matches[i].Substring(10, matches[i].Length - 11)); ++i; } Match("# ADD LINK32 " + flags); } config.BuildFlags = (string[])bldflags.ToArray(typeof(string)); config.LinkFlags = (string[])lnkflags.ToArray(typeof(string)); config.Defines = (string[])defines.ToArray(typeof(string)); config.IncludePaths = (string[])incpaths.ToArray(typeof(string)); config.Links = (string[])links.ToArray(typeof(string)); config.LibPaths = (string[])libpaths.ToArray(typeof(string)); Match(""); } Match("!ENDIF"); Match(""); Match("# Begin Target"); Match(""); foreach (Configuration config in package.Config) Match("# Name \"" + package.Name + " - " + config.Name + "\""); string folder = ""; while (!Match("# End Target", true)) { matches = Regex("# Begin Group \"(.+)\"", true); if (matches != null) { folder = Path.Combine(folder, matches[0]); Match(""); Match("# PROP Default_Filter \"\""); continue; } matches = Regex("# End Group", true); if (matches != null) { folder = Path.GetDirectoryName(folder); continue; } Match("# Begin Source File"); Match(""); matches = Regex("SOURCE=(.+)"); filename = matches[0]; package.File.Add(filename); if (filename.StartsWith("./")) filename = filename.Substring(2); while (filename.StartsWith("../")) filename = filename.Substring(3); if (Path.GetDirectoryName(filename) != folder) throw new FormatException("File '" + matches[0] + "' is in folder '" + folder + "'"); Match("# End Source File"); } }
private void ParseCpp(Project project, Package package) { bool isMac = false; string[] matches; foreach (Configuration config in package.Config) { package.Kind = "exe"; config.Kind = "exe"; ArrayList buildFlags = new ArrayList(); Match("ifeq ($(CONFIG)," + config.Name + ")"); matches = Regex(" BINDIR := (.+)"); config.BinDir = matches[0]; matches = Regex(" LIBDIR := (.+)"); config.LibDir = matches[0]; matches = Regex(" OBJDIR := (.+)"); config.ObjDir = matches[0]; matches = Regex(" OUTDIR := (.+)"); config.OutDir = matches[0]; matches = Regex(" CPPFLAGS := (.*)"); System.Text.RegularExpressions.MatchCollection mc; mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "-I \"(.+?)\""); config.IncludePaths = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.IncludePaths[i] = mc[i].Groups[1].ToString(); mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "-D \"(.+?)\""); config.Defines = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.Defines[i] = mc[i].Groups[1].ToString(); matches = Regex(" CFLAGS \\+= \\$\\(CPPFLAGS\\)(.*)"); if (matches != null) { bool symbols = false; config.BuildOptions = ""; string[] flags = matches[0].Split(' '); foreach (string flag in flags) { switch (flag) { case "-fomit-frame-pointer": buildFlags.Add("no-frame-pointer"); break; case "-g": symbols = true; break; case "-O2": buildFlags.Add("optimize"); break; case "-O3": buildFlags.Add("optimize-speed"); break; case "-Os": buildFlags.Add("optimize-size"); break; case "-Wall": buildFlags.Add("extra-warnings"); break; case "-Werror": buildFlags.Add("fatal-warnings"); break; default: config.BuildOptions += flag + " "; break; } } if (!symbols) buildFlags.Add("no-symbols"); config.BuildOptions = config.BuildOptions.Trim(' '); } matches = Regex(" CXXFLAGS := \\$\\(CFLAGS\\)(.*)"); if (matches != null) { string[] flags = matches[0].Split(' '); foreach (string flag in flags) { switch (flag) { case "--no-exceptions": buildFlags.Add("no-exceptions"); break; case "--no-rtti": buildFlags.Add("no-rtti"); break; } } } matches = Regex(" LDFLAGS \\+= -L\\$\\(BINDIR\\) -L\\$\\(LIBDIR\\)(.*)"); mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "-L \"(.+?)\""); config.LibPaths = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.LibPaths[i] = mc[i].Groups[1].ToString(); mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "-l([^ $]+)"); config.Links = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.Links[i] = mc[i].Groups[1].ToString(); foreach (string flag in matches[0].Split(' ')) { switch (flag) { case "-dynamiclib": buildFlags.Add("dylib"); break; case "-shared": package.Kind = "dll"; config.Kind = "dll"; break; } } /* Pull out the link options...this gets a bit hairy */ int split = matches[0].IndexOf("-L"); if (split < 0) split = matches[0].IndexOf("-l"); if (split < 0) split = matches[0].Length; config.LinkOptions = matches[0].Substring(0, split); config.LinkOptions = config.LinkOptions.Trim(' '); if (config.LinkOptions.StartsWith("-s")) { config.LinkOptions = config.LinkOptions.Substring(2); config.LinkOptions = config.LinkOptions.Trim(' '); } matches = Regex(" LDDEPS :=(.*)"); config.LinkDeps = matches[0].Trim().Split(' '); matches = Regex(" TARGET := (.+)"); config.Target = matches[0]; isMac = Match(" MACAPP := " + config.Target + ".app/Contents", true); if (Match(" BLDCMD = ar -cr $(OUTDIR)/$(TARGET) $(OBJECTS); ranlib $(OUTDIR)/$(TARGET)", true)) config.Kind = "lib"; else if (package.Language == "c++") Match(" BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES)"); else Match(" BLDCMD = $(CC) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES)"); Match("endif"); Match(""); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } Match("OBJECTS := \\"); do { matches = Regex("\t\\$\\(OBJDIR\\)/(.+?) \\\\", true); } while (matches != null); Match(""); if (Match("RESOURCES := \\", true)) { do { matches = Regex("\t\\$\\(OBJDIR\\)/(.+?) \\\\", true); } while (matches != null); Match(""); } Match("CMD := $(subst \\,\\\\,$(ComSpec)$(COMSPEC))"); Match("ifeq (,$(CMD))"); Match(" CMD_MKBINDIR := mkdir -p $(BINDIR)"); Match(" CMD_MKLIBDIR := mkdir -p $(LIBDIR)"); Match(" CMD_MKOUTDIR := mkdir -p $(OUTDIR)"); Match(" CMD_MKOBJDIR := mkdir -p $(OBJDIR)"); Match("else"); Match(" CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\\\,$(BINDIR)) mkdir $(subst /,\\\\,$(BINDIR))"); Match(" CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\\\,$(LIBDIR)) mkdir $(subst /,\\\\,$(LIBDIR))"); Match(" CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\\\,$(OUTDIR)) mkdir $(subst /,\\\\,$(OUTDIR))"); Match(" CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\\\,$(OBJDIR)) mkdir $(subst /,\\\\,$(OBJDIR))"); Match("endif"); Match(""); Match(".PHONY: clean"); Match(""); if (isMac) { Match("all: $(OUTDIR)/$(MACAPP)/PkgInfo $(OUTDIR)/$(MACAPP)/Info.plist $(OUTDIR)/$(MACAPP)/MacOS/$(TARGET)"); Match(""); Match("$(OUTDIR)/$(MACAPP)/MacOS/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)"); } else { Match("$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)"); } Match("\t@echo Linking " + package.Name); Match("\t-@$(CMD_MKBINDIR)"); Match("\t-@$(CMD_MKLIBDIR)"); Match("\t-@$(CMD_MKOUTDIR)"); if (isMac) { Match("\t-@if [ ! -d $(OUTDIR)/$(MACAPP)/MacOS ]; then mkdir -p $(OUTDIR)/$(MACAPP)/MacOS; fi"); } Match("\t@$(BLDCMD)"); Match(""); if (isMac) { Match("$(OUTDIR)/$(MACAPP)/PkgInfo:"); Match(""); Match("$(OUTDIR)/$(MACAPP)/Info.plist:"); Match(""); } Match("clean:"); Match("\t@echo Cleaning " + package.Name); if (isMac) { Match("\t-@rm -rf $(OUTDIR)/$(TARGET).app $(OBJDIR)"); } else { Match("\t-@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR)"); } Match(""); do { matches = Regex("^\\$\\(OBJDIR\\)/(.+)[.](o|res): (.+)", true); if (matches != null) { package.File.Add(matches[2]); Match("\t-@$(CMD_MKOBJDIR)"); Match("\t@echo $(notdir $<)"); switch (Path.GetExtension(matches[2])) { case ".c": Match("\t@$(CC) $(CFLAGS) -o $@ -c $<"); break; case ".s": Match("\t@$(CC) -x assembler-with-cpp $(CPPFLAGS) -o $@ -c $<"); break; case ".rc": Match("\t@windres $< -O coff -o $@"); break; default: Match("\t@$(CXX) $(CXXFLAGS) -o $@ -c $<"); break; } Match(""); } } while (matches != null); Match("-include $(OBJECTS:%.o=%.d)"); }
private void ParseCpp(Project project, Package package, string filename) { Begin(filename); Match("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"); Match("<CodeBlocks_project_file>"); Match("\t<FileVersion major=\"1\" minor=\"6\" />"); Match("\t<Project>"); Match("\t\t<Option title=\"" + package.Name + "\" />"); Match("\t\t<Option pch_mode=\"2\" />", true); Match("\t\t<Option compiler=\"gcc\" />"); Match("\t\t<Build>"); package.Language = "c++"; while (!Match("\t\t</Build>", true)) { Configuration config = new Configuration(); package.Config.Add(config); string[] matches = Regex("\t\t\t<Target title=\"(.+?)\">"); config.Name = matches[0]; while (!Match("\t\t\t</Target>", true)) { ArrayList buildFlags = new ArrayList(); ArrayList defines = new ArrayList(); ArrayList incPaths = new ArrayList(); ArrayList libPaths = new ArrayList(); ArrayList libs = new ArrayList(); config.BuildOptions = ""; config.LinkOptions = ""; matches = Regex("\t\t\t\t<Option output=\"(.+?)\" prefix_auto=\"0\" extension_auto=\"0\" />"); config.Target = Path.GetFileName(matches[0]).Replace('\\', '/'); config.OutDir = Path.GetDirectoryName(matches[0]).Replace('\\', '/'); ; config.OutFile = Path.GetFileName(matches[0]).Replace('\\', '/'); ; matches = Regex("\t\t\t\t<Option object_output=\"(.+?)\" />"); config.ObjDir = matches[0]; matches = Regex("\t\t\t\t<Option type=\"([0-9])\" />"); switch (matches[0]) { case "0": config.Kind = "winexe"; break; case "1": config.Kind = "exe"; break; case "2": config.Kind = "lib"; break; case "3": config.Kind = "dll"; break; default: throw new FormatException("Unknown configuration type " + matches[0]); } if (config.Kind == "lib") { config.BinDir = ""; config.LibDir = config.OutDir; } else { config.BinDir = config.OutDir; config.LibDir = ""; } Match("\t\t\t\t<Option compiler=\"gcc\" />"); if (config.Kind == "dll") { Match("\t\t\t\t<Option createDefFile=\"0\" />"); matches = Regex("\t\t\t\t<Option createStaticLib=\"([0-1])\" />"); if (matches[0] == "0") buildFlags.Add("no-import-lib"); } Match("\t\t\t\t<Compiler>"); while (!Match("\t\t\t\t</Compiler>", true)) { matches = Regex("\t\t\t\t\t<Add option=\"(.+?)\" />", true); if (matches != null) { switch (matches[0]) { case "-fomit-frame-pointer": buildFlags.Add("no-frame-pointer"); break; case "--no-exceptions": buildFlags.Add("no-exceptions"); break; case "--no-rtti": buildFlags.Add("no-rtti"); break; case "-O": buildFlags.Add("optimize"); break; case "-O3": buildFlags.Add("optimize-speed"); break; case "-Os": buildFlags.Add("optimize-size"); break; case "-g": break; case "-Wall": buildFlags.Add("extra-warnings"); break; case "-Werror": buildFlags.Add("fatal-warnings"); break; default: if (matches[0].StartsWith("-D")) { defines.Add(matches[0].Substring(2)); } else { config.BuildOptions += matches[0] + " "; } break; } } matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />", true); if (matches != null) { incPaths.Add(matches[0]); } } Match("\t\t\t\t<Linker>"); while (!Match("\t\t\t\t</Linker>", true)) { matches = Regex("\t\t\t\t\t<Add option=\"(.+?)\" />", true); if (matches != null) { switch (matches[0]) { case "-s": buildFlags.Add("no-symbols"); break; default: config.LinkOptions += matches[0] + " "; break; } } matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />", true); if (matches != null) { libPaths.Add(matches[0]); } matches = Regex("\t\t\t\t\t<Add library=\"(.+?)\" />", true); if (matches != null) { libs.Add(matches[0]); } } ArrayList resPaths = new ArrayList(); if (Match("\t\t\t\t<ResourceCompiler>", true)) { while (!Match("\t\t\t\t</ResourceCompiler>", true)) { matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />"); resPaths.Add(matches[0]); } } config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); config.Defines = (string[])defines.ToArray(typeof(string)); config.IncludePaths = (string[])incPaths.ToArray(typeof(string)); config.LibPaths = (string[])libPaths.ToArray(typeof(string)); config.Links = (string[])libs.ToArray(typeof(string)); config.BuildOptions = config.BuildOptions.Trim(' '); config.LinkOptions = config.LinkOptions.Trim(' '); config.ResPaths = (string[])resPaths.ToArray(typeof(string)); } } if (project.Configuration.Count == 0) { foreach (Configuration config in package.Config) project.Configuration.Add(config.Name); } while (!Match("\t\t<Extensions />", true)) { string[] matches = Regex("\t\t<Unit filename=\"(.+?)\">"); string name = matches[0]; package.File.Add(name); if (Path.GetExtension(name) == ".rc") { string resname = name.Replace("../", ""); resname = resname.Replace(".rc", ".res"); Match("\t\t\t<Option compilerVar=\"WINDRES\" />"); } else { if (Match("\t\t\t<Option compilerVar=\"CC\" />", true)) package.Language = "c"; else Match("\t\t\t<Option compilerVar=\"CPP\" />", true); if (!name.EndsWith(".c") && !name.EndsWith(".cpp")) { // Match("\t\t\t<Option compile=\"0\" />"); // Match("\t\t\t<Option link=\"0\" />"); } } foreach (Configuration cfg in package.Config) Match("\t\t\t<Option target=\"" + cfg.Name + "\" />"); Match("\t\t</Unit>"); } Match("\t</Project>"); Match("</CodeBlocks_project_file>"); }
private void ParsePackageHeader(Project project, Package package, string filename) { Begin(filename); string[] matches = Regex("# (.+?) (.+?) Makefile autogenerated by premake"); package.Language = matches[0].ToLower(); switch (matches[1]) { case "Console Executable": package.Kind = "exe"; break; case "Windowed Executable": package.Kind = "winexe"; break; case "Shared Library": package.Kind = "dll"; break; case "Static Library": package.Kind = "lib"; break; case "ASP.NET": package.Kind = "aspnet"; break; } Match("# Don't edit this file! Instead edit `premake.lua` then rerun `make`"); Match(""); Match("ifndef CONFIG"); Match(" CONFIG=" + project.Configuration[0]); Match("endif"); Match(""); if (package.Language == "c++" || package.Language == "c") ParseCpp(project, package); else ParseManaged(project, package); }
public void Add(Package package) { List.Add(package); }
public override void Parse(Project project, string filename) { Begin(filename + ".cmbx"); string[] matches = Regex("<Combine fileversion=\"(.+)\" name=\"(.+)\" description=\"(.*)\">"); project.Name = matches[1]; matches = Regex(" <StartMode startupentry=\"\" single=\"True\">"); while (!Match(" </StartMode>", true)) { matches = Regex(" <Execute entry=\"(.+)\" type=\"None\" />"); Package package = new Package(); package.Name = matches[0]; project.Package.Add(package); } Match(" <Entries>"); foreach (Package package in project.Package) { matches = Regex(" <Entry filename=\"(.+)\" />"); /* Pull out directory, but keep the path separators intact (no translation) */ package.Path = matches[0].Substring(0, Path.GetDirectoryName(matches[0]).Length); package.ScriptName = Path.GetFileName(matches[0]); } Match(" </Entries>"); matches = Regex(" <Configurations active=\"(.+)\">"); string active = matches[0]; while (!Match(" </Configurations>", true)) { matches = Regex(" <Configuration name=\"(.+)\">"); Configuration config = new Configuration(); config.Name = matches[0]; project.Configuration.Add(matches[0]); foreach (Package package in project.Package) { package.Config.Add(config); Match(" <Entry name=\"" + package.Name + "\" configurationname=\"" + active + "\" build=\"False\" />"); } Match(" </Configuration>"); } if (active != (string)project.Configuration[0]) throw new FormatException("Active configuration should be '" + project.Configuration[0] + "' but is '" + active + "'"); Match("</Combine>"); foreach (Package package in project.Package) { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); ParsePackage(project, package, filename); /* SHARPDEV_DEPENDENCY_BUG: Dependencies are set correctly here! */ #if SHARPDEV_DEPENDENCY_BUG Console.WriteLine(package.Name + ": "); foreach (Configuration config in package.Config) { Console.WriteLine(" " + config.Name + ": " + config.Dependencies.Length); } #endif } }
private void ParsePackage(Project project, Package package, string filename) { Begin(filename); string[] matches = Regex("<Project name=\"(.+)\" standardNamespace=\"(.+)\" description=\"(.*)\" newfilesearch=\"None\" enableviewstate=\"True\" version=\"1.1\" projecttype=\"(.+)\">"); package.Name = matches[0]; package.Language = matches[3].ToLower(); if (package.Name != matches[1]) throw new FormatException("Namespace should be '" + package.Name + "' but is '" + matches[1] + "'"); Match(" <Contents>"); Hashtable folders = new Hashtable(); folders.Add(".", true); while (!Match(" </Contents>", true)) { matches = Regex(" <File name=\"(.+)\" subtype=\"(.*)\" buildaction=\"(.+)\" dependson=\"(.*)\" data=\"(.*)\" />"); if (matches[1] == "Directory") { if (matches[2] != "Compile") throw new FormatException("Buildaction of folders must be Compile"); folders.Add(matches[0].Replace("/", "\\"), true); } else if (matches[1] == "Code") { if (matches[2] == "EmbedAsResource") matches[2] = "EmbeddedResource"; string path = Path.GetDirectoryName(matches[0]); if (folders[path] == null) throw new FormatException("Missing directory entry in file block for '" + path + "'"); package.File.Add(matches[0], matches[1], matches[2], matches[3]); } else { throw new FormatException("Unrecognized file subtype '" + matches[1] + "'"); } } ArrayList links = new ArrayList(); ArrayList lddep = new ArrayList(); if (!Match(" <References />", true)) { Match(" <References>"); while (!Match(" </References>", true)) { matches = Regex(" <Reference type=\"(Assembly|Gac|Project)\" refto=\"(.+)\" localcopy=\"(True|False)\" />"); links.Add(matches[1]); if (matches[0] == "Project") lddep.Add(matches[1]); } } foreach (Configuration config in package.Config) { config.Links = (string[])links.ToArray(typeof(string)); config.Dependencies = (string[])lddep.ToArray(typeof(string)); } Match(" <DeploymentInformation target=\"\" script=\"\" strategy=\"File\" />"); Match(" <Configurations active=\"" + project.Configuration[0] + "\">"); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); matches = Regex(" <Configuration runwithwarnings=\"(True|False)\" name=\"" + config.Name + "\">"); if (matches[0] == "False") buildFlags.Add("fatal-warnings"); matches = Regex(" <CodeGeneration runtime=\"(.+)\" compiler=\"(.+)\" compilerversion=\"(.*)\" warninglevel=\"4\" nowarn=\"(.*)\" includedebuginformation=\"(True|False)\" optimize=\"(True|False)\" unsafecodeallowed=\"(True|False)\" generateoverflowchecks=\"(True|False)\" mainclass=\"(.*)\" target=\"(.+)\" definesymbols=\"(.*)\" generatexmldocumentation=\"(.+)\" win32Icon=\"(.*)\" noconfig=\"False\" nostdlib=\"(True|False)\" />"); package.Compiler = matches[1]; switch (matches[9]) { case "Exe": config.Kind = "exe"; break; case "WinExe": config.Kind = "winexe"; break; case "Library": config.Kind = "dll"; break; } if (matches[4] == "False") buildFlags.Add("no-symbols"); if (matches[5] == "True") buildFlags.Add("optimize"); if (matches[6] == "True") buildFlags.Add("unsafe"); config.Defines = (matches[10] != "") ? matches[10].Split(';') : new string[]{}; Match(" <Execution commandlineparameters=\"\" consolepause=\"True\" />"); matches = Regex(" <Output directory=\"(.+)\" assembly=\"(.+)\" executeScript=\"(.*)\" executeBeforeBuild=\"(.*)\" executeAfterBuild=\"(.*)\" executeBeforeBuildArguments=\"(.*)\" executeAfterBuildArguments=\"(.*)\" />"); config.BinDir = matches[0]; config.OutDir = matches[0]; config.Target = matches[1]; Match(" </Configuration>"); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } Match(" </Configurations>"); Match("</Project>"); }
public override void Parse(Project project, string filename) { string root = Path.GetDirectoryName(filename); if (root != String.Empty) root += Path.DirectorySeparatorChar; Begin(root + "Makefile"); /* File header */ Match("# Makefile autogenerated by premake"); Match("# Don't edit this file! Instead edit `premake.lua` then rerun `make`"); Match("# Options:"); /* Project configurations */ string[] matches = Regex("# CONFIG=\\[(.+)\\]"); matches = matches[0].Split('|'); foreach (string config in matches) project.Configuration.Add(config); Match(""); Match("ifndef CONFIG"); Match(" CONFIG=" + project.Configuration[0]); Match("endif"); Match(""); Match("export CONFIG"); Match(""); /* Package list */ matches = Regex(".PHONY: all clean (.+)"); matches = matches[0].Split(' '); foreach (string name in matches) { Package package = new Package(project); project.Package.Add(package); package.Name = name; } Match(""); Match("all: " + String.Join(" ", matches)); Match(""); /* The premake script dependency...need a way to test this! */ string path = Path.Combine(project.Path, "premake.lua"); Regex("Makefile: (.+)"); Match("\t@echo ==== Regenerating Makefiles ===="); Regex("\t@premake --file \\$\\^ (.+)"); Match(""); foreach (Package package in project.Package) { matches = Regex(package.Name + ":(.*)"); foreach (Configuration config in package.Config) { config.Dependencies = matches[0].Trim().Split(' '); } Match("\t@echo ==== Building " + package.Name + " ===="); /* Pull out the package path */ matches = Regex("\t@\\$\\(MAKE\\) --no-print-directory -C (.+)"); int split = matches[0].IndexOf(" -f "); if (split > 0) { package.Path = matches[0].Substring(0, split); package.ScriptName = matches[0].Substring(split + 4); } else { package.Path = matches[0]; package.ScriptName = "Makefile"; } Match(""); } Match("clean:"); foreach (Package package in project.Package) { Regex("\t@\\$\\(MAKE\\) --no-print-directory -C " + package.Path + "(.*)clean$"); } /* Parse the individual packages */ foreach (Package package in project.Package) { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); ParsePackageHeader(project, package, filename); } }
public override void Parse(Project project, string filename) { /* File header */ Begin(filename + ".dsw"); Match("Microsoft Developer Studio Workspace File, Format Version 6.00"); Match("# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!"); Match(""); Match("###############################################################################"); Match(""); Hashtable dependencies = new Hashtable(); string[] matches; while (!Match("Global:", true)) { Package package = new Package(); project.Package.Add(package); matches = Regex("Project: \"(.+)\"=(.+) - Package Owner=<4>"); package.Name = matches[0]; package.Path = Path.GetDirectoryName(matches[1]); package.ScriptName = Path.GetFileName(matches[1]); package.Language = "c++"; Match(""); Match("Package=<5>"); Match("{{{"); Match("}}}"); Match(""); Match("Package=<4>"); Match("{{{"); /* Get the package dependencies, cache until I have configs */ ArrayList deps = new ArrayList(); while (Match(" Begin Project Dependency", true)) { matches = Regex(" Project_Dep_Name (.+)"); deps.Add(matches[0]); Match(" End Project Dependency"); } dependencies[package] = (string[])deps.ToArray(typeof(string)); Match("}}}"); Match(""); Match("###############################################################################"); Match(""); } Match(""); Match("Package=<5>"); Match("{{{"); Match("}}}"); Match(""); Match("Package=<3>"); Match("{{{"); Match("}}}"); Match(""); Match("###############################################################################"); Match(""); foreach (Package package in project.Package) { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); switch (package.Language) { case "c++": ParseCpp(project, package, filename); break; default: throw new NotImplementedException("Loading of " + package.Language + " packages not implemented"); } ArrayList temp = new ArrayList(); foreach (Configuration config in package.Config) { config.Dependencies = (string[])dependencies[package]; temp.Add(config); } /* VS6 stores configs in reverse order */ temp.Reverse(); for (int i = 0; i < package.Config.Count; ++i) package.Config[i] = (Configuration)temp[i]; } }
private void ParseManaged(Project project, Package package) { string[] matches = Regex("CSC := ([a-z]+)"); package.Compiler = matches[0]; matches = Regex("RESGEN := ([a-z]+)"); bool ok = false; switch (package.Compiler) { case "csc": case "cscc": ok = (matches[0] == "resgen"); break; case "mcs": ok = (matches[0] == "resgen"); break; default: throw new NotImplementedException("Unrecognized compiler: " + package.Compiler); } if (!ok) throw new FormatException("Compiler/Resgen mismatch"); Match(""); matches = Regex("OBJDIR := (.+)"); string objdir = matches[0]; Match(""); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); config.ObjDir = objdir; Match("ifeq ($(CONFIG)," + config.Name + ")"); matches = Regex(" BINDIR := (.+)"); config.BinDir = matches[0]; matches = Regex(" OUTDIR := (.+)"); config.OutDir = matches[0]; matches = Regex(" FLAGS \\+=(.*)"); bool symbols = false; config.BuildOptions = ""; string[] flags = matches[0].Split(' '); foreach (string flag in flags) { switch (flag) { case "/warnaserror": buildFlags.Add("fatal-warnings"); break; case "/o": buildFlags.Add("optimize"); break; case "/unsafe": buildFlags.Add("unsafe"); break; case "/debug": symbols = true; break; default: if (flag.StartsWith("/t:")) { config.Kind = flag.Substring(3); if (config.Kind == "library") config.Kind = "dll"; } else { config.BuildOptions += flag + " "; } break; } } if (!symbols) buildFlags.Add("no-symbols"); config.BuildOptions = config.BuildOptions.Trim(' '); System.Text.RegularExpressions.MatchCollection mc; mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "/d:([A-Za-z0-9_]+)"); config.Defines = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.Defines[i] = mc[i].Groups[1].ToString(); mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "/lib:\"(.+?)\""); config.LibPaths = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.LibPaths[i] = mc[i].Groups[1].ToString(); mc = System.Text.RegularExpressions.Regex.Matches(matches[0], "/r:([^ $]+)"); config.Links = new string[mc.Count]; for (int i = 0; i < mc.Count; ++i) config.Links[i] = mc[i].Groups[1].ToString(); matches = Regex(" DEPS :=(.*)"); config.LinkDeps = matches[0].Trim().Split(' '); matches = Regex(" TARGET := (.+)"); config.Target = Path.Combine(Path.GetDirectoryName(matches[0]), Path.GetFileNameWithoutExtension(matches[0])); Match("endif"); Match(""); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); } Match("SOURCES := \\"); do { matches = Regex("\t(.+?)[ ]\\\\", true); if (matches != null) package.File.Add(matches[0], "Compile"); } while (matches != null); Match(""); Match("EMBEDDEDFILES := \\"); do { matches = Regex("\t(.+?)[ ]\\\\", true); if (matches != null) package.File.Add(matches[0], "EmbeddedResource"); } while (matches != null); Match(""); Match("EMBEDDEDCOMMAND := \\"); foreach (SourceFile file in package.File) { if (file.BuildAction == "EmbeddedResource") Match("\t/resource:" + file.Name + " \\"); } while (matches != null); Match(""); Match("LINKEDFILES := \\"); do { matches = Regex("\t(.+?)[ ]\\\\", true); if (matches != null) package.File.Add(matches[0], "Linked"); } while (matches != null); Match(""); Match("LINKEDCOMMAND := \\"); foreach (SourceFile file in package.File) { if (file.BuildAction == "Linked") Match("\t/linkresource:" + file.Name + " \\"); } Match(""); Match("CONTENTFILES := \\"); do { matches = Regex("\t(.+?)[ ]\\\\", true); if (matches != null) package.File.Add(matches[0], "Content"); } while (matches != null); Match(""); Match("COPYLOCALFILES := \\"); do { matches = Regex("\t(.+?)[ ]\\\\", true); if (matches != null) package.CopyLocal.Add(matches[0].Substring(10)); } while (matches != null); Match(""); Match("COMPILECOMMAND := $(SOURCES) $(EMBEDDEDCOMMAND) $(LINKEDCOMMAND)"); Match(""); Match("CMD := $(subst \\,\\\\,$(ComSpec)$(COMSPEC))"); Match("ifeq (,$(CMD))"); Match(" CMD_MKOUTDIR := mkdir -p $(OUTDIR)"); Match("else"); Match(" CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\\\,$(OUTDIR)) mkdir $(subst /,\\\\,$(OUTDIR))"); Match("endif"); Match(""); Match(".PHONY: clean"); Match(""); Match("all: \\"); Match("\t$(OUTDIR)/$(TARGET) \\"); foreach (SourceFile file in package.File) { if (file.BuildAction == "Content") Match("\t$(BINDIR)/" + Path.GetFileName(file.Name) + " \\"); } Match(""); Match("$(OUTDIR)/$(TARGET): $(SOURCES) $(EMBEDDEDFILES) $(LINKEDFILES) $(COPYLOCALFILES) $(DEPS)"); Match("\t-@$(CMD_MKOUTDIR)"); Match("\t@$(CSC) /nologo /out:$@ /lib:$(BINDIR) $(FLAGS) $(COMPILECOMMAND)"); Match(""); foreach (SourceFile file in package.File) { if (file.BuildAction == "Linked") { string basename = Path.GetFileName(file.Name); Match("$(BINDIR)/" + basename + ": " + file.Name); Match("\t-@cp -fR $^ $@"); Match(""); } } foreach (SourceFile file in package.File) { if (file.BuildAction == "Content") { string basename = Path.GetFileName(file.Name); Match("$(BINDIR)/" + basename + ": " + file.Name); Match("\t-@cp -fR $^ $@"); Match(""); } } Match("clean:"); Match("\t@echo Cleaning " + package.Name); Match("\t-@rm -f $(OUTDIR)/$(TARGET)"); Match("\t-@rm -fR $(OBJDIR)"); }
public override void Parse(Project project, string filename) { /* File header */ Begin(filename + ".sln"); Match("Microsoft Visual Studio Solution File, Format Version 9.00"); Match("# Visual Studio 2005"); /* Package entries - VS "projects" */ string[] matches; Hashtable packageDependencies = new Hashtable(); while (!Match("Global", true)) { matches = Regex("Project\\(\"{([0-9A-F-]+)}\"\\) = \"(.+)\", \"(.+)\", \"{([0-9A-F-]+)}\""); Package package = new Package(); project.Package.Add(package); package.Name = matches[1]; package.ID = matches[3]; package.Path = Path.GetDirectoryName(matches[2]); package.ScriptName = Path.GetFileName(matches[2]); switch (matches[0]) { case "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942": package.Language = "c++"; break; case "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC": package.Language = "c#"; break; case "E24C65DC-7377-472B-9ABA-BC803B73C61A": package.Kind = "aspnet"; break; } if (package.Kind == "aspnet") { Match("\tProjectSection(WebsiteProperties) = preProject"); ArrayList deps = new ArrayList(); matches = Regex("\t\tProjectReferences = \"{([0-9A-F-]+)}|(.+).dll;\"", true); while (matches != null) { deps.Add(matches[0]); matches = Regex("\t\tProjectReferences = \"{([0-9A-F-]+)}|(.+).dll;\"", true); } packageDependencies[package.ID] = deps; matches = Regex("\t\t(.+).AspNetCompiler.VirtualPath = \"/" + package.Name + "\"", true); while (matches != null) { string cfg = matches[0]; Match("\t\t" + cfg + ".AspNetCompiler.PhysicalPath = \"" + package.Path + "\\\""); Match("\t\t" + cfg + ".AspNetCompiler.TargetPath = \"PrecompiledWeb\\" + package.Name + "\\\""); Match("\t\t" + cfg + ".AspNetCompiler.Updateable = \"true\""); Match("\t\t" + cfg + ".AspNetCompiler.ForceOverwrite = \"true\""); Match("\t\t" + cfg + ".AspNetCompiler.FixedNames = \"false\""); matches = Regex("\t\t" + cfg + ".AspNetCompiler.Debug = \"(True|False)\""); matches = Regex("\t\t(.+).AspNetCompiler.VirtualPath = \"/" + package.Name + "\"", true); } int port; if (_numAspNet == 0) port = 1106; else if (_numAspNet == 1) port = 1231; else port = 1251 + 2 * (_numAspNet - 2); Match("\t\tVWDPort = \"" + port + "\""); _numAspNet++; matches = Regex("\t\tDefaultWebSiteLanguage = \"(.+)\""); if (matches == null) package.Language = "vbnet"; else if (matches[0] == "Visual C#") package.Language = "c#"; Match("\tEndProjectSection"); } else { /* Collect package dependencies, I'll sort them out after * I finish parsing the scripts below */ Match("\tProjectSection(ProjectDependencies) = postProject"); ArrayList deps = new ArrayList(); while (!Match("\tEndProjectSection", true)) { matches = Regex("\t\t{([0-9A-F-]+)} = {([0-9A-F-]+)}"); if (matches[0] != matches[1]) throw new FormatException("GUID mismatch in ProjectDependencies block, should be the same"); deps.Add(matches[0]); } packageDependencies[package.ID] = deps; } Match("EndProject"); } /* Read the list of configurations...just cache for now, test later */ ArrayList possibleConfigs = new ArrayList(); Match("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); while (!Match("\tEndGlobalSection", true)) { matches = Regex("\t\t(.+)[ ]=[ ](.+)", true); string cfg = matches[0]; if (possibleConfigs.Contains(cfg)) throw new FormatException("Duplicate configuration '" + cfg + "'"); possibleConfigs.Add(cfg); /* Build up my list of scripted package configurations */ matches = cfg.Split('|'); if (!project.Configuration.Contains(matches[0])) project.Configuration.Add(matches[0]); } foreach (Package package in project.Package) package.Config.Add(project); /* Read the list of package configurations...cache and test later */ ArrayList packageConfigs = new ArrayList(); Match("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); while (!Match("\tEndGlobalSection", true)) { string cfg = GetLine(); if (packageConfigs.Contains(cfg)) throw new FormatException("Duplicate configuration '" + cfg + "'"); packageConfigs.Add(cfg); } Match("\tGlobalSection(SolutionProperties) = preSolution"); Match("\t\tHideSolutionNode = FALSE"); Match("\tEndGlobalSection"); Match("EndGlobal"); foreach (Package package in project.Package) { if (package.Kind != "aspnet") { filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName); switch (package.Language) { case "c++": ParseCpp(project, package, filename); break; case "c#": ParseCs(project, package, filename); break; default: throw new NotImplementedException("Loading of " + package.Language + " packages not implemented"); } } else { foreach (Configuration config in package.Config) config.Kind = "aspnet"; } } /* Now sort out the inter-package dependencies */ foreach (Package package in project.Package) { ArrayList deps = (ArrayList)packageDependencies[package.ID]; string[] deplist = new string[deps.Count]; for (int i = 0; i < deps.Count; ++i) { foreach (Package p2 in project.Package) { if (p2.ID == (string)deps[i]) deplist[i] = p2.Name; } } foreach (Configuration config in package.Config) config.Dependencies = deplist; } /* Now test configurations */ bool hasDotNet = false; bool hasCpp = false; foreach (Package package in project.Package) { if (package.Language == "c" || package.Language == "c++") hasCpp = true; else hasDotNet = true; } ArrayList platforms = new ArrayList(); if (hasDotNet) platforms.Add("Any CPU"); if (hasDotNet && hasCpp) platforms.Add("Mixed Platforms"); if (hasCpp) platforms.Add("Win32"); int c = 0; foreach (Package package in project.Package) { string arch; if (package.Language == "c" || package.Language == "c++") arch = "Win32"; else arch = "Any CPU"; foreach (Configuration config in package.Config) { foreach (string platform in platforms) { string configPlatform = config.Name + "|" + platform; if (!possibleConfigs.Contains(configPlatform)) throw new FormatException(configPlatform + " is not listed in possible configuration"); string root = "\t\t{" + package.ID + "}." + configPlatform + "."; string match = root + "ActiveCfg = " + config.Name + "|" + arch; if (((string)packageConfigs[c]) != match) throw new FormatException("Expected:\n " + match + "\nBut I got:\n " + packageConfigs[c]); c++; if (platform == "MixedPlatforms" || platform == arch) { match = root + "Build.0 = " + config.Name + "|" + arch; if (((string)packageConfigs[c]) != match) throw new FormatException("Expected:\n " + match + "\nBut I got:\n " + packageConfigs[c]); c++; } } } } }
private void ParsePackageHeader(Project project, Package package, string filename) { Begin(filename); string[] matches = Regex("# (.+?) (.+?) Makefile autogenerated by premake"); package.Language = matches[0].ToLower(); Match("# Don't edit this file! Instead edit `premake.lua` then rerun `make`"); Match(""); Match("ifndef CONFIG"); Match(" CONFIG=" + project.Configuration[0]); Match("endif"); Match(""); if (package.Language == "c++" || package.Language == "c") ParseCpp(project, package); else ParseManaged(project, package); }
private void ParseUserFile(Project project, Package package, string filename) { Begin(filename + ".user"); Match("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"); Match(" <PropertyGroup>"); string[] matches = Regex(" <ReferencePath>(.+)</ReferencePath>"); matches = matches[0].Split(';'); string[] libpaths = new string[matches.Length - 1]; /* VS.NET stores reference directories as absolute paths, so I need * to do some ugly trickery here */ string[] bindir = matches[matches.Length - 1].Split('\\'); for (int i = 0; i < matches.Length - 1; ++i) { string[] thisdir = matches[i].Split('\\'); int j = 0; while (j < bindir.Length && j < thisdir.Length && bindir[j] == thisdir[j]) ++j; string path = ""; for (int k = j + 1; k < bindir.Length; ++k) path += "..\\"; for (int k = j; k < thisdir.Length; ++k) path += thisdir[k] + '\\'; libpaths[i] = path.Substring(0, path.Length - 1); libpaths[i] = libpaths[i].Replace("/", "\\"); } foreach (Configuration config in package.Config) { config.LibPaths = libpaths; } Match(" </PropertyGroup>"); Match("</Project>"); }
private void ParsePackage(Project project, Package package, string filename) { Begin(filename); string[] matches; matches = Regex("<Project name=\"(.+?)\" fileversion=\"2.0\" language=\"(.+?)\" ctype=\"DotNetProject\">"); package.Name = matches[0]; package.Language = matches[1].ToLower(); Match(" <Configurations active=\"" + project.Configuration[0] + "\">"); foreach (Configuration config in package.Config) { ArrayList buildFlags = new ArrayList(); Match(" <Configuration name=\"" + config.Name + "\" ctype=\"DotNetProjectConfiguration\">"); matches = Regex(" <Output directory=\"(.+)\" assembly=\"(.+)\" />"); config.BinDir = matches[0]; config.OutDir = matches[0]; config.Target = matches[1]; matches = Regex(" <Build debugmode=\"(True|False)\" target=\"(.+?)\" />"); if (matches[0] == "False") buildFlags.Add("no-symbols"); switch (matches[1]) { case "Exe": config.Kind = "exe"; break; case "WinExe": config.Kind = "winexe"; break; case "Library": config.Kind = "dll"; break; } matches = Regex(" <Execution runwithwarnings=\"(True|False)\" consolepause=\"(True|False)\" runtime=\"MsNet\" />"); if (matches[0] == "False") buildFlags.Add("fatal-warnings"); matches = Regex(" <CodeGeneration compiler=\"Csc\" warninglevel=\"4\" optimize=\"(True|False)\" unsafecodeallowed=\"(True|False)\" generateoverflowchecks=\"(True|False)\" definesymbols=\"(.*?)\" generatexmldocumentation=\"(True|False)\" ctype=\"CSharpCompilerParameters\" />"); package.Compiler = "Csc"; if (matches[0] == "True") buildFlags.Add("optimize"); if (matches[1] == "True") buildFlags.Add("unsafe"); Match(" </Configuration>"); config.BuildFlags = (string[])buildFlags.ToArray(typeof(string)); config.Defines = (matches[3] != "") ? matches[3].Split(';') : new string[] { }; } Match(" </Configurations>"); Match(" <DeploymentInformation strategy=\"File\">"); Match(" <excludeFiles />"); Match(" </DeploymentInformation>"); Match(" <Contents>"); Hashtable folders = new Hashtable(); folders.Add(".", true); while (!Match(" </Contents>", true)) { matches = Regex(" <File name=\"(.+?)\" subtype=\"(.*)\" buildaction=\"(.+?)\" />"); if (matches[1] == "Directory") { if (matches[2] != "Compile") throw new FormatException("Buildaction of folders must be Compile"); folders.Add(matches[0], true); } else if (matches[1] == "Code") { if (matches[2] == "EmbedAsResource") matches[2] = "EmbeddedResource"; /* Get path without translating directory separators to \ */ string path = matches[0].Substring(0, Path.GetDirectoryName(matches[0]).Length); if (folders[path] == null) throw new FormatException("Missing directory entry in file block for '" + path + "'"); package.File.Add(matches[0], matches[1], matches[2], null); } else { throw new FormatException("Unrecognized file subtype '" + matches[1] + "'"); } } ArrayList links = new ArrayList(); ArrayList lddep = new ArrayList(); if (!Match(" <References />", true)) { Match(" <References>"); while (!Match(" </References>", true)) { matches = Regex(" <Reference type=\"(Assembly|Gac|Project)\" localcopy=\"(True|False)\" refto=\"(.+)\" />"); links.Add(matches[2]); if (matches[0] == "Project") lddep.Add(matches[2]); } } foreach (Configuration config in package.Config) { config.Links = (string[])links.ToArray(typeof(string)); config.Dependencies = (string[])lddep.ToArray(typeof(string)); } Match("</Project>"); }