testDynamicLoader.cxx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
  3. #include "kwsysPrivate.h"
  4. #include KWSYS_HEADER(DynamicLoader.hxx)
  5. #if defined(__BEOS__) || defined(__HAIKU__)
  6. # include <be/kernel/OS.h> /* disable_debugger() API. */
  7. #endif
  8. // Work-around CMake dependency scanning limitation. This must
  9. // duplicate the above list of headers.
  10. #if 0
  11. # include "DynamicLoader.hxx.in"
  12. #endif
  13. #include <iostream>
  14. #include <string>
  15. // Include with <> instead of "" to avoid getting any in-source copy
  16. // left on disk.
  17. #include <testSystemTools.h>
  18. static std::string GetLibName(const char* lname, const char* subdir = nullptr)
  19. {
  20. // Construct proper name of lib
  21. std::string slname;
  22. slname = RUNTIME_OUTPUT_DIRECTORY;
  23. if (subdir) {
  24. slname += "/";
  25. slname += subdir;
  26. }
  27. #ifdef CMAKE_INTDIR
  28. slname += "/";
  29. slname += CMAKE_INTDIR;
  30. #endif
  31. slname += "/";
  32. slname += kwsys::DynamicLoader::LibPrefix();
  33. slname += lname;
  34. slname += kwsys::DynamicLoader::LibExtension();
  35. return slname;
  36. }
  37. /* libname = Library name (proper prefix, proper extension)
  38. * System = symbol to lookup in libname
  39. * r1: should OpenLibrary succeed ?
  40. * r2: should GetSymbolAddress succeed ?
  41. * r3: should CloseLibrary succeed ?
  42. */
  43. static int TestDynamicLoader(const char* libname, const char* symbol, int r1,
  44. int r2, int r3, int flags = 0)
  45. {
  46. std::cerr << "Testing: " << libname << std::endl;
  47. kwsys::DynamicLoader::LibraryHandle l =
  48. kwsys::DynamicLoader::OpenLibrary(libname, flags);
  49. // If result is incompatible with expectation just fails (xor):
  50. if ((r1 && !l) || (!r1 && l)) {
  51. std::cerr << "OpenLibrary: " << kwsys::DynamicLoader::LastError()
  52. << std::endl;
  53. return 1;
  54. }
  55. kwsys::DynamicLoader::SymbolPointer f =
  56. kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
  57. if ((r2 && !f) || (!r2 && f)) {
  58. std::cerr << "GetSymbolAddress: " << kwsys::DynamicLoader::LastError()
  59. << std::endl;
  60. return 1;
  61. }
  62. #ifndef __APPLE__
  63. int s = kwsys::DynamicLoader::CloseLibrary(l);
  64. if ((r3 && !s) || (!r3 && s)) {
  65. std::cerr << "CloseLibrary: " << kwsys::DynamicLoader::LastError()
  66. << std::endl;
  67. return 1;
  68. }
  69. #else
  70. (void)r3;
  71. #endif
  72. return 0;
  73. }
  74. int testDynamicLoader(int argc, char* argv[])
  75. {
  76. #if defined(_WIN32)
  77. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  78. #elif defined(__BEOS__) || defined(__HAIKU__)
  79. disable_debugger(1);
  80. #endif
  81. int res = 0;
  82. if (argc == 3) {
  83. // User specify a libname and symbol to check.
  84. res = TestDynamicLoader(argv[1], argv[2], 1, 1, 1);
  85. return res;
  86. }
  87. // dlopen() on Syllable before 11/22/2007 doesn't return 0 on error
  88. #ifndef __SYLLABLE__
  89. // Make sure that inexistent lib is giving correct result
  90. res += TestDynamicLoader("azerty_", "foo_bar", 0, 0, 0);
  91. // Make sure that random binary file cannot be assimilated as dylib
  92. res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin",
  93. "wp", 0, 0, 0);
  94. #endif
  95. #ifdef __linux__
  96. // This one is actually fun to test, since dlopen is by default
  97. // loaded...wonder why :)
  98. res += TestDynamicLoader("foobar.lib", "dlopen", 0, 1, 0);
  99. res += TestDynamicLoader("libdl.so", "dlopen", 1, 1, 1);
  100. res += TestDynamicLoader("libdl.so", "TestDynamicLoader", 1, 0, 1);
  101. #endif
  102. // Now try on the generated library
  103. std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
  104. res += TestDynamicLoader(libname.c_str(), "dummy", 1, 0, 1);
  105. res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",
  106. 1, 1, 1);
  107. res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",
  108. 1, 0, 1);
  109. res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData", 1, 1, 1);
  110. res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData", 1, 0, 1);
  111. #ifdef _WIN32
  112. libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynloadUse", "dynloaddir");
  113. res += TestDynamicLoader(libname.c_str(), "dummy", 0, 0, 0);
  114. res += TestDynamicLoader(libname.c_str(), "TestLoad", 1, 1, 1,
  115. kwsys::DynamicLoader::SearchBesideLibrary);
  116. res += TestDynamicLoader(libname.c_str(), "_TestLoad", 1, 0, 1,
  117. kwsys::DynamicLoader::SearchBesideLibrary);
  118. #endif
  119. return res;
  120. }