forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			749 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			749 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
import haxe.io.Eof;
 | 
						|
import sys.io.Process;
 | 
						|
import sys.FileSystem;
 | 
						|
import BuildTool;
 | 
						|
 | 
						|
class Setup
 | 
						|
{
 | 
						|
   static function findAndroidNdkRoot(defines: Map<String,String>, inBaseVersion:Int):String
 | 
						|
   {
 | 
						|
      var bestVersion = 0.0;
 | 
						|
      var result:String = null;
 | 
						|
 | 
						|
      var ndkDir = defines.get("ANDROID_NDK_DIR");
 | 
						|
      if (ndkDir!=null)
 | 
						|
      {
 | 
						|
         Log.v("Looking in ANDROID_NDK_DIR " + ndkDir);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         Log.v("ANDROID_NDK_DIR not set");
 | 
						|
         if (BuildTool.isMac)
 | 
						|
         {
 | 
						|
            var lib = defines.get("HOME") + "/Library/Android/sdk/ndk";
 | 
						|
            if (FileSystem.exists(lib))
 | 
						|
            {
 | 
						|
               Log.v("trying default " + lib);
 | 
						|
               ndkDir = lib;
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      if (ndkDir!=null)
 | 
						|
      {
 | 
						|
        ndkDir = ndkDir.split("\\").join("/");
 | 
						|
        var files:Array<String> = null;
 | 
						|
        var checkFiles:Bool = true;
 | 
						|
        try
 | 
						|
        {
 | 
						|
             files = FileSystem.readDirectory(ndkDir);
 | 
						|
        }
 | 
						|
        catch (e:Dynamic)
 | 
						|
        {
 | 
						|
             Log.warn('ANDROID_NDK_DIR "$ndkDir" does not point to a valid directory');
 | 
						|
             checkFiles=false;
 | 
						|
        }
 | 
						|
        if (checkFiles)
 | 
						|
          for (file in files)
 | 
						|
          {
 | 
						|
             file = file.split("\\").join("/");
 | 
						|
             var version = getNdkVersion(ndkDir + "/" + file);
 | 
						|
             if (inBaseVersion==0 || Std.int(version)==inBaseVersion)
 | 
						|
             {
 | 
						|
                if (version>bestVersion)
 | 
						|
                {
 | 
						|
                   bestVersion = version;
 | 
						|
                   result = ndkDir + "/" + file;
 | 
						|
                }
 | 
						|
             }
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
      Log.v("Looking in ANDROID_SDK/ndk-bundle");
 | 
						|
      if (defines.exists("ANDROID_SDK"))
 | 
						|
      {
 | 
						|
        Log.v("checks default ndk-bundle in android sdk");
 | 
						|
        var ndkBundle = defines.get("ANDROID_SDK")+"/ndk-bundle";
 | 
						|
        ndkBundle = ndkBundle.split("\\").join("/");
 | 
						|
        var version = getNdkVersion(ndkBundle);
 | 
						|
        if (version>bestVersion && (inBaseVersion==0 || inBaseVersion==Std.int(version)) )
 | 
						|
        {
 | 
						|
           Log.v("Using default ndk-bundle in android sdk");
 | 
						|
           result = ndkBundle;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return result;
 | 
						|
   }
 | 
						|
 | 
						|
   static public function getNdkVersion(inDirName:String):Float
 | 
						|
   {
 | 
						|
      Log.v("Try to get version from source.properties");
 | 
						|
      var src = toPath(inDirName+"/source.properties");
 | 
						|
      if (sys.FileSystem.exists(src))
 | 
						|
      {
 | 
						|
         var fin = sys.io.File.read(src, false);
 | 
						|
         try
 | 
						|
         {
 | 
						|
            while (true)
 | 
						|
            {
 | 
						|
               var str = fin.readLine();
 | 
						|
               var split = str.split ("=");
 | 
						|
               var name = StringTools.trim(split[0]);
 | 
						|
               if (name == "Pkg.Revision")
 | 
						|
               {
 | 
						|
                  var revision = StringTools.trim(split[1]);
 | 
						|
                  var split2 = revision.split( "." );
 | 
						|
                  var result:Float = 1.0 * Std.parseInt(split2[0]) + 0.001 * Std.parseInt(split2[1]);
 | 
						|
                  if (result>=8)
 | 
						|
                  {
 | 
						|
                     Log.v('Deduced NDK version '+result+' from "$inDirName"/source.properties');
 | 
						|
                     fin.close();
 | 
						|
                     return result;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
         catch (e:haxe.io.Eof)
 | 
						|
         {
 | 
						|
            Log.v('Could not deduce NDK version from "$inDirName"/source.properties');
 | 
						|
         }
 | 
						|
         fin.close();
 | 
						|
      }
 | 
						|
 | 
						|
      var dir = inDirName.split("\\").join("/");
 | 
						|
      Log.v('Try to get version from directory name "$dir"');
 | 
						|
      var extract_version = ~/\/?(android-ndk-)?r(\d+)([a-z]?)$/;
 | 
						|
      if (extract_version.match(dir))
 | 
						|
      {
 | 
						|
         var major:Int = Std.parseInt( extract_version.matched(2) );
 | 
						|
         var result:Float = 1.0 * major;
 | 
						|
         var minor = extract_version.matched(3);
 | 
						|
         if (minor!=null && minor.length>0)
 | 
						|
            result += 0.001 * (minor.toLowerCase().charCodeAt(0)-'a'.code);
 | 
						|
         return result;
 | 
						|
      }
 | 
						|
 | 
						|
      Log.v('Could not deduce NDK version from "$inDirName" - assuming 8');
 | 
						|
      return 8;
 | 
						|
   }
 | 
						|
 | 
						|
   public static function initHXCPPConfig(ioDefines:Hash<String>)
 | 
						|
   {
 | 
						|
      var env = Sys.environment();
 | 
						|
      // If the user has set it themselves, they mush know what they are doing...
 | 
						|
      if (env.exists("HXCPP_CONFIG"))
 | 
						|
         return;
 | 
						|
 | 
						|
      var home = "";
 | 
						|
      if (env.exists("HOME"))
 | 
						|
         home = env.get("HOME");
 | 
						|
      else if (env.exists("USERPROFILE"))
 | 
						|
         home = env.get("USERPROFILE");
 | 
						|
      else
 | 
						|
      {
 | 
						|
         Log.warn("No $HOME variable set, \".hxcpp_config.xml\" might be missing");
 | 
						|
         //Sys.println("Warning: No 'HOME' variable set - .hxcpp_config.xml might be missing.");
 | 
						|
         return;
 | 
						|
      }
 | 
						|
 | 
						|
      ioDefines.set("HXCPP_HOME", home);
 | 
						|
 | 
						|
      var  config = toPath(home+"/.hxcpp_config.xml");
 | 
						|
      ioDefines.set("HXCPP_CONFIG",config);
 | 
						|
 | 
						|
      if (BuildTool.HXCPP!="")
 | 
						|
      {
 | 
						|
         var src = toPath(BuildTool.HXCPP + "/toolchain/example.hxcpp_config.xml");
 | 
						|
         if (!sys.FileSystem.exists(config))
 | 
						|
         {
 | 
						|
            try
 | 
						|
            {
 | 
						|
               Log.info("", "Copying HXCPP config \"" + src + "\" to \"" + config + "\"");
 | 
						|
               sys.io.File.copy(src,config);
 | 
						|
            }
 | 
						|
            catch(e:Dynamic)
 | 
						|
            {
 | 
						|
               Log.warn("Could not create HXCPP config \"" + config + "\"");
 | 
						|
               //Sys.println("Warning : could not create config: " + config );
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   public static function setupMingw(ioDefines:Hash<String>)
 | 
						|
   {
 | 
						|
      // Setup MINGW_ROOT or fail
 | 
						|
      if (!ioDefines.exists("MINGW_ROOT"))
 | 
						|
      {
 | 
						|
 | 
						|
         var haxelib = PathManager.getHaxelib("minimingw","",false);
 | 
						|
         if (haxelib!=null && haxelib!="")
 | 
						|
         {
 | 
						|
            ioDefines.set("MINGW_ROOT", haxelib);
 | 
						|
            Log.v('Using haxelib version of MinGW, $haxelib');
 | 
						|
            return;
 | 
						|
         }
 | 
						|
 | 
						|
         var guesses = ["c:/MinGW"];
 | 
						|
         for (guess in guesses)
 | 
						|
         {
 | 
						|
            if (FileSystem.exists(guess))
 | 
						|
            {
 | 
						|
               ioDefines.set("MINGW_ROOT", guess);
 | 
						|
               Log.v('Using default version of MinGW, $guess');
 | 
						|
               return;
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         if (ioDefines.exists("mingw"))
 | 
						|
         {
 | 
						|
            //when mingw is explicitly indicated but not properly configured, this log will be shown
 | 
						|
            Log.error('Could not guess MINGW_ROOT (tried $guesses) - please set explicitly');
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            //when both mingw and MSVC is not properly configured, this log will be shown
 | 
						|
            Log.error('Could not setup any C++ compiler, please install or reinstall a valid C++ compiler');
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
   public static function setupEmscripten(ioDefines:Hash<String>)
 | 
						|
   {
 | 
						|
      // Setup EMSCRIPTEN_SDK if possible - else assume developer has it in path
 | 
						|
      if (!ioDefines.exists("EMSCRIPTEN_SDK"))
 | 
						|
      {
 | 
						|
         var home = ioDefines.get("HXCPP_HOME");
 | 
						|
         var file = home + "/.emscripten";
 | 
						|
         if (FileSystem.exists(file))
 | 
						|
         {
 | 
						|
            var content = sys.io.File.getContent(file);
 | 
						|
            content = content.split("\r").join("");
 | 
						|
            var value = ~/^(\w*)\s*=\s*'(.*)'/;
 | 
						|
            for (line in content.split("\n"))
 | 
						|
            {
 | 
						|
               if (value.match(line))
 | 
						|
               {
 | 
						|
                  var name = value.matched(1);
 | 
						|
                  var val= value.matched(2);
 | 
						|
                  if (name=="EMSCRIPTEN_ROOT")
 | 
						|
                  {
 | 
						|
                     ioDefines.set("EMSCRIPTEN_SDK", val);
 | 
						|
                  }
 | 
						|
                  if (name=="PYTHON")
 | 
						|
                     ioDefines.set("EMSCRIPTEN_PYTHON", val);
 | 
						|
                  if (name=="NODE_JS")
 | 
						|
                     ioDefines.set("EMSCRIPTEN_NODE_JS", val);
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
   public static function isRaspberryPi()
 | 
						|
   {
 | 
						|
       var modelFile = '/sys/firmware/devicetree/base/model';
 | 
						|
       if( !FileSystem.exists( modelFile ) )
 | 
						|
           return false;
 | 
						|
       try {
 | 
						|
           var model = sys.io.File.getContent( modelFile );
 | 
						|
           return ~/Raspberry/.match( model );
 | 
						|
       } catch(e:Dynamic) {
 | 
						|
           trace( e );
 | 
						|
       }
 | 
						|
       return false;
 | 
						|
   }
 | 
						|
 | 
						|
   static public function startPdbServer()
 | 
						|
   {
 | 
						|
      var oldPath = Sys.getCwd();
 | 
						|
      try
 | 
						|
      {
 | 
						|
         // Run it in hxcpp directory so it does not lock the build directory after build finishes
 | 
						|
         Sys.setCwd(BuildTool.HXCPP);
 | 
						|
         var proc = new Process("mspdbsrv.exe",["-start"]);
 | 
						|
         Tools.addOnExitHook(function(_) {
 | 
						|
           proc.kill();
 | 
						|
         });
 | 
						|
      }
 | 
						|
      catch(e:Dynamic)
 | 
						|
      {
 | 
						|
         Log.v("Could not start mspdbsrv:" + e);
 | 
						|
      }
 | 
						|
      Sys.setCwd(oldPath);
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
   public static function setup(inWhat:String,ioDefines:Map<String,String>)
 | 
						|
   {
 | 
						|
      if (ioDefines.exists("HXCPP_CLEAN_ONLY"))
 | 
						|
         return;
 | 
						|
 | 
						|
      Profile.push("setup " + inWhat);
 | 
						|
      if (inWhat=="androidNdk")
 | 
						|
      {
 | 
						|
         setupAndroidNdk(ioDefines);
 | 
						|
      }
 | 
						|
      else if (inWhat=="blackberry")
 | 
						|
      {
 | 
						|
         setupBlackBerryNativeSDK(ioDefines);
 | 
						|
      }
 | 
						|
      else if (inWhat=="msvc")
 | 
						|
      {
 | 
						|
         setupMSVC(ioDefines, ioDefines.exists("HXCPP_M64"), ioDefines.exists("HXCPP_ARM64"), ioDefines.exists("winrt"));
 | 
						|
      }
 | 
						|
      else if (inWhat=="pdbserver")
 | 
						|
      {
 | 
						|
         startPdbServer();
 | 
						|
      }
 | 
						|
      else if (inWhat=="mingw")
 | 
						|
      {
 | 
						|
         setupMingw(ioDefines);
 | 
						|
      }
 | 
						|
      else if (inWhat=="emscripten")
 | 
						|
      {
 | 
						|
         setupEmscripten(ioDefines);
 | 
						|
      }
 | 
						|
      else if (inWhat=="nvcc")
 | 
						|
      {
 | 
						|
         BuildTool.setupNvcc();
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         Log.error('Unknown setup feature "$inWhat"');
 | 
						|
         //throw 'Unknown setup feature $inWhat';
 | 
						|
      }
 | 
						|
      Profile.pop();
 | 
						|
   }
 | 
						|
 | 
						|
   static public function setupAndroidNdk(defines:Map<String,String>)
 | 
						|
   {
 | 
						|
      var root:String = null;
 | 
						|
 | 
						|
      if (Log.verbose) Log.println("");
 | 
						|
 | 
						|
      var ndkVersion = 0;
 | 
						|
      for (i in 6...20)
 | 
						|
      {
 | 
						|
         if (defines.exists("NDKV" + i))
 | 
						|
         {
 | 
						|
            ndkVersion = i;
 | 
						|
            Log.info("", "\x1b[33;1mRequested Android NDK r" + i + "\x1b[0m");
 | 
						|
            break;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      if (!defines.exists("ANDROID_NDK_ROOT") || ndkVersion!=0)
 | 
						|
      {
 | 
						|
         root = Setup.findAndroidNdkRoot( defines, ndkVersion );
 | 
						|
         if (root==null)
 | 
						|
         {
 | 
						|
            var ndkDir = defines.exists("ANDROID_NDK_DIR") ? defines.get("ANDROID_NDK_DIR") : "not set";
 | 
						|
            if (ndkVersion!=0)
 | 
						|
               Log.error('ANDROID_NDK_DIR ["$ndkDir"] or ndk-bundle does not contain requested NDK $ndkVersion');
 | 
						|
            else
 | 
						|
               Log.error('ANDROID_NDK_DIR ["$ndkDir"] or ndk-bundle does not contain a matching NDK');
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            Sys.putEnv("ANDROID_NDK_ROOT", root);
 | 
						|
            defines.set("ANDROID_NDK_ROOT", root);
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         root = defines.get("ANDROID_NDK_ROOT");
 | 
						|
         Log.info("", "\x1b[33;1mUsing Android NDK root: " + root + "\x1b[0m");
 | 
						|
      }
 | 
						|
 | 
						|
      if (ndkVersion==0)
 | 
						|
      {
 | 
						|
         var version = Setup.getNdkVersion( root );
 | 
						|
         if (version > 0)
 | 
						|
         {
 | 
						|
            Log.info("", "\x1b[33;1mDetected Android NDK " + version + "\x1b[0m");
 | 
						|
            defines.set("NDKV" + Std.int(version), "1" );
 | 
						|
            ndkVersion = Std.int(version);
 | 
						|
         }
 | 
						|
         else
 | 
						|
            Log.error("Invalid ndk version");
 | 
						|
      }
 | 
						|
      for (i in 5...ndkVersion+1)
 | 
						|
         defines.set("NDKV" + i + "+", "1");
 | 
						|
 | 
						|
      var arm_type = 'arm-linux-androideabi';
 | 
						|
      var arm_64 = defines.exists('HXCPP_ARM64');
 | 
						|
      if(arm_64) arm_type = 'aarch64-linux-android';
 | 
						|
 | 
						|
      // Find toolchain
 | 
						|
      if (!defines.exists("TOOLCHAIN_VERSION"))
 | 
						|
      {
 | 
						|
         try
 | 
						|
         {
 | 
						|
            var files = FileSystem.readDirectory(root+"/toolchains");
 | 
						|
 | 
						|
            // Prefer clang?
 | 
						|
            var extract_version = ~/^arm-linux-androideabi-(\d.*)/;
 | 
						|
            if(arm_64) extract_version = ~/^aarch64-linux-android-(\d.*)/;
 | 
						|
 | 
						|
            var bestVer="";
 | 
						|
            for (file in files)
 | 
						|
            {
 | 
						|
               if (extract_version.match(file))
 | 
						|
               {
 | 
						|
                  var ver = extract_version.matched(1);
 | 
						|
                  if (ver<bestVer || bestVer=="")
 | 
						|
                  {
 | 
						|
                     bestVer = ver;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
            }
 | 
						|
            if (bestVer!="")
 | 
						|
            {
 | 
						|
               defines.set("TOOLCHAIN_VERSION",bestVer);
 | 
						|
               Log.info("", "\x1b[33;1mDetected Android toolchain: "+arm_type+"-" + bestVer + "\x1b[0m");
 | 
						|
            }
 | 
						|
         }
 | 
						|
         catch(e:Dynamic) { }
 | 
						|
      }
 | 
						|
 | 
						|
      // See what ANDROID_HOST to use ...
 | 
						|
      try
 | 
						|
      {
 | 
						|
         var prebuilt = root+"/toolchains/";
 | 
						|
         if (defines.exists("TOOLCHAIN_VERSION"))
 | 
						|
            prebuilt += arm_type + "-" + defines.get("TOOLCHAIN_VERSION") + "/prebuilt";
 | 
						|
         else
 | 
						|
            prebuilt += "llvm/prebuilt";
 | 
						|
         var files = FileSystem.readDirectory(prebuilt);
 | 
						|
         for (file in files)
 | 
						|
         {
 | 
						|
            if (!FileSystem.isDirectory (prebuilt + "/" + file))
 | 
						|
            {
 | 
						|
               files.remove (file);
 | 
						|
            }
 | 
						|
         }
 | 
						|
         if (files.length==1)
 | 
						|
         {
 | 
						|
            defines.set("ANDROID_HOST", files[0]);
 | 
						|
            Log.info("", "\x1b[33;1mDetected Android host: " + files[0] + "\x1b[0m");
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            Log.info("", "\x1b[33;1mCould not detect ANDROID_HOST (" + files + ") - using default\x1b[0m");
 | 
						|
         }
 | 
						|
      }
 | 
						|
      catch(e:Dynamic) { }
 | 
						|
 | 
						|
      if(defines.exists('NDKV20+')) {
 | 
						|
         Log.v([
 | 
						|
            "x86 Platform: 16",
 | 
						|
            "arm Platform: 16",
 | 
						|
            "x86_64 Platform: 21",
 | 
						|
            "arm_64 Platform: 21",
 | 
						|
            "Frameworks should set the minSdkVersion for each APK to these values."
 | 
						|
         ].join('\n'));
 | 
						|
      }
 | 
						|
      else {
 | 
						|
         globallySetThePlatform(root, defines);
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   private static function globallySetThePlatform(root:String, defines:Map<String,String>) {
 | 
						|
      var androidPlatform = 5;
 | 
						|
      if (!defines.exists("PLATFORM"))
 | 
						|
      {
 | 
						|
         for (i in 5...100)
 | 
						|
         {
 | 
						|
            var test = "android-" + i;
 | 
						|
            if (defines.exists(test))
 | 
						|
            {
 | 
						|
               defines.set("PLATFORM",test);
 | 
						|
               break;
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      if (defines.exists("PLATFORM"))
 | 
						|
      {
 | 
						|
         var platform = defines.get("PLATFORM");
 | 
						|
         var id = Std.parseInt( platform.substr("android-".length) );
 | 
						|
         if (id==0 || id==null)
 | 
						|
            Log.error('Badly formed android PLATFORM "$platform" - should be like android-123');
 | 
						|
         androidPlatform = id;
 | 
						|
         Log.info("", "\x1b[33;1mUsing Android NDK platform: " + defines.get("PLATFORM") + "\x1b[0m");
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         var base = root + "/platforms";
 | 
						|
         var best = 0;
 | 
						|
         try
 | 
						|
         {
 | 
						|
            for (file in FileSystem.readDirectory(base))
 | 
						|
            {
 | 
						|
               if (file.substr(0,8)=="android-")
 | 
						|
               {
 | 
						|
                  var platform = Std.parseInt(file.substr(8));
 | 
						|
                  if (platform>best)
 | 
						|
                     best = platform;
 | 
						|
               }
 | 
						|
            }
 | 
						|
         } catch(e:Dynamic) {}
 | 
						|
 | 
						|
         if (best==0)
 | 
						|
         {
 | 
						|
            Log.error("Could not detect Android API platforms in \"" + base + "\"");
 | 
						|
            //throw "Could not find platform in " + base;
 | 
						|
         }
 | 
						|
 | 
						|
         Log.info("", "\x1b[33;1mUsing newest Android NDK platform: " + best + "\x1b[0m");
 | 
						|
         defines.set("PLATFORM", "android-" + best);
 | 
						|
         androidPlatform = best;
 | 
						|
      }
 | 
						|
      defines.set("ANDROID_PLATFORM_DEFINE", "HXCPP_ANDROID_PLATFORM=" + androidPlatform);
 | 
						|
      if (Log.verbose) Log.println("");
 | 
						|
   }
 | 
						|
 | 
						|
   public static function setupBlackBerryNativeSDK(ioDefines:Hash<String>)
 | 
						|
   {
 | 
						|
      if (!ioDefines.exists ("BLACKBERRY_NDK_ROOT"))
 | 
						|
      {
 | 
						|
          Log.error("Could not find BLACKBERRY_NDK_ROOT variable");
 | 
						|
      }
 | 
						|
 | 
						|
      var fileName = ioDefines.get ("BLACKBERRY_NDK_ROOT");
 | 
						|
      if (BuildTool.isWindows)
 | 
						|
      {
 | 
						|
         fileName += "\\bbndk-env.bat";
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         fileName += "/bbndk-env.sh";
 | 
						|
      }
 | 
						|
 | 
						|
      if (FileSystem.exists (fileName))
 | 
						|
      {
 | 
						|
         var fin = sys.io.File.read(fileName, false);
 | 
						|
         try
 | 
						|
         {
 | 
						|
            while(true)
 | 
						|
            {
 | 
						|
               var str = fin.readLine();
 | 
						|
               var split = str.split ("=");
 | 
						|
               var name = StringTools.trim (split[0].substr (split[0].lastIndexOf (" ") + 1));
 | 
						|
               switch (name)
 | 
						|
               {
 | 
						|
                  case "QNX_HOST", "QNX_TARGET", "QNX_HOST_VERSION", "QNX_TARGET_VERSION":
 | 
						|
                     var value = split[1];
 | 
						|
                     if (StringTools.startsWith (value, "${") && split.length > 2)
 | 
						|
                     {
 | 
						|
                        value = split[2].substr (0, split[2].length - 1);
 | 
						|
                     }
 | 
						|
                     if (StringTools.startsWith(value, "\""))
 | 
						|
                     {
 | 
						|
                        value = value.substr (1);
 | 
						|
                     }
 | 
						|
                     if (StringTools.endsWith(value, "\""))
 | 
						|
                     {
 | 
						|
                        value = value.substr (0, value.length - 1);
 | 
						|
                     }
 | 
						|
                     if (name == "QNX_HOST_VERSION" || name == "QNX_TARGET_VERSION")
 | 
						|
                     {
 | 
						|
                        if (Sys.getEnv (name) != null)
 | 
						|
                        {
 | 
						|
                           continue;
 | 
						|
                        }
 | 
						|
                     }
 | 
						|
                     else
 | 
						|
                     {
 | 
						|
                        value = StringTools.replace (value, "$BASE_DIR", ioDefines.get ("BLACKBERRY_NDK_ROOT"));
 | 
						|
                        value = StringTools.replace (value, "%BASE_DIR%", ioDefines.get ("BLACKBERRY_NDK_ROOT"));
 | 
						|
                        value = StringTools.replace (value, "$TARGET", "qnx6");
 | 
						|
                        value = StringTools.replace (value, "%TARGET%", "qnx6");
 | 
						|
                        value = StringTools.replace (value, "$QNX_HOST_VERSION", Sys.getEnv("QNX_HOST_VERSION"));
 | 
						|
                        value = StringTools.replace (value, "$QNX_TARGET_VERSION", Sys.getEnv("QNX_TARGET_VERSION"));
 | 
						|
                        value = StringTools.replace (value, "%QNX_HOST_VERSION%", Sys.getEnv("QNX_HOST_VERSION"));
 | 
						|
                        value = StringTools.replace (value, "%QNX_TARGET_VERSION%", Sys.getEnv("QNX_TARGET_VERSION"));
 | 
						|
                     }
 | 
						|
                     ioDefines.set(name,value);
 | 
						|
                     Sys.putEnv(name,value);
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
         catch( ex:Eof )
 | 
						|
         {}
 | 
						|
         fin.close();
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         Log.error("Could not find \"" + fileName + "\"");
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   public static function setupMSVC(ioDefines:Hash<String>, in64:Bool, inArm64, isWinRT:Bool)
 | 
						|
   {
 | 
						|
      var detectMsvc = !ioDefines.exists("NO_AUTO_MSVC") &&
 | 
						|
                       !ioDefines.exists("HXCPP_MSVC_CUSTOM");
 | 
						|
 | 
						|
      if (ioDefines.exists("HXCPP_MSVC_VER"))
 | 
						|
      {
 | 
						|
         var val = ioDefines.get("HXCPP_MSVC_VER");
 | 
						|
         if (val=="")
 | 
						|
            detectMsvc = false;
 | 
						|
         else
 | 
						|
         {
 | 
						|
            var ival = Std.parseInt(ioDefines.get("HXCPP_MSVC_VER"));
 | 
						|
            if (ival>0)
 | 
						|
            {
 | 
						|
               var varName = "VS" + ival+ "COMNTOOLS";
 | 
						|
               var where = Sys.getEnv(varName);
 | 
						|
               if (where==null)
 | 
						|
               {
 | 
						|
                  for (env in Sys.environment().keys())
 | 
						|
                  {
 | 
						|
                     if (env.substr(0,2)=="VS")
 | 
						|
                     {
 | 
						|
                        Log.info("Found VS variable: " + env);
 | 
						|
                        //Sys.println("Found VS variable " + env);
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
                  Log.error("Could not find specified MSVC version: " + ival);
 | 
						|
                  //throw "Could not find specified MSVC version " + ival;
 | 
						|
               }
 | 
						|
               ioDefines.set("HXCPP_MSVC", where );
 | 
						|
               Sys.putEnv("HXCPP_MSVC", where);
 | 
						|
               Log.info("", 'Using MSVC Ver $ival in $where ($varName)');
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               Log.info("", 'Using specified MSVC Ver $val');
 | 
						|
               ioDefines.set("HXCPP_MSVC", val );
 | 
						|
               Sys.putEnv("HXCPP_MSVC", val);
 | 
						|
            }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (detectMsvc)
 | 
						|
      {
 | 
						|
        var extra:String = "";
 | 
						|
        if (isWinRT)
 | 
						|
            extra += "-winrt";
 | 
						|
        if (inArm64)
 | 
						|
            extra += "-arm64";
 | 
						|
        else if (in64)
 | 
						|
            extra += "64";
 | 
						|
         var xpCompat = false;
 | 
						|
         if (ioDefines.exists("HXCPP_WINXP_COMPAT"))
 | 
						|
         {
 | 
						|
            Sys.putEnv("HXCPP_WINXP_COMPAT","1");
 | 
						|
            xpCompat = true;
 | 
						|
         }
 | 
						|
         Sys.putEnv("msvc_host_arch", ioDefines.exists("windows_arm_host") ? "x86" : "x64" );
 | 
						|
 | 
						|
         var vc_setup_proc = new Process("cmd.exe", ["/C", BuildTool.HXCPP + "\\toolchain\\msvc" + extra + "-setup.bat" ]);
 | 
						|
         var vars_found = false;
 | 
						|
         var error_string = "";
 | 
						|
         var output = new Array<String>();
 | 
						|
         try{
 | 
						|
            while(true)
 | 
						|
            {
 | 
						|
               var str = vc_setup_proc.stdout.readLine();
 | 
						|
               if (str=="HXCPP_VARS")
 | 
						|
                  vars_found = true;
 | 
						|
               else if (!vars_found)
 | 
						|
               {
 | 
						|
                  if (str.substr(0,5)=="Error" || ~/missing/.match(str) )
 | 
						|
                     error_string = str;
 | 
						|
 | 
						|
                  output.push(str);
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  var pos = str.indexOf("=");
 | 
						|
                  var name = str.substr(0,pos);
 | 
						|
                  switch(name.toLowerCase())
 | 
						|
                  {
 | 
						|
                     case "path", "vcinstalldir", "windowssdkdir","framework35version",
 | 
						|
                        "frameworkdir", "frameworkdir32", "frameworkversion",
 | 
						|
                        "frameworkversion32", "devenvdir", "include", "lib", "libpath", "hxcpp_xp_define",
 | 
						|
                        "hxcpp_hack_pdbsrv"
 | 
						|
                      :
 | 
						|
                        var value = str.substr(pos+1);
 | 
						|
                        ioDefines.set(name,value);
 | 
						|
                        Log.v('  msvs $name=$value');
 | 
						|
                        Sys.putEnv(name,value);
 | 
						|
                  }
 | 
						|
               }
 | 
						|
            }
 | 
						|
         } catch (e:Dynamic) {
 | 
						|
         };
 | 
						|
 | 
						|
         vc_setup_proc.exitCode();
 | 
						|
         vc_setup_proc.close();
 | 
						|
         if (!vars_found || error_string!="")
 | 
						|
         {
 | 
						|
            for (o in output)
 | 
						|
            {
 | 
						|
               Log.info(o);
 | 
						|
               //BuildTool.println(o);
 | 
						|
            }
 | 
						|
            if (error_string!="")
 | 
						|
            {
 | 
						|
               Log.error (error_string);
 | 
						|
               //throw(error_string);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               Log.info("Missing HXCPP_VARS");
 | 
						|
               //BuildTool.println("Missing HXCPP_VARS");
 | 
						|
            }
 | 
						|
 | 
						|
            Log.error("Could not automatically setup MSVC");
 | 
						|
            //throw("Could not automatically setup MSVC");
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      try
 | 
						|
      {
 | 
						|
         var proc = new Process("cl.exe",[]);
 | 
						|
         var str = proc.stderr.readLine();
 | 
						|
         proc.close();
 | 
						|
         if (str>"")
 | 
						|
         {
 | 
						|
            Log.v("MSVC output:" + str);
 | 
						|
            var reg = ~/(\d{2})\.\d+/i;
 | 
						|
            if (reg.match(str))
 | 
						|
            {
 | 
						|
               var cl_version = Std.parseInt(reg.matched(1));
 | 
						|
               Log.info("", "Using MSVC version: " + cl_version);
 | 
						|
               ioDefines.set("MSVC_VER", cl_version+"");
 | 
						|
               if (cl_version>=17)
 | 
						|
                  ioDefines.set("MSVC17+","1");
 | 
						|
               if (cl_version>=18)
 | 
						|
                  ioDefines.set("MSVC18+","1");
 | 
						|
               if (cl_version==19)
 | 
						|
                  ioDefines.set("MSVC19","1");
 | 
						|
               BuildTool.sAllowNumProcs = cl_version >= 14;
 | 
						|
               var threads = BuildTool.getThreadCount();
 | 
						|
               if (threads>1 && cl_version>=18)
 | 
						|
                  ioDefines.set("HXCPP_FORCE_PDB_SERVER","1");
 | 
						|
            }
 | 
						|
         }
 | 
						|
      } catch(e:Dynamic){}
 | 
						|
      //if (cl_version!="") BuildTool.println("Using cl version: " + cl_version);
 | 
						|
   }
 | 
						|
 | 
						|
   static function toPath(inPath:String)
 | 
						|
   {
 | 
						|
      if (!BuildTool.isWindows)
 | 
						|
         return inPath;
 | 
						|
      var bits = inPath.split("/");
 | 
						|
      return bits.join("\\");
 | 
						|
   }
 | 
						|
}
 |