Browse Source

Adding support for Android C# platform on Atomic Editor binary builds: ./Build_AtomicEditor.sh --with-android

Josh Engebretson 9 years ago
parent
commit
61dc38e8e4

+ 25 - 25
Build/Scripts/BuildAndroid.js

@@ -8,40 +8,40 @@ var buildDir = host.artifactsRoot + "Build/Android/";
 
 
 namespace('build', function() {
 namespace('build', function() {
 
 
-  task('android_native', {
-    async: true
-  }, function() {
+    task('android_native', {
+        async: true
+    }, function() {
 
 
-    // Clean build
-    common.cleanCreateDir(buildDir);
+        // Clean build
+        common.cleanCreateDir(buildDir);
 
 
-    process.chdir(buildDir);
+        process.chdir(buildDir);
 
 
-    var cmds = [];
+        var cmds = [];
 
 
-    if (os.platform() == "win32") {
-      cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAndroid.bat");
-    }
-    else {
-      cmds.push("cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../../");
-      cmds.push("make -j4");
-    }
+        if (os.platform() == "win32") {
+            cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAndroid.bat");
+        }
+        else {
+            cmds.push("cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=../../../Build/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../../");
+            cmds.push("make -j4");
+        }
 
 
-    jake.exec(cmds, function() {
+        jake.exec(cmds, function() {
 
 
-      var editorAppFolder = host.artifactsRoot + (os.platform() == "win32" ? "AtomicEditor/" : "AtomicEditor/AtomicEditor.app/");
+            var editorAppFolder = host.artifactsRoot + (os.platform() == "win32" ? "AtomicEditor/" : "AtomicEditor/AtomicEditor.app/");
 
 
-      // Install Deployment
-      fs.copySync(buildDir + "Source/AtomicPlayer/Application/libAtomicPlayer.so",
-        editorAppFolder + "Resources/ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so");
+            // Install Deployment
+            fs.copySync(buildDir + "Source/AtomicPlayer/Application/libAtomicPlayer.so",
+            editorAppFolder + "Contents/Resources/ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so");
 
 
-      complete();
+            complete();
 
 
-    }, {
-      printStdout: true,
-      breakOnError : false
-    });
+        }, {
+            printStdout: true,
+            breakOnError : false
+        });
 
 
-  });
+    });
 
 
 }); // end of build namespace
 }); // end of build namespace

+ 87 - 67
Build/Scripts/BuildMac.js

@@ -6,108 +6,128 @@ var atomicRoot = host.atomicRoot;
 
 
 var buildDir = host.artifactsRoot + "Build/Mac/";
 var buildDir = host.artifactsRoot + "Build/Mac/";
 var editorAppFolder = host.artifactsRoot + "/AtomicEditor/AtomicEditor.app/";
 var editorAppFolder = host.artifactsRoot + "/AtomicEditor/AtomicEditor.app/";
+var resourceDest = editorAppFolder + "/Contents/Resources/"
 
 
 namespace('build', function() {
 namespace('build', function() {
 
 
-// Builds a standalone Atomic Editor, which can be distributed out of build tree
-task('atomiceditor', {
-  async: true
-}, function() {
+    // Builds a standalone Atomic Editor, which can be distributed out of build tree
+    task('atomiceditor', {
+        async: true
+    }, function(android) {
 
 
-  // Clean build
-  var cleanBuild = true;
-  if (cleanBuild) {
-    common.cleanCreateDir(buildDir);
-    common.cleanCreateDir(editorAppFolder);
-    common.cleanCreateDir(host.getGenScriptRootDir("MACOSX"));
-  }
+        android = android == "android" ? true : false;
 
 
-  var buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
+        // Clean build
+        var cleanBuild = true;
+        if (cleanBuild) {
+            common.cleanCreateDir(host.artifactsRoot + "AtomicNET/");
+            common.cleanCreateDir(buildDir);
+            common.cleanCreateDir(editorAppFolder);
+            common.cleanCreateDir(host.getGenScriptRootDir());
+        }
 
 
-  process.chdir(buildDir);
+        var buildAtomicNET = spawnSync("which", ["xbuild"]).status == 1 ? false : true;
 
 
-  var cmds = [];
+        process.chdir(buildDir);
 
 
-  cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode");
-  cmds.push("xcodebuild -target AtomicEditor -target AtomicPlayer -target AtomicNETNative -configuration Release -parallelizeTargets -jobs 4")
+        var cmds = [];
 
 
-  if (buildAtomicNET)
-    cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json MACOSX Release");
+        cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode");
+        cmds.push("xcodebuild -target AtomicEditor -target AtomicPlayer -target AtomicNETNative -configuration Release -parallelizeTargets -jobs 4")
 
 
-  jake.exec(cmds, function() {
+        if (buildAtomicNET)
+            cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + (android ? "ANDROID" : "WINDOWS") + " Release");
 
 
-    fs.copySync(buildDir + "Source/AtomicEditor/Release/AtomicEditor.app", editorAppFolder);
+        function copyAtomicNET() {
 
 
-    var resourceDest = editorAppFolder + "/Contents/Resources/"
+            if (!buildAtomicNET)
+                return;
 
 
-    // We need some resources to run
-    fs.copySync(atomicRoot + "Resources/CoreData",
-      resourceDest + "CoreData");
+            fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
+            resourceDest + "ToolData/AtomicNET/Release");
 
 
-    fs.copySync(atomicRoot + "Resources/PlayerData",
-      resourceDest + "PlayerData");
+            fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
+            resourceDest + "ToolData/AtomicNET/Build/Projects/AtomicProject.json");
 
 
-    fs.copySync(atomicRoot + "Data/AtomicEditor",
-      resourceDest + "ToolData");
+        }
 
 
-    fs.copySync(atomicRoot + "Resources/EditorData",
-      resourceDest + "EditorData");
 
 
-    fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
-      resourceDest + "EditorData/AtomicEditor/EditorScripts");
+        jake.exec(cmds, function() {
 
 
-    // copy the mac player binary to deployment
-    var playerBinary =  buildDir +  "Source/AtomicPlayer/Application/Release/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
+            fs.copySync(buildDir + "Source/AtomicEditor/Release/AtomicEditor.app", editorAppFolder);
 
 
-    fs.copySync(playerBinary,
-      resourceDest + "ToolData/Deployment/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
+            // We need some resources to run
+            fs.copySync(atomicRoot + "Resources/CoreData",
+            resourceDest + "CoreData");
 
 
-    // AtomicNET
-    if (buildAtomicNET) {
-        
-      fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
-        resourceDest + "ToolData/AtomicNET/Release");
+            fs.copySync(atomicRoot + "Resources/PlayerData",
+            resourceDest + "PlayerData");
 
 
-      fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
-        resourceDest + "ToolData/AtomicNET/Build/Projects/AtomicProject.json");
-    }
+            fs.copySync(atomicRoot + "Data/AtomicEditor",
+            resourceDest + "ToolData");
 
 
-    console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
+            fs.copySync(atomicRoot + "Resources/EditorData",
+            resourceDest + "EditorData");
 
 
-    complete();
+            fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
+            resourceDest + "EditorData/AtomicEditor/EditorScripts");
 
 
-  }, {
-    printStdout: true
-  });
+            // copy the mac player binary to deployment
+            var playerBinary =  buildDir +  "Source/AtomicPlayer/Application/Release/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
 
 
-});
+            fs.copySync(playerBinary, resourceDest + "ToolData/Deployment/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
 
 
-// Generate a XCode Workspace
-task('genxcode', {
-  async: true
-}, function() {
+            if (android) {
 
 
-  var xcodeRoot = path.resolve(atomicRoot, "") + "-XCode";
+                var androidNativeTask = jake.Task['build:android_native'];
 
 
-  if (!fs.existsSync(xcodeRoot)) {
-      jake.mkdirP(xcodeRoot);
-  }
+                androidNativeTask.addListener('complete', function () {
+                    copyAtomicNET();
+                    console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
+                    complete();
+                });
 
 
-  process.chdir(xcodeRoot);
+                androidNativeTask.invoke();
 
 
-  var cmds = [];
+            }
+            else {
+                copyAtomicNET();
+                console.log("\n\nAtomic Editor build to " + editorAppFolder + "\n\n");
+                complete();
+            }
 
 
-  cmds.push("cmake ../AtomicGameEngine -DATOMIC_DEV_BUILD=1 -G Xcode");
+        }, {
+            printStdout: true
+        });
 
 
-  jake.exec(cmds, function() {
+    });
 
 
-    complete();
+    // Generate a XCode Workspace
+    task('genxcode', {
+        async: true
+    }, function() {
 
 
-  }, {
-    printStdout: true
-  });
+        var xcodeRoot = path.resolve(atomicRoot, "") + "-XCode";
 
 
-});
+        if (!fs.existsSync(xcodeRoot)) {
+            jake.mkdirP(xcodeRoot);
+        }
+
+        process.chdir(xcodeRoot);
+
+        var cmds = [];
+
+        cmds.push("cmake ../AtomicGameEngine -DATOMIC_DEV_BUILD=1 -G Xcode");
+
+        jake.exec(cmds, function() {
+
+            complete();
+
+        }, {
+            printStdout: true
+        });
+
+    });
 
 
 
 
 });// end of build namespace
 });// end of build namespace

+ 79 - 78
Build/Scripts/BuildWindows.js

@@ -8,119 +8,120 @@ var editorAppFolder = host.artifactsRoot + "AtomicEditor/";
 
 
 namespace('build', function() {
 namespace('build', function() {
 
 
-  // Builds a standalone Atomic Editor, which can be distributed out of build tree
-  task('atomiceditor', {
-    async: true
-}, function(android) {
+    // Builds a standalone Atomic Editor, which can be distributed out of build tree
+    task('atomiceditor', {
+        async: true
+    }, function(android) {
 
 
-    android = android == "android" ? true : false;
+        android = android == "android" ? true : false;
 
 
-    // Clean build
-    var cleanBuild = true;
-    if (cleanBuild) {
-      common.cleanCreateDir(buildDir);
-      common.cleanCreateDir(editorAppFolder);
-      common.cleanCreateDir(host.getGenScriptRootDir("WINDOWS"));
-    }
+        // Clean build
+        var cleanBuild = true;
+        if (cleanBuild) {
+            common.cleanCreateDir(host.artifactsRoot + "AtomicNET/");
+            common.cleanCreateDir(buildDir);
+            common.cleanCreateDir(editorAppFolder);
+            common.cleanCreateDir(host.getGenScriptRootDir());
+        }
 
 
-    process.chdir(buildDir);
+        process.chdir(buildDir);
 
 
-    var cmds = [];
+        var cmds = [];
 
 
-    // Build the AtomicEditor
-    cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAtomicEditor.bat");
-    cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + (android ? "ANDROID" : "WINDOWS") + " Release");
+        // Build the AtomicEditor
+        cmds.push(atomicRoot + "Build/Scripts/Windows/CompileAtomicEditor.bat");
+        cmds.push(host.atomicTool + " net compile " + atomicRoot + "Script/AtomicNET/AtomicNETProject.json " + (android ? "ANDROID" : "WINDOWS") + " Release");
 
 
-    function copyAtomicNET() {
+        function copyAtomicNET() {
 
 
-        fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
-          editorAppFolder + "Resources/ToolData/AtomicNET/Release");
+            fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
+            editorAppFolder + "Resources/ToolData/AtomicNET/Release");
 
 
-        fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
-          editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
+            fs.copySync(atomicRoot + "Script/AtomicNET/AtomicProject.json",
+            editorAppFolder + "Resources/ToolData/AtomicNET/Build/Projects/AtomicProject.json");
 
 
-    }
+        }
 
 
-    jake.exec(cmds, function() {
+        jake.exec(cmds, function() {
 
 
-      // Copy the Editor binaries
-      fs.copySync(buildDir + "Source/AtomicEditor/Release",
-        host.artifactsRoot + "AtomicEditor");
+            // Copy the Editor binaries
+            fs.copySync(buildDir + "Source/AtomicEditor/Release",
+            host.artifactsRoot + "AtomicEditor");
 
 
-      // We need some resources to run
-      fs.copySync(atomicRoot + "Resources/CoreData",
-        editorAppFolder + "Resources/CoreData");
+            // We need some resources to run
+            fs.copySync(atomicRoot + "Resources/CoreData",
+            editorAppFolder + "Resources/CoreData");
 
 
-      fs.copySync(atomicRoot + "Resources/PlayerData",
-        editorAppFolder + "Resources/PlayerData");
+            fs.copySync(atomicRoot + "Resources/PlayerData",
+            editorAppFolder + "Resources/PlayerData");
 
 
-      fs.copySync(atomicRoot + "Data/AtomicEditor",
-        editorAppFolder + "Resources/ToolData");
+            fs.copySync(atomicRoot + "Data/AtomicEditor",
+            editorAppFolder + "Resources/ToolData");
 
 
-      fs.copySync(atomicRoot + "Resources/EditorData",
-        editorAppFolder + "Resources/EditorData");
+            fs.copySync(atomicRoot + "Resources/EditorData",
+            editorAppFolder + "Resources/EditorData");
 
 
-      fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
-        editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
+            fs.copySync(atomicRoot + "Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts",
+            editorAppFolder + "Resources/EditorData/AtomicEditor/EditorScripts");
 
 
-      fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/AtomicPlayer.exe",
-        editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/AtomicPlayer.exe");
+            fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/AtomicPlayer.exe",
+            editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/AtomicPlayer.exe");
 
 
-      fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/D3DCompiler_47.dll",
-        editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
+            fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/D3DCompiler_47.dll",
+            editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
 
 
-      if (android) {
+            if (android) {
 
 
-          var androidNativeTask = jake.Task['build:android_native'];
+                var androidNativeTask = jake.Task['build:android_native'];
 
 
-          androidNativeTask.addListener('complete', function () {
-              copyAtomicNET();
-              console.log("\nAtomic Editor build to ", editorAppFolder);
-              complete();
-          });
+                androidNativeTask.addListener('complete', function () {
+                    copyAtomicNET();
+                    console.log("\nAtomic Editor build to ", editorAppFolder);
+                    complete();
+                });
 
 
-          androidNativeTask.invoke();
+                androidNativeTask.invoke();
 
 
-      }
-      else {
-          copyAtomicNET();
-          console.log("\nAtomic Editor build to ", editorAppFolder);
-          complete();
-      }
+            }
+            else {
+                copyAtomicNET();
+                console.log("\nAtomic Editor build to ", editorAppFolder);
+                complete();
+            }
+
+        }, {
+            printStdout: true
+        });
 
 
-    }, {
-      printStdout: true
     });
     });
 
 
-  });
+    // Generate a Visual Studio 2015 solution
+    task('genvs2015', {
+        async: true
+    }, function(devBuild) {
+        if (devBuild === undefined)
+        devBuild = 1;
 
 
-  // Generate a Visual Studio 2015 solution
-  task('genvs2015', {
-    async: true
-  }, function(devBuild) {
-    if (devBuild === undefined)
-      devBuild = 1;
+        var slnRoot = path.resolve(atomicRoot, "") + "-VS2015\\";
 
 
-    var slnRoot = path.resolve(atomicRoot, "") + "-VS2015\\";
+        if (!fs.existsSync(slnRoot)) {
+            jake.mkdirP(slnRoot);
+        }
 
 
-    if (!fs.existsSync(slnRoot)) {
-        jake.mkdirP(slnRoot);
-    }
+        process.chdir(slnRoot);
 
 
-    process.chdir(slnRoot);
+        var cmds = [];
 
 
-    var cmds = [];
+        cmds.push(atomicRoot + "Build/Scripts/Windows/GenerateVS2015.bat " + atomicRoot + " " + devBuild);
 
 
-    cmds.push(atomicRoot + "Build/Scripts/Windows/GenerateVS2015.bat " + atomicRoot + " " + devBuild);
+        jake.exec(cmds, function() {
 
 
-    jake.exec(cmds, function() {
+            complete();
 
 
-      complete();
+        }, {
+            printStdout: true
+        });
 
 
-    }, {
-      printStdout: true
     });
     });
 
 
-  });
-
 }); // end of build namespace
 }); // end of build namespace

+ 1 - 1
Build_AtomicEditor.bat

@@ -20,7 +20,7 @@ if "%ATOMICEDITOR_ANDROID%" == "YES" (
     @echo:
     @echo:
     echo Building Atomic Editor with Android support
     echo Building Atomic Editor with Android support
     @echo:
     @echo:
-    set ATOMICEDITOR_BUILD_CMD=!ATOMICEDITOR_BUILD_CMD!["android"]
+    set ATOMICEDITOR_BUILD_CMD=!ATOMICEDITOR_BUILD_CMD![android]
 )
 )
 
 
 @echo:
 @echo:

+ 17 - 3
Build_AtomicEditor.sh

@@ -1,9 +1,23 @@
 #!/usr/bin/env sh
 #!/usr/bin/env sh
 
 
+buildcmd="build:atomiceditor"
+
+for var in "$@"
+do
+    if [ $var == "--with-android" ]; then
+        if [ "$ANDROID_NDK" == "" ]; then
+            echo "\n\nANDROID_NDK environment variable not set, exiting\n\n"
+            exit 1
+        fi
+        echo "\n\nBuilding Atomic Editor with Android support\n\n"
+        buildcmd+="[android]"
+    fi
+done
+
 if [ "$(uname)" = "Darwin" ]; then
 if [ "$(uname)" = "Darwin" ]; then
-    ./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
 elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then
 elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then
-    ./Build/Linux/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Linux/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
 elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then
 elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then
-    ./Build/Windows/node/node.exe ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Windows/node/node.exe ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js $buildcmd
 fi
 fi

+ 7 - 2
Source/Atomic/IO/FileSystem.cpp

@@ -439,7 +439,7 @@ bool FileSystem::SystemOpen(const String& fileName, const String& mode)
     {
     {
         // ATOMIC BEGIN
         // ATOMIC BEGIN
         // allow opening of http and file urls
         // allow opening of http and file urls
-        if (!fileName.StartsWith("http://") && !fileName.StartsWith("https://") && !fileName.StartsWith("file://"))        
+        if (!fileName.StartsWith("http://") && !fileName.StartsWith("https://") && !fileName.StartsWith("file://"))
             if (!FileExists(fileName) && !DirExists(fileName))
             if (!FileExists(fileName) && !DirExists(fileName))
             {
             {
                 ATOMIC_LOGERROR("File or directory " + fileName + " not found");
                 ATOMIC_LOGERROR("File or directory " + fileName + " not found");
@@ -1261,6 +1261,8 @@ String GetSanitizedPath(const String& path)
     String sanitized = GetInternalPath(path);
     String sanitized = GetInternalPath(path);
     StringVector parts = sanitized.Split('/');
     StringVector parts = sanitized.Split('/');
 
 
+    bool hasTrailingSlash = path.EndsWith("/") || path.EndsWith("\\");
+
 #ifndef ATOMIC_PLATFORM_WINDOWS
 #ifndef ATOMIC_PLATFORM_WINDOWS
 
 
     bool absolute = IsAbsolutePath(path);
     bool absolute = IsAbsolutePath(path);
@@ -1274,6 +1276,9 @@ String GetSanitizedPath(const String& path)
 
 
 #endif
 #endif
 
 
+    if (hasTrailingSlash)
+        sanitized += "/";
+
     return sanitized;
     return sanitized;
 
 
 }
 }
@@ -1305,7 +1310,7 @@ bool GetRelativePath(const String& fromPath, const String& toPath, String& outpu
     for (startIdx = 0; startIdx < toParts.Size(); startIdx++)
     for (startIdx = 0; startIdx < toParts.Size(); startIdx++)
     {
     {
         if (startIdx >= fromParts.Size() || fromParts[startIdx] != toParts[startIdx])
         if (startIdx >= fromParts.Size() || fromParts[startIdx] != toParts[startIdx])
-            break;       
+            break;
     }
     }
 
 
     if (startIdx == toParts.Size())
     if (startIdx == toParts.Size())

+ 20 - 15
Source/ToolCore/NETTools/NETProjectGen.cpp

@@ -60,6 +60,9 @@ namespace ToolCore
 
 
 		String atomicProjectPath = projectGen_->GetAtomicProjectPath();
 		String atomicProjectPath = projectGen_->GetAtomicProjectPath();
 
 
+		// TODO: This is the cause of a bunch of "GetSanitizedPath" calls,
+		// It should be removed, and the few places in csproj/sln that need backslash
+		// adjusted there
 		atomicProjectPath.Replace("/", "\\");
 		atomicProjectPath.Replace("/", "\\");
 
 
 		if (atomicProjectPath.Length())
 		if (atomicProjectPath.Length())
@@ -236,7 +239,7 @@ namespace ToolCore
 				}
 				}
 
 
 				if (platform.Length())
 				if (platform.Length())
-				{					
+				{
 					String atomicNETAssembly = tenv->GetAtomicNETCoreAssemblyDir() + ToString("%s/%s.dll", platform.CString(), ref.CString());
 					String atomicNETAssembly = tenv->GetAtomicNETCoreAssemblyDir() + ToString("%s/%s.dll", platform.CString(), ref.CString());
 					xref = igroup.CreateChild("Reference");
 					xref = igroup.CreateChild("Reference");
 					xref.SetAttribute("Include", atomicNETAssembly);
 					xref.SetAttribute("Include", atomicNETAssembly);
@@ -526,7 +529,7 @@ namespace ToolCore
 
 
 		if (SupportsDesktop())
 		if (SupportsDesktop())
 		{
 		{
-			// AtomicNETNative 
+			// AtomicNETNative
 
 
 			XMLElement atomicNETNativeDLL = itemGroup.CreateChild("None");
 			XMLElement atomicNETNativeDLL = itemGroup.CreateChild("None");
 
 
@@ -548,7 +551,7 @@ namespace ToolCore
 #endif
 #endif
 
 
 #ifdef ATOMIC_DEV_BUILD
 #ifdef ATOMIC_DEV_BUILD
-			
+
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/" + platform + "/" + filename;
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/" + platform + "/" + filename;
 #else
 #else
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/" + platform + "/" + filename;
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/" + platform + "/" + filename;
@@ -624,7 +627,7 @@ namespace ToolCore
 			// TODO: more than armeabi-v7a (which this is)
 			// TODO: more than armeabi-v7a (which this is)
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/Android/libAtomicNETNative.so";
 			String nativePath = AddTrailingSlash(tenv->GetAtomicNETRootDir()) + config + "/Native/Android/libAtomicNETNative.so";
 
 
-			XMLElement nativeLibrary =  projectRoot.CreateChild("ItemGroup").CreateChild("AndroidNativeLibrary"); 
+			XMLElement nativeLibrary =  projectRoot.CreateChild("ItemGroup").CreateChild("AndroidNativeLibrary");
 			nativeLibrary.SetAttribute("Include", nativePath);
 			nativeLibrary.SetAttribute("Include", nativePath);
 
 
 			nativeLibrary.CreateChild("Link").SetValue("Libs\\armeabi-v7a\\libAtomicNETNative.so");
 			nativeLibrary.CreateChild("Link").SetValue("Libs\\armeabi-v7a\\libAtomicNETNative.so");
@@ -695,8 +698,8 @@ namespace ToolCore
 	bool NETCSProject::GetRelativeProjectPath(const String& fromPath, const String& toPath, String& output)
 	bool NETCSProject::GetRelativeProjectPath(const String& fromPath, const String& toPath, String& output)
 	{
 	{
 		String path = fromPath;
 		String path = fromPath;
-
 		ReplacePathStrings(path);
 		ReplacePathStrings(path);
+		path = GetSanitizedPath(path);
 
 
 		String relativePath;
 		String relativePath;
 
 
@@ -772,7 +775,7 @@ namespace ToolCore
 				{
 				{
 					pgroup.CreateChild("ProjectTypeGuids").SetValue("{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}");
 					pgroup.CreateChild("ProjectTypeGuids").SetValue("{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}");
 				}
 				}
-				
+
 				pgroup.CreateChild("AndroidUseLatestPlatformSdk").SetValue("True");
 				pgroup.CreateChild("AndroidUseLatestPlatformSdk").SetValue("True");
 
 
 				if (!androidApplication_)
 				if (!androidApplication_)
@@ -795,14 +798,15 @@ namespace ToolCore
 
 
 					String manifestSourceFile = "$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/Android/Properties/AndroidManifest.xml";
 					String manifestSourceFile = "$ATOMIC_PROJECT_ROOT$/Project/AtomicNET/Platforms/Android/Properties/AndroidManifest.xml";
 					ReplacePathStrings(manifestSourceFile);
 					ReplacePathStrings(manifestSourceFile);
+					manifestSourceFile = GetSanitizedPath(manifestSourceFile);
 
 
 					if (fileSystem->FileExists(manifestSourceFile))
 					if (fileSystem->FileExists(manifestSourceFile))
 					{
 					{
-						String manifestDest = projectPath_ + "Properties/";
+						String manifestDest = GetSanitizedPath(projectPath_ + "Properties/");
 
 
 						if (!fileSystem->DirExists(manifestDest))
 						if (!fileSystem->DirExists(manifestDest))
 						{
 						{
-							fileSystem->CreateDirs(projectGen_->GetAtomicProjectPath(), ToString("AtomicNET/Solution/%s/Properties/", name_.CString()));
+							fileSystem->CreateDirs(GetSanitizedPath(projectGen_->GetAtomicProjectPath()), ToString("/AtomicNET/Solution/%s/Properties/", name_.CString()));
 						}
 						}
 
 
 						if (fileSystem->DirExists(manifestDest))
 						if (fileSystem->DirExists(manifestDest))
@@ -816,11 +820,11 @@ namespace ToolCore
 						{
 						{
 							ATOMIC_LOGERRORF("Unable to create folder %s for AndroidManifest.xml", manifestDest.CString());
 							ATOMIC_LOGERRORF("Unable to create folder %s for AndroidManifest.xml", manifestDest.CString());
 						}
 						}
-						
+
 					}
 					}
 					else
 					else
 					{
 					{
-						ATOMIC_LOGERROR("No AndroidManifest.xml, project will not deploy");
+						ATOMIC_LOGERRORF("No AndroidManifest.xml, project will not deploy (%s)", manifestSourceFile.CString());
 					}
 					}
 
 
 					String relativePath;
 					String relativePath;
@@ -833,7 +837,7 @@ namespace ToolCore
 					{
 					{
 						ATOMIC_LOGERROR("Unabled to get relative path for AndroidResgenFile");
 						ATOMIC_LOGERROR("Unabled to get relative path for AndroidResgenFile");
 					}
 					}
-					
+
 					pgroup.CreateChild("GenerateSerializationAssemblies").SetValue("Off");
 					pgroup.CreateChild("GenerateSerializationAssemblies").SetValue("Off");
 				}
 				}
 
 
@@ -1111,10 +1115,11 @@ namespace ToolCore
 		assemblyName_ = root["assemblyName"].GetString();
 		assemblyName_ = root["assemblyName"].GetString();
 		assemblyOutputPath_ = root["assemblyOutputPath"].GetString();
 		assemblyOutputPath_ = root["assemblyOutputPath"].GetString();
 		ReplacePathStrings(assemblyOutputPath_);
 		ReplacePathStrings(assemblyOutputPath_);
+		assemblyOutputPath_ = GetSanitizedPath(assemblyOutputPath_);
 
 
 		assemblySearchPaths_ = root["assemblySearchPaths"].GetString();
 		assemblySearchPaths_ = root["assemblySearchPaths"].GetString();
-
 		ReplacePathStrings(assemblySearchPaths_);
 		ReplacePathStrings(assemblySearchPaths_);
+		assemblySearchPaths_ = GetSanitizedPath(assemblySearchPaths_);
 
 
 		const JSONArray& platforms = root["platforms"].GetArray();
 		const JSONArray& platforms = root["platforms"].GetArray();
 
 
@@ -1311,7 +1316,7 @@ namespace ToolCore
 							source += ToString("        %s\\%s.projitems*{%s}*SharedItemsImports = 4\n", p->name_.CString(), p->name_.CString(), p2->projectGuid_.CString());
 							source += ToString("        %s\\%s.projitems*{%s}*SharedItemsImports = 4\n", p->name_.CString(), p->name_.CString(), p2->projectGuid_.CString());
 						}
 						}
 					}
 					}
-						
+
 				}
 				}
 
 
 
 
@@ -1574,7 +1579,7 @@ namespace ToolCore
 			atomicProjectPath_ = AddTrailingSlash(atomicProjectPath);
 			atomicProjectPath_ = AddTrailingSlash(atomicProjectPath);
 		}
 		}
 
 
-		// Do we have a loaded project?  
+		// Do we have a loaded project?
 		if (Project* project = tsystem->GetProject())
 		if (Project* project = tsystem->GetProject())
 		{
 		{
 			// If so, use loaded project settings
 			// If so, use loaded project settings
@@ -1645,7 +1650,7 @@ namespace ToolCore
 #else
 #else
 		return LoadProject(jvalue);
 		return LoadProject(jvalue);
 #endif
 #endif
-		
+
 	}
 	}
 
 
 	void NETProjectGen::SetSupportedPlatforms(const StringVector& platforms)
 	void NETProjectGen::SetSupportedPlatforms(const StringVector& platforms)