ScriptCompiler.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. #include <Urho3D/AngelScript/Script.h>
  4. #include <Urho3D/AngelScript/ScriptFile.h>
  5. #include <Urho3D/Core/Context.h>
  6. #include <Urho3D/Core/ProcessUtils.h>
  7. #include <Urho3D/Engine/Engine.h>
  8. #include <Urho3D/Engine/EngineDefs.h>
  9. #include <Urho3D/IO/File.h>
  10. #include <Urho3D/IO/FileSystem.h>
  11. #include <Urho3D/IO/Log.h>
  12. #include <Urho3D/Resource/ResourceCache.h>
  13. #ifdef URHO3D_LUA
  14. #include <Urho3D/LuaScript/LuaScript.h>
  15. #endif
  16. #ifdef WIN32
  17. #include <Urho3D/Engine/WinWrapped.h>
  18. #endif
  19. #include <Urho3D/DebugNew.h>
  20. using namespace Urho3D;
  21. void CompileScript(Context* context, const String& fileName);
  22. int main(int argc, char** argv)
  23. {
  24. #ifdef WIN32
  25. const Vector<String>& arguments = ParseArguments(GetCommandLineW());
  26. #else
  27. const Vector<String>& arguments = ParseArguments(argc, argv);
  28. #endif
  29. bool dumpApiMode = false;
  30. String sourceTree;
  31. String outputFile;
  32. if (arguments.Size() < 1)
  33. ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n"
  34. " ScriptCompiler -dumpapi <source tree> <Doxygen output file> [C header output file]");
  35. else
  36. {
  37. if (arguments[0] != "-dumpapi")
  38. outputFile = arguments[0];
  39. else
  40. {
  41. dumpApiMode = true;
  42. if (arguments.Size() > 2)
  43. {
  44. sourceTree = arguments[1];
  45. outputFile = arguments[2];
  46. }
  47. else
  48. ErrorExit("Usage: ScriptCompiler -dumpapi <source tree> <Doxygen output file> [C header output file]");
  49. }
  50. }
  51. SharedPtr<Context> context(new Context());
  52. SharedPtr<Engine> engine(new Engine(context));
  53. context->RegisterSubsystem(new Script(context));
  54. // In API dumping mode initialize the engine and instantiate LuaScript system if available so that we
  55. // can dump attributes from as many classes as possible
  56. if (dumpApiMode)
  57. {
  58. VariantMap engineParameters;
  59. engineParameters[EP_HEADLESS] = true;
  60. engineParameters[EP_WORKER_THREADS] = false;
  61. engineParameters[EP_LOG_NAME] = String::EMPTY;
  62. engineParameters[EP_RESOURCE_PATHS] = String::EMPTY;
  63. engineParameters[EP_AUTOLOAD_PATHS] = String::EMPTY;
  64. engine->Initialize(engineParameters);
  65. #ifdef URHO3D_LUA
  66. context->RegisterSubsystem(new LuaScript(context));
  67. #endif
  68. }
  69. auto* log = context->GetSubsystem<Log>();
  70. // Register Log subsystem manually if compiled without logging support
  71. if (!log)
  72. {
  73. context->RegisterSubsystem(new Log(context));
  74. log = context->GetSubsystem<Log>();
  75. }
  76. log->SetLevel(LOG_WARNING);
  77. log->SetTimeStamp(false);
  78. if (!dumpApiMode)
  79. {
  80. String path, file, extension;
  81. SplitPath(outputFile, path, file, extension);
  82. auto* cache = context->GetSubsystem<ResourceCache>();
  83. // Add resource path to be able to resolve includes
  84. if (arguments.Size() > 1)
  85. cache->AddResourceDir(arguments[1]);
  86. else
  87. cache->AddResourceDir(cache->GetPreferredResourceDir(path));
  88. if (!file.StartsWith("*"))
  89. CompileScript(context, outputFile);
  90. else
  91. {
  92. Vector<String> scriptFiles;
  93. context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
  94. for (unsigned i = 0; i < scriptFiles.Size(); ++i)
  95. CompileScript(context, path + scriptFiles[i]);
  96. }
  97. }
  98. else
  99. {
  100. if (!outputFile.Empty())
  101. {
  102. log->SetQuiet(true);
  103. log->Open(outputFile);
  104. }
  105. // If without output file, dump to stdout instead
  106. context->GetSubsystem<Script>()->DumpAPI(DOXYGEN, sourceTree);
  107. // Only dump API as C Header when an output file name is explicitly given
  108. if (arguments.Size() > 3)
  109. {
  110. outputFile = arguments[3];
  111. log->Open(outputFile);
  112. context->GetSubsystem<Script>()->DumpAPI(C_HEADER, sourceTree);
  113. }
  114. }
  115. return EXIT_SUCCESS;
  116. }
  117. void CompileScript(Context* context, const String& fileName)
  118. {
  119. PrintLine("Compiling script file " + fileName);
  120. File inFile(context, fileName, FILE_READ);
  121. if (!inFile.IsOpen())
  122. ErrorExit("Failed to open script file " + fileName);
  123. ScriptFile script(context);
  124. script.SetOnlyCompile();
  125. if (!script.Load(inFile))
  126. ErrorExit();
  127. String outFileName = ReplaceExtension(fileName, ".asc");
  128. File outFile(context, outFileName, FILE_WRITE);
  129. if (!outFile.IsOpen())
  130. ErrorExit("Failed to open output file " + fileName);
  131. script.SaveByteCode(outFile);
  132. }