Gave CreateTemplate the ability to generate a new Solution. Updated documentation. Minor fixes.
parent
40588a0974
commit
7bf338e925
|
@ -8,55 +8,253 @@ namespace CreateTemplate
|
|||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
static int Main(string[] args)
|
||||
{
|
||||
// Validate command line:
|
||||
if(args.Length == 0 || args.Length != (args[0] == "--template" ? 4 : 3))
|
||||
if(args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" CreateTemplate [--template] <ProjectName> <SourceDirectory> <DestinationDirectory>");
|
||||
Console.WriteLine("Creates a copy of FNA Template suitable for starting new FNA projects.");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("The output will be placed in the folder at <DestinationDirectory>" + Path.DirectorySeparatorChar + "<ProjectName>");
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" CreateTemplate [--source <SourceDir>] [--solution] [--template]");
|
||||
Console.WriteLine(" <ProjectName> <DestinationDir>");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine(" --template: Generate a Visual Studio compatible project template.");
|
||||
Console.WriteLine(" --source (-s) : Sets the source directory containing FNATemplate.csproj.");
|
||||
Console.WriteLine(" If not specified, it is searched for up the directory");
|
||||
Console.WriteLine(" hierarchy with the name FNATemplate.");
|
||||
Console.WriteLine(" --solution : Generates a full solution in the output directory.");
|
||||
Console.WriteLine(" --template (-t) : Generate a Visual Studio compatible project template.");
|
||||
Console.WriteLine();
|
||||
return;
|
||||
Console.WriteLine("The output project is placed at <DestinationDir>" + Path.DirectorySeparatorChar + "<ProjectName>");
|
||||
Console.WriteLine();
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool createTemplate = false;
|
||||
bool createSolution = false;
|
||||
string sourceDirectory = null;
|
||||
string projectName = null;
|
||||
string destinationDirectory = null;
|
||||
int parameterNumber = 0;
|
||||
|
||||
Queue<string> arguments = new Queue<string>(args);
|
||||
while(arguments.Count > 0)
|
||||
{
|
||||
string a = arguments.Dequeue();
|
||||
switch(a)
|
||||
{
|
||||
case "--source":
|
||||
if(arguments.Count > 0)
|
||||
sourceDirectory = Path.GetFullPath(arguments.Dequeue());
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: Must specify a directory for --source.");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case "--solution":
|
||||
createSolution = true;
|
||||
break;
|
||||
|
||||
case "--template":
|
||||
case "-t":
|
||||
createTemplate = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch(parameterNumber)
|
||||
{
|
||||
case 0:
|
||||
projectName = a;
|
||||
break;
|
||||
case 1:
|
||||
destinationDirectory = Path.GetFullPath(a);
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("ERROR: Too many parameters.");
|
||||
return 1;
|
||||
}
|
||||
parameterNumber++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(parameterNumber < 2)
|
||||
{
|
||||
Console.WriteLine("ERROR: Not enough parameters.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(createSolution && createTemplate)
|
||||
{
|
||||
Console.WriteLine("WARNING: --template and --solution options together are kind of silly.");
|
||||
}
|
||||
|
||||
|
||||
bool vsTemplate = args[0] == "--template";
|
||||
string projectName = args[vsTemplate ? 1 : 0];
|
||||
string sourceDirectory = Path.GetFullPath(args[vsTemplate ? 2 : 1]);
|
||||
string destinationDirectory = Path.GetFullPath(args[vsTemplate ? 3 : 2]);
|
||||
// Search for the source directory if it is not specified
|
||||
if(sourceDirectory == null)
|
||||
{
|
||||
DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
|
||||
while(true)
|
||||
{
|
||||
string possibleSourceDir = Path.Combine(di.FullName, "FNATemplate");
|
||||
if(Directory.Exists(possibleSourceDir) && File.Exists(Path.Combine(possibleSourceDir, "FNATemplate.csproj")))
|
||||
{
|
||||
sourceDirectory = possibleSourceDir;
|
||||
Console.WriteLine("Found source directory at:");
|
||||
Console.WriteLine(sourceDirectory);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(di.Parent != null)
|
||||
di = di.Parent;
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find SourceDir. Specify with --source or ensure CreateTemplate is in the correct location.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!Directory.Exists(sourceDirectory))
|
||||
{
|
||||
Console.WriteLine("ERROR: Source directory not found!");
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!File.Exists(Path.Combine(sourceDirectory, "FNATemplate.csproj")))
|
||||
{
|
||||
Console.WriteLine("ERROR: Source directory is missing \"FNATemplate.csproj\"");
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(destinationDirectory.StartsWith(sourceDirectory)) // <- Probably not the most robust way to do this...
|
||||
{
|
||||
Console.WriteLine("ERROR: Destination directory is contained with the source directory!");
|
||||
return;
|
||||
Console.WriteLine("ERROR: Destination directory is contained within the source directory!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// If we're creating a solution, we need these paths:
|
||||
string fnaProjectDirectory = null;
|
||||
string fnaProjectFile = null;
|
||||
string fnalibsDirectory = null;
|
||||
string buildDirectory = null;
|
||||
if(createSolution)
|
||||
{
|
||||
DirectoryInfo di = new DirectoryInfo(sourceDirectory).Parent;
|
||||
|
||||
fnaProjectDirectory = Path.Combine(di.FullName, "FNA");
|
||||
fnaProjectFile = Path.Combine(fnaProjectDirectory, "FNA.csproj");
|
||||
fnalibsDirectory = Path.Combine(di.FullName, "fnalibs");
|
||||
buildDirectory = Path.Combine(di.FullName, "build");
|
||||
|
||||
if(!Directory.Exists(fnaProjectDirectory))
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find directory \"" + fnaProjectDirectory + "\".");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!File.Exists(fnaProjectFile))
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find \"" + fnaProjectFile + "\".");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!Directory.Exists(fnalibsDirectory))
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find directory \"" + fnalibsDirectory + "\".");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!Directory.Exists(buildDirectory))
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find directory \"" + buildDirectory + "\".");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// And off we go...
|
||||
//
|
||||
|
||||
string projectDirectory = Path.Combine(destinationDirectory, projectName);
|
||||
Directory.CreateDirectory(projectDirectory);
|
||||
StreamWriter templateFile = null;
|
||||
|
||||
if(vsTemplate)
|
||||
StreamWriter templateFile = null;
|
||||
StreamWriter solutionFile = null;
|
||||
|
||||
string fnaProjectGuid = null;
|
||||
string projectGuid = Guid.NewGuid().ToString("B").ToUpperInvariant();
|
||||
|
||||
if(createSolution)
|
||||
{
|
||||
string fnaProjectText = File.ReadAllText(fnaProjectFile);
|
||||
string projectGuidString = "<ProjectGuid>";
|
||||
int guidStart = fnaProjectText.IndexOf(projectGuidString);
|
||||
int guidEnd = fnaProjectText.IndexOf("</ProjectGuid>");
|
||||
if(guidStart >= 0 && guidEnd >= guidStart + projectGuidString.Length)
|
||||
{
|
||||
fnaProjectGuid = fnaProjectText.Substring(guidStart + projectGuidString.Length, guidEnd - (guidStart + projectGuidString.Length));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: Could not find ProjectGuid in FNA.csproj.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
solutionFile = new StreamWriter(Path.Combine(destinationDirectory, projectName + ".sln"), false,
|
||||
Encoding.UTF8); // <- NOTE: Encoding required so we get a BOM so the VS version selector can deal with us
|
||||
solutionFile.WriteLine("");
|
||||
solutionFile.WriteLine("Microsoft Visual Studio Solution File, Format Version 11.00");
|
||||
solutionFile.WriteLine("# Visual Studio 2010");
|
||||
solutionFile.WriteLine("Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"" + projectName + "\", \"" + projectName + "\\" + projectName + ".csproj\", \"" + projectGuid + "\"");
|
||||
solutionFile.WriteLine("EndProject");
|
||||
solutionFile.WriteLine("Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"FNA\", \"FNA\\FNA.csproj\", \"" + fnaProjectGuid + "\"");
|
||||
solutionFile.WriteLine("EndProject");
|
||||
solutionFile.WriteLine("Global");
|
||||
solutionFile.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
|
||||
solutionFile.WriteLine("\t\tDebug|Any CPU = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\tDebug|x86 = Debug|x86");
|
||||
solutionFile.WriteLine("\t\tRelease|Any CPU = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\tRelease|x86 = Release|x86");
|
||||
solutionFile.WriteLine("\tEndGlobalSection");
|
||||
solutionFile.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Debug|Any CPU.ActiveCfg = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Debug|Any CPU.Build.0 = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Debug|x86.ActiveCfg = Debug|x86");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Debug|x86.Build.0 = Debug|x86");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Release|Any CPU.ActiveCfg = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Release|Any CPU.Build.0 = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Release|x86.ActiveCfg = Release|x86");
|
||||
solutionFile.WriteLine("\t\t" + projectGuid + ".Release|x86.Build.0 = Release|x86");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Debug|Any CPU.ActiveCfg = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Debug|Any CPU.Build.0 = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Debug|x86.ActiveCfg = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Debug|x86.Build.0 = Debug|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Release|Any CPU.ActiveCfg = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Release|Any CPU.Build.0 = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Release|x86.ActiveCfg = Release|Any CPU");
|
||||
solutionFile.WriteLine("\t\t" + fnaProjectGuid + ".Release|x86.Build.0 = Release|Any CPU");
|
||||
solutionFile.WriteLine("\tEndGlobalSection");
|
||||
solutionFile.WriteLine("\tGlobalSection(SolutionProperties) = preSolution");
|
||||
solutionFile.WriteLine("\t\tHideSolutionNode = FALSE");
|
||||
solutionFile.WriteLine("\tEndGlobalSection");
|
||||
solutionFile.WriteLine("EndGlobal");
|
||||
solutionFile.Close();
|
||||
|
||||
string[] ignore = { "bin", "obj" };
|
||||
CopyDirectoryRecursive(fnaProjectDirectory, Path.Combine(destinationDirectory, "FNA"), ignore);
|
||||
CopyDirectoryRecursive(fnalibsDirectory, Path.Combine(destinationDirectory, "fnalibs"), ignore);
|
||||
CopyDirectoryRecursive(buildDirectory, Path.Combine(destinationDirectory, "build"), ignore);
|
||||
}
|
||||
|
||||
if(createTemplate)
|
||||
{
|
||||
templateFile = new StreamWriter(Path.Combine(projectDirectory, projectName + ".vstemplate"));
|
||||
templateFile.WriteLine("<VSTemplate Version=\"3.0.0\" xmlns=\"http://schemas.microsoft.com/developer/vstemplate/2005\" Type=\"Project\">");
|
||||
|
@ -111,9 +309,9 @@ namespace CreateTemplate
|
|||
for(int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if(lines[i].Contains("<ProjectGuid>"))
|
||||
lines[i] = " <ProjectGuid>" + (vsTemplate ? "$guid1$" : Guid.NewGuid().ToString()) + "</ProjectGuid>";
|
||||
lines[i] = " <ProjectGuid>" + (createTemplate ? "$guid1$" : projectGuid) + "</ProjectGuid>"; // <- TODO: Handle more than one project?
|
||||
else if(lines[i].Contains("FNATemplate"))
|
||||
lines[i] = lines[i].Replace("FNATemplate", vsTemplate ? "$safeprojectname$" : projectName);
|
||||
lines[i] = lines[i].Replace("FNATemplate", createTemplate ? "$safeprojectname$" : projectName);
|
||||
}
|
||||
File.WriteAllLines(outputPath, lines);
|
||||
|
||||
|
@ -125,9 +323,9 @@ namespace CreateTemplate
|
|||
for(int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if(lines[i].Contains("[assembly: Guid("))
|
||||
lines[i] = "[assembly: Guid(\"" + (vsTemplate ? "$guid2$" : Guid.NewGuid().ToString()) + "\")]";
|
||||
lines[i] = "[assembly: Guid(\"" + (createTemplate ? "$guid2$" : Guid.NewGuid().ToString()) + "\")]";
|
||||
else if(lines[i].Contains("FNATemplate"))
|
||||
lines[i] = lines[i].Replace("FNATemplate", vsTemplate ? "$safeprojectname$" : projectName);
|
||||
lines[i] = lines[i].Replace("FNATemplate", createTemplate ? "$safeprojectname$" : projectName);
|
||||
}
|
||||
File.WriteAllLines(outputPath, lines);
|
||||
|
||||
|
@ -139,7 +337,7 @@ namespace CreateTemplate
|
|||
replaceParameters = false;
|
||||
}
|
||||
|
||||
if(vsTemplate)
|
||||
if(createTemplate)
|
||||
{
|
||||
templateFile.Write(" <ProjectItem TargetFileName=\"");
|
||||
templateFile.Write(templateTargetFileName);
|
||||
|
@ -152,8 +350,7 @@ namespace CreateTemplate
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if(vsTemplate)
|
||||
if(createTemplate)
|
||||
{
|
||||
templateFile.WriteLine(" </Project>");
|
||||
templateFile.WriteLine(" </TemplateContent>");
|
||||
|
@ -161,6 +358,44 @@ namespace CreateTemplate
|
|||
templateFile.Close();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void CopyDirectoryRecursive(string sourceDirName, string destDirName, IEnumerable<string> ignore = null)
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
|
||||
|
||||
if(!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
if(!Directory.Exists(destDirName))
|
||||
{
|
||||
Directory.CreateDirectory(destDirName);
|
||||
}
|
||||
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach(FileInfo file in files)
|
||||
{
|
||||
if(ignore != null && ignore.Contains(file.Name))
|
||||
continue;
|
||||
|
||||
string temppath = Path.Combine(destDirName, file.Name);
|
||||
file.CopyTo(temppath, true);
|
||||
}
|
||||
|
||||
foreach(DirectoryInfo subdir in dirs)
|
||||
{
|
||||
if(ignore != null && ignore.Contains(subdir.Name))
|
||||
continue;
|
||||
|
||||
string temppath = Path.Combine(destDirName, subdir.Name);
|
||||
CopyDirectoryRecursive(subdir.FullName, temppath, ignore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
README.md
20
README.md
|
@ -46,9 +46,9 @@ Once Wine and winetricks are installed:
|
|||
- Setup Wine with `winecfg`
|
||||
- Install the DirectX SDK with `winetricks dxsdk_jun2010`
|
||||
|
||||
NOTE: At time of writing there is a bug in winetricks that will cause the DirectX SDK to not install correctly. See https://github.com/Winetricks/winetricks/issues/841. You can either fix that bug (`which winetricks`, then find and replace the broken hash value), or use the alternative method:
|
||||
NOTE: Ensure you have the latest version of winetricks, or you may hit this bug: https://github.com/Winetricks/winetricks/issues/841.
|
||||
|
||||
**Alternative:** Instead of installing the DirectX SDK, you can place a copy of `fxc.exe` from the DirectX SDK in the `build/tools` directory. Then use `winetricks d3dcompiler_43` to install the required DLL from the DirectX redistributable (this is a smaller download than the SDK). See `BuildShaders.targets` for details. The same fallback also works on Windows.
|
||||
**Alternative method:** Instead of installing the DirectX SDK, you can place a copy of `fxc.exe` from the DirectX SDK in the `build/tools` directory. Then use `winetricks d3dcompiler_43` to install the required DLL from the DirectX redistributable (this is a smaller download than the SDK). See `BuildShaders.targets` for details. The same fallback also works on Windows.
|
||||
|
||||
(Linux/macOS) Setting the library path for debugging
|
||||
----------------------------------------------------
|
||||
|
@ -80,15 +80,15 @@ Use the CreateTemplate tool to create new versions of the FNATemplate project (N
|
|||
|
||||
The command line is:
|
||||
|
||||
`CreateTemplate [--template] <ProjectName> <SourceDirectory> <DestinationDirectory>`
|
||||
`CreateTemplate [--source <SourceDir>] [--solution] [--template] <ProjectName> <DestinationDir>`
|
||||
|
||||
You can use it to directly create new projects:
|
||||
You can use it to directly create new projects (or an entire solution with `--solution`):
|
||||
|
||||
`CreateTemplate NewProject "X:\pathToThisSolution\FNATemplate" "X:\yourSolution"`
|
||||
`CreateTemplate NewProject "X:\yourSolution"`
|
||||
|
||||
Or you can create a Visual Studio template file, which itself can be used to create projects.
|
||||
|
||||
`CreateTemplate --template FNATemplate "X:\pathToThisSolution\FNATemplate" .`
|
||||
`CreateTemplate --template FNATemplate "X:\outputPath"`
|
||||
|
||||
To install the generated template in Visual Studio:
|
||||
|
||||
|
@ -99,17 +99,15 @@ To install the generated template in Visual Studio:
|
|||
|
||||
(NOTE: Ensure that the .vstemplate file is at the root of the resulting .zip file. Otherwise the template will not work.)
|
||||
|
||||
Creating your own solution
|
||||
--------------------------
|
||||
Adding a FNA Template project to an existing solution
|
||||
-----------------------------------------------------
|
||||
|
||||
To use FNA Template to create projects in a fresh solution, you will need to:
|
||||
To use an FNA Template-drived project in an existing solution you will need to:
|
||||
|
||||
- Copy the "build" directory into the same directory as your new solution
|
||||
- Add the "FNA" and "fnalibs" directories as specified above
|
||||
- Add the FNA project to your solution (Right click solution -> Add Existing Project)
|
||||
|
||||
From this point, you can use the CreateTemplate tool (or a Visual Studio template created by the same) to add new FNA game projects to your solution.
|
||||
|
||||
|
||||
Building and loading shaders
|
||||
============================
|
||||
|
|
Loading…
Reference in New Issue