|
|
@@ -0,0 +1,390 @@
|
|
|
+//
|
|
|
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
|
|
|
+// LICENSE: Atomic Game Engine Editor and Tools EULA
|
|
|
+// Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
|
|
|
+// license information: https://github.com/AtomicGameEngine/AtomicGameEngine
|
|
|
+//
|
|
|
+
|
|
|
+#include <Atomic/IO/Log.h>
|
|
|
+#include <Atomic/IO/File.h>
|
|
|
+#include <Atomic/IO/FileSystem.h>
|
|
|
+
|
|
|
+#include "../ToolEnvironment.h"
|
|
|
+#include "NETProjectGen.h"
|
|
|
+
|
|
|
+namespace ToolCore
|
|
|
+{
|
|
|
+
|
|
|
+NETProjectBase::NETProjectBase(Context* context, NETProjectGen* projectGen):
|
|
|
+ Object(context), xmlFile_(new XMLFile(context)), projectGen_(projectGen)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+NETProjectBase::~NETProjectBase()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void NETProjectBase::ReplacePathStrings(String& path)
|
|
|
+{
|
|
|
+ ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
|
|
|
+
|
|
|
+ const String& atomicRoot = tenv->GetRootSourceDir();
|
|
|
+ const String& scriptPlatform = projectGen_->GetScriptPlatform();
|
|
|
+
|
|
|
+ path.Replace("$ATOMIC_ROOT$", atomicRoot, false);
|
|
|
+ path.Replace("$SCRIPT_PLATFORM$", scriptPlatform, false);
|
|
|
+}
|
|
|
+
|
|
|
+NETCSProject::NETCSProject(Context* context, NETProjectGen* projectGen) : NETProjectBase(context, projectGen)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+NETCSProject::~NETCSProject()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void NETCSProject::CreateCompileItemGroup(XMLElement &projectRoot)
|
|
|
+{
|
|
|
+ FileSystem* fs = GetSubsystem<FileSystem>();
|
|
|
+
|
|
|
+ XMLElement igroup = projectRoot.CreateChild("ItemGroup");
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < sourceFolders_.Size(); i++)
|
|
|
+ {
|
|
|
+ const String& sourceFolder = sourceFolders_[i];
|
|
|
+
|
|
|
+ Vector<String> result;
|
|
|
+ fs->ScanDir(result, sourceFolder, "*.cs", SCAN_FILES, true);
|
|
|
+
|
|
|
+ for (unsigned j = 0; j < result.Size(); j++)
|
|
|
+ {
|
|
|
+ igroup.CreateChild("Compile").SetAttribute("Include", sourceFolder + result[j]);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void NETCSProject::CreateReferencesItemGroup(XMLElement &projectRoot)
|
|
|
+{
|
|
|
+ ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
|
|
|
+ FileSystem* fs = GetSubsystem<FileSystem>();
|
|
|
+
|
|
|
+ const String& coreCLRAbsPath = tenv->GetNETCoreCLRAbsPath();
|
|
|
+
|
|
|
+ XMLElement igroup = projectRoot.CreateChild("ItemGroup");
|
|
|
+
|
|
|
+ XMLElement mscorlibref = igroup.CreateChild("Reference");
|
|
|
+ mscorlibref.SetAttribute("Include", "mscorlib");
|
|
|
+ mscorlibref.CreateChild("HintPath").SetValue(coreCLRAbsPath + "mscorlib.dll");
|
|
|
+ mscorlibref.CreateChild("Private").SetValue("False");
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < references_.Size(); i++)
|
|
|
+ {
|
|
|
+ String ref = references_[i];
|
|
|
+ String refpath = ref + ".dll";
|
|
|
+
|
|
|
+ // we explicitly add mscorlib
|
|
|
+ if (ref == "mscorlib")
|
|
|
+ continue;
|
|
|
+
|
|
|
+ XMLElement xref = igroup.CreateChild("Reference");
|
|
|
+ xref.SetAttribute("Include", ref);
|
|
|
+
|
|
|
+ // if we're a coreclr assembly, qualify it
|
|
|
+ if (fs->FileExists(coreCLRAbsPath + refpath))
|
|
|
+ {
|
|
|
+ refpath = coreCLRAbsPath + refpath;
|
|
|
+ }
|
|
|
+
|
|
|
+ xref.CreateChild("HintPath").SetValue(refpath);
|
|
|
+ xref.CreateChild("Private").SetValue("False");
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void NETCSProject::CreateReleasePropertyGroup(XMLElement &projectRoot)
|
|
|
+{
|
|
|
+ XMLElement pgroup = projectRoot.CreateChild("PropertyGroup");
|
|
|
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ");
|
|
|
+
|
|
|
+ pgroup.CreateChild("DebugType").SetValue("full");
|
|
|
+ pgroup.CreateChild("Optimize").SetValue("true");
|
|
|
+ pgroup.CreateChild("OutputPath").SetValue(assemblyOutputPath_);
|
|
|
+ pgroup.CreateChild("ErrorReport").SetValue("prompt");
|
|
|
+ pgroup.CreateChild("WarningLevel").SetValue("4");
|
|
|
+ pgroup.CreateChild("ConsolePause").SetValue("false");
|
|
|
+ pgroup.CreateChild("AllowUnsafeBlocks").SetValue("true");
|
|
|
+ pgroup.CreateChild("NoStdLib").SetValue("true");
|
|
|
+}
|
|
|
+
|
|
|
+void NETCSProject::CreateDebugPropertyGroup(XMLElement &projectRoot)
|
|
|
+{
|
|
|
+ XMLElement pgroup = projectRoot.CreateChild("PropertyGroup");
|
|
|
+ pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ");
|
|
|
+
|
|
|
+ pgroup.CreateChild("DebugSymbols").SetValue("true");
|
|
|
+ pgroup.CreateChild("DebugType").SetValue("full");
|
|
|
+ pgroup.CreateChild("Optimize").SetValue("false");
|
|
|
+ pgroup.CreateChild("OutputPath").SetValue(assemblyOutputPath_);
|
|
|
+ pgroup.CreateChild("DefineConstants").SetValue("DEBUG;");
|
|
|
+ pgroup.CreateChild("ErrorReport").SetValue("prompt");
|
|
|
+ pgroup.CreateChild("WarningLevel").SetValue("4");
|
|
|
+ pgroup.CreateChild("ConsolePause").SetValue("false");
|
|
|
+ pgroup.CreateChild("AllowUnsafeBlocks").SetValue("true");
|
|
|
+ pgroup.CreateChild("NoStdLib").SetValue("true");
|
|
|
+}
|
|
|
+
|
|
|
+void NETCSProject::CreateMainPropertyGroup(XMLElement& projectRoot)
|
|
|
+{
|
|
|
+ XMLElement pgroup = projectRoot.CreateChild("PropertyGroup");
|
|
|
+
|
|
|
+ // Configuration
|
|
|
+ XMLElement config = pgroup.CreateChild("Configuration");
|
|
|
+ config.SetAttribute("Condition", " '$(Configuration)' == '' ");
|
|
|
+ config.SetValue("Debug");
|
|
|
+
|
|
|
+ // Platform
|
|
|
+ XMLElement platform = pgroup.CreateChild("Platform");
|
|
|
+ platform.SetAttribute("Condition", " '$(Platform)' == '' ");
|
|
|
+ platform.SetValue("AnyCPU");
|
|
|
+
|
|
|
+ // ProjectGuid
|
|
|
+ XMLElement guid = pgroup.CreateChild("ProjectGuid");
|
|
|
+ guid.SetValue(projectGuid_);
|
|
|
+
|
|
|
+ // OutputType
|
|
|
+ XMLElement outputType = pgroup.CreateChild("OutputType");
|
|
|
+ outputType.SetValue(outputType_);
|
|
|
+
|
|
|
+ // RootNamespace
|
|
|
+ XMLElement rootNamespace = pgroup.CreateChild("RootNamespace");
|
|
|
+ rootNamespace.SetValue(rootNamespace_);
|
|
|
+
|
|
|
+ // AssemblyName
|
|
|
+ XMLElement assemblyName = pgroup.CreateChild("AssemblyName");
|
|
|
+ assemblyName.SetValue(assemblyName_);
|
|
|
+
|
|
|
+ // TargetFrameworkVersion
|
|
|
+ XMLElement targetFrameWork = pgroup.CreateChild("TargetFrameworkVersion");
|
|
|
+ targetFrameWork.SetValue("4.5");
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool NETCSProject::Generate()
|
|
|
+{
|
|
|
+ XMLElement project = xmlFile_->CreateRoot("Project");
|
|
|
+
|
|
|
+ project.SetAttribute("DefaultTargets", "Build");
|
|
|
+ project.SetAttribute("ToolsVersion", "4.0");
|
|
|
+ project.SetAttribute("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
|
|
+
|
|
|
+ CreateMainPropertyGroup(project);
|
|
|
+ CreateDebugPropertyGroup(project);
|
|
|
+ CreateReleasePropertyGroup(project);
|
|
|
+ CreateReferencesItemGroup(project);
|
|
|
+ CreateCompileItemGroup(project);
|
|
|
+
|
|
|
+ project.CreateChild("Import").SetAttribute("Project", "$(MSBuildBinPath)\\Microsoft.CSharp.targets");
|
|
|
+
|
|
|
+ String projectSource = xmlFile_->ToString();
|
|
|
+
|
|
|
+ NETSolution* solution = projectGen_->GetSolution();
|
|
|
+
|
|
|
+ String projectPath = solution->GetOutputPath() + name_ + ".csproj";
|
|
|
+
|
|
|
+ SharedPtr<File> output(new File(context_, projectPath, FILE_WRITE));
|
|
|
+ output->Write(projectSource.CString(), projectSource.Length());
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool NETCSProject::Load(const JSONValue& root)
|
|
|
+{
|
|
|
+
|
|
|
+ name_ = root["name"].GetString();
|
|
|
+ projectGuid_ = root["projectGuid"].GetString();
|
|
|
+ outputType_ = root["outputType"].GetString();
|
|
|
+ rootNamespace_ = root["rootNamespace"].GetString();
|
|
|
+ assemblyName_ = root["assemblyName"].GetString();
|
|
|
+ assemblyOutputPath_ = root["assemblyOutputPath"].GetString();
|
|
|
+ ReplacePathStrings(assemblyOutputPath_);
|
|
|
+
|
|
|
+ const JSONArray& references = root["references"].GetArray();
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < references.Size(); i++)
|
|
|
+ {
|
|
|
+ String reference = references[i].GetString();
|
|
|
+ ReplacePathStrings(reference);
|
|
|
+ references_.Push(reference);
|
|
|
+ }
|
|
|
+
|
|
|
+ const JSONArray& sources = root["sources"].GetArray();
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < sources.Size(); i++)
|
|
|
+ {
|
|
|
+ String source = sources[i].GetString();
|
|
|
+ ReplacePathStrings(source);
|
|
|
+ sourceFolders_.Push(AddTrailingSlash(source));
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+NETSolution::NETSolution(Context* context, NETProjectGen* projectGen) : NETProjectBase(context, projectGen)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+NETSolution::~NETSolution()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool NETSolution::Generate()
|
|
|
+{
|
|
|
+
|
|
|
+ String slnPath = outputPath_ + name_ + ".sln";
|
|
|
+
|
|
|
+ GenerateXamarinStudio(slnPath);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void NETSolution::GenerateXamarinStudio(const String &slnPath)
|
|
|
+{
|
|
|
+
|
|
|
+ String source = "Microsoft Visual Studio Solution File, Format Version 12.00\n";
|
|
|
+ source += "# Visual Studio 2012\n";
|
|
|
+
|
|
|
+ const Vector<SharedPtr<NETCSProject>>& projects = projectGen_->GetCSProjects();
|
|
|
+ for (unsigned i = 0; i < projects.Size(); i++)
|
|
|
+ {
|
|
|
+ NETCSProject* p = projects.At(i);
|
|
|
+
|
|
|
+ source += ToString("Project(\"{%s}\") = \"%s\", \"%s.csproj\", \"{%s}\"\n",
|
|
|
+ p->GetProjectGUID().CString(), p->GetName().CString(), p->GetName().CString(),
|
|
|
+ p->GetProjectGUID().CString());
|
|
|
+
|
|
|
+ source += "EndProject\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ source += "Global\n";
|
|
|
+ source += " GlobalSection(SolutionConfigurationPlatforms) = preSolution\n";
|
|
|
+ source += " Debug|Any CPU = Debug|Any CPU\n";
|
|
|
+ source += " Release|Any CPU = Release|Any CPU\n";
|
|
|
+ source += " EndGlobalSection\n";
|
|
|
+ source += " GlobalSection(ProjectConfigurationPlatforms) = postSolution\n";
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < projects.Size(); i++)
|
|
|
+ {
|
|
|
+ NETCSProject* p = projects.At(i);
|
|
|
+
|
|
|
+ source += ToString(" {%s}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n", p->GetProjectGUID().CString());
|
|
|
+ source += ToString(" {%s}.Debug|Any CPU.Build.0 = Debug|Any CPU\n", p->GetProjectGUID().CString());
|
|
|
+ source += ToString(" {%s}.Release|Any CPU.ActiveCfg = Release|Any CPU\n", p->GetProjectGUID().CString());
|
|
|
+ source += ToString(" {%s}.Release|Any CPU.Build.0 = Release|Any CPU\n", p->GetProjectGUID().CString());
|
|
|
+ }
|
|
|
+
|
|
|
+ source += " EndGlobalSection\n";
|
|
|
+
|
|
|
+ source += "EndGlobal\n";
|
|
|
+
|
|
|
+ SharedPtr<File> output(new File(context_, slnPath, FILE_WRITE));
|
|
|
+ output->Write(source.CString(), source.Length());
|
|
|
+ output->Close();
|
|
|
+}
|
|
|
+
|
|
|
+bool NETSolution::Load(const JSONValue& root)
|
|
|
+{
|
|
|
+ FileSystem* fs = GetSubsystem<FileSystem>();
|
|
|
+
|
|
|
+ name_ = root["name"].GetString();
|
|
|
+
|
|
|
+ outputPath_ = AddTrailingSlash(root["outputPath"].GetString());
|
|
|
+ ReplacePathStrings(outputPath_);
|
|
|
+
|
|
|
+ // TODO: use poco mkdirs
|
|
|
+ if (!fs->DirExists(outputPath_))
|
|
|
+ fs->CreateDir(outputPath_);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+NETProjectGen::NETProjectGen(Context* context) : Object(context)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+NETProjectGen::~NETProjectGen()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool NETProjectGen::Generate()
|
|
|
+{
|
|
|
+ solution_->Generate();
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < projects_.Size(); i++)
|
|
|
+ {
|
|
|
+ if (!projects_[i]->Generate())
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool NETProjectGen::LoadProject(const JSONValue &root)
|
|
|
+{
|
|
|
+
|
|
|
+ solution_ = new NETSolution(context_, this);
|
|
|
+
|
|
|
+ solution_->Load(root["solution"]);
|
|
|
+
|
|
|
+ const JSONValue& jprojects = root["projects"];
|
|
|
+
|
|
|
+ if (!jprojects.IsArray() || ! jprojects.Size())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < jprojects.Size(); i++)
|
|
|
+ {
|
|
|
+ const JSONValue& jproject = jprojects[i];
|
|
|
+
|
|
|
+ if (!jproject.IsObject())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ SharedPtr<NETCSProject> csProject(new NETCSProject(context_, this));
|
|
|
+
|
|
|
+ if (!csProject->Load(jproject))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ projects_.Push(csProject);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool NETProjectGen::LoadProject(const String& projectPath)
|
|
|
+{
|
|
|
+ SharedPtr<File> file(new File(context_));
|
|
|
+
|
|
|
+ if (!file->Open(projectPath))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ String json;
|
|
|
+ file->ReadText(json);
|
|
|
+
|
|
|
+ JSONValue jvalue;
|
|
|
+
|
|
|
+ if (!JSONFile::ParseJSON(json, jvalue))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return LoadProject(jvalue);
|
|
|
+}
|
|
|
+
|
|
|
+}
|