XSTools.pm.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:4k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - C++-to-Perl binding library
  3. #
  4. #  Copryight (c) 2006 OpenKore Development Team
  5. #
  6. #  This software is open source, licensed under the GNU General Public
  7. #  License, version 2.
  8. #  Basically, this means that you're allowed to modify and distribute
  9. #  this software. However, if you distribute modified versions, you MUST
  10. #  also distribute the source code.
  11. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  12. #########################################################################
  13. package XSTools;
  14. use strict;
  15. use FindBin qw($RealBin);
  16. use File::Spec;
  17. use Cwd 'abs_path', 'realpath';
  18. use DynaLoader;
  19. use XSLoader;
  20. # Make sure PerlApp doesn't include Exception::Class;
  21. my $class = 'Exception::Class'; eval "use $class;"; die $@ if ($@);
  22. $class = 'Utils::Exceptions'; eval "use $class;"; die $@ if ($@);
  23. import Exception::Class (
  24. 'XSTools::LoadException' => { fields => 'wrappedError' },
  25. 'XSTools::CompileException',
  26. 'XSTools::CompilationInterrupted',
  27. 'XSTools::MakefileNotFound'
  28. );
  29. our @makefilePaths;
  30. ##
  31. # void XSTools::bootstrap()
  32. #
  33. # Bootstrap the XSTools library. Calling this function more than once will have no effect.
  34. #
  35. # Throws XSTools::LoadException when the XSTools library cannot be loaded. This is usually
  36. # because the library does not exist.
  37. sub boot {
  38. our $booted;
  39. if (!$booted) {
  40. eval {
  41. XSLoader::load('XSTools');
  42. $booted = 1;
  43. };
  44. if ($@) {
  45. XSTools::LoadException->throw(
  46. error => "Cannot load the XSTools library.",
  47. wrappedError => $@
  48. );
  49. }
  50. }
  51. }
  52. ##
  53. # void XSTools::bootModule(String moduleName)
  54. #
  55. # Convenience function for loading other modules in the XSTools library.
  56. #
  57. # Throws XSTools::LoadException when this module cannot be loaded.
  58. sub bootModule {
  59. my ($module) = @_;
  60. my $symbolName = $module;
  61. $symbolName =~ s/::/__/;
  62. $symbolName = "boot_$symbolName";
  63. boot();
  64. my $symbol = DynaLoader::dl_find_symbol_anywhere($symbolName);
  65. if (!$symbol) {
  66. XSTools::LoadException->throw(error => "Unable to find symbol $symbolName");
  67. }
  68. my $sub = DynaLoader::dl_install_xsub("${module}::bootstrap", $symbol);
  69. if (!$sub) {
  70. XSTools::LoadException->throw(error => "Cannot bootstrap $module");
  71. }
  72. $sub->();
  73. }
  74. ##
  75. # void XSTools::compile()
  76. #
  77. # Compile the XSTools library. This function only works on Unix.
  78. #
  79. # Throws XSTools::CompileException if compilation failed.
  80. # Throws XSTools::MakefileNotFound if the compilation makefile cannot be found.
  81. # Throws XSTools::CompilationInterrupted if the user pressed Ctrl+C when compiling.
  82. sub compile {
  83. my $dir;
  84. foreach my $try (@makefilePaths) {
  85. if (-f "$try/Makefile") {
  86. $dir = $try;
  87. last;
  88. }
  89. }
  90. if (!defined $dir) {
  91. XSTools::MakefileNotFound->throw(error => "Cannot find Makefile.");
  92. }
  93. my $ret = system('make', '-C', $dir);
  94. if ($ret != 0) {
  95. if (($ret & 127) == 2) {
  96. # Ctrl+C pressed
  97. XSTools::CompilationInterrupted->throw(error => "User interrupted compilation.");
  98. } else {
  99. XSTools::CompileException->throw(error => "Compilation failed.");
  100. }
  101. }
  102. }
  103. eval {
  104. # We put this in an 'eval' because realpath() will die if we're run in a
  105. # PerlApp executable, because __FILE__ does not exist.
  106. my ($drive, $dirs, undef) = File::Spec->splitpath(realpath(__FILE__));
  107. $dirs = "$drive$dirs";
  108. push @makefilePaths, abs_path(File::Spec->join($dirs, ".."));
  109. };
  110. push @makefilePaths, $RealBin;
  111. # Initialize the library, auto-compile if necessary.
  112. eval {
  113. boot();
  114. };
  115. if (my $e = caught('XSTools::LoadException')) {
  116. if ($^O eq 'MSWin32') {
  117. print $e->wrappedError();
  118. print STDERR "Error: XSTools.dll is not found. Please check your installation.n";
  119. <STDIN>;
  120. exit 1;
  121. } else {
  122. eval {
  123. compile();
  124. boot();
  125. };
  126. if (my $e = caught('XSTools::LoadException')) {
  127. print $e->wrappedError();
  128. exit 1;
  129. } elsif (caught('XSTools::CompileException') || caught('XSTools::CompilationInterrupted')) {
  130. exit 1;
  131. } elsif (caught('XSTools::MakefileNotFound')) {
  132. print STDERR "Makefile not found. Please check your installation.n";
  133. exit 1;
  134. } elsif ($@) {
  135. die $@;
  136. }
  137. }
  138. } elsif ($@) {
  139. die $@;
  140. }
  141. 1;