ScriptCompiler.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (c) 2008-2023 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, bool stripDebugSymbols);
  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] [-nostrip]\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. bool stripDebugSymbols = true;
  84. for (int idx = arguments.Size() - 1; idx > 0; idx--)
  85. {
  86. if (arguments[idx] == "-nostrip")
  87. {
  88. stripDebugSymbols = false;
  89. break;
  90. }
  91. }
  92. // Add resource path to be able to resolve includes
  93. if (arguments.Size() > 1 && arguments[1] != "-nostrip")
  94. cache->AddResourceDir(arguments[1]);
  95. else
  96. cache->AddResourceDir(cache->GetPreferredResourceDir(path));
  97. if (!file.StartsWith("*"))
  98. CompileScript(context, outputFile, stripDebugSymbols);
  99. else
  100. {
  101. Vector<String> scriptFiles;
  102. context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
  103. for (unsigned i = 0; i < scriptFiles.Size(); ++i)
  104. CompileScript(context, path + scriptFiles[i], stripDebugSymbols);
  105. }
  106. }
  107. else
  108. {
  109. if (!outputFile.Empty())
  110. {
  111. log->SetQuiet(true);
  112. log->Open(outputFile);
  113. }
  114. // If without output file, dump to stdout instead
  115. context->GetSubsystem<Script>()->DumpAPI(DOXYGEN, sourceTree);
  116. // Only dump API as C Header when an output file name is explicitly given
  117. if (arguments.Size() > 3)
  118. {
  119. outputFile = arguments[3];
  120. log->Open(outputFile);
  121. context->GetSubsystem<Script>()->DumpAPI(C_HEADER, sourceTree);
  122. }
  123. }
  124. return EXIT_SUCCESS;
  125. }
  126. void CompileScript(Context* context, const String& fileName, bool stripDebugSymbols)
  127. {
  128. PrintLine("Compiling script file " + fileName);
  129. File inFile(context, fileName, FILE_READ);
  130. if (!inFile.IsOpen())
  131. ErrorExit("Failed to open script file " + fileName);
  132. ScriptFile script(context);
  133. script.SetOnlyCompile();
  134. if (!script.Load(inFile))
  135. ErrorExit();
  136. String outFileName = ReplaceExtension(fileName, ".asc");
  137. File outFile(context, outFileName, FILE_WRITE);
  138. if (!outFile.IsOpen())
  139. ErrorExit("Failed to open output file " + fileName);
  140. script.SaveByteCode(outFile, stripDebugSymbols);
  141. }