testDynamicLoader.cxx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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)
  19. {
  20. // Construct proper name of lib
  21. std::string slname;
  22. slname = EXECUTABLE_OUTPUT_PATH;
  23. #ifdef CMAKE_INTDIR
  24. slname += "/";
  25. slname += CMAKE_INTDIR;
  26. #endif
  27. slname += "/";
  28. slname += kwsys::DynamicLoader::LibPrefix();
  29. slname += lname;
  30. slname += kwsys::DynamicLoader::LibExtension();
  31. return slname;
  32. }
  33. /* libname = Library name (proper prefix, proper extension)
  34. * System = symbol to lookup in libname
  35. * r1: should OpenLibrary succeed ?
  36. * r2: should GetSymbolAddress succeed ?
  37. * r3: should CloseLibrary succeed ?
  38. */
  39. static int TestDynamicLoader(const char* libname, const char* symbol, int r1,
  40. int r2, int r3)
  41. {
  42. std::cerr << "Testing: " << libname << std::endl;
  43. kwsys::DynamicLoader::LibraryHandle l =
  44. kwsys::DynamicLoader::OpenLibrary(libname);
  45. // If result is incompatible with expectation just fails (xor):
  46. if ((r1 && !l) || (!r1 && l)) {
  47. std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
  48. return 1;
  49. }
  50. kwsys::DynamicLoader::SymbolPointer f =
  51. kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
  52. if ((r2 && !f) || (!r2 && f)) {
  53. std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
  54. return 1;
  55. }
  56. #ifndef __APPLE__
  57. int s = kwsys::DynamicLoader::CloseLibrary(l);
  58. if ((r3 && !s) || (!r3 && s)) {
  59. std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
  60. return 1;
  61. }
  62. #else
  63. (void)r3;
  64. #endif
  65. return 0;
  66. }
  67. int testDynamicLoader(int argc, char* argv[])
  68. {
  69. #if defined(_WIN32)
  70. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  71. #elif defined(__BEOS__) || defined(__HAIKU__)
  72. disable_debugger(1);
  73. #endif
  74. int res = 0;
  75. if (argc == 3) {
  76. // User specify a libname and symbol to check.
  77. res = TestDynamicLoader(argv[1], argv[2], 1, 1, 1);
  78. return res;
  79. }
  80. // dlopen() on Syllable before 11/22/2007 doesn't return 0 on error
  81. #ifndef __SYLLABLE__
  82. // Make sure that inexistent lib is giving correct result
  83. res += TestDynamicLoader("azerty_", "foo_bar", 0, 0, 0);
  84. // Make sure that random binary file cannot be assimilated as dylib
  85. res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin",
  86. "wp", 0, 0, 0);
  87. #endif
  88. #ifdef __linux__
  89. // This one is actually fun to test, since dlopen is by default
  90. // loaded...wonder why :)
  91. res += TestDynamicLoader("foobar.lib", "dlopen", 0, 1, 0);
  92. res += TestDynamicLoader("libdl.so", "dlopen", 1, 1, 1);
  93. res += TestDynamicLoader("libdl.so", "TestDynamicLoader", 1, 0, 1);
  94. #endif
  95. // Now try on the generated library
  96. std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
  97. res += TestDynamicLoader(libname.c_str(), "dummy", 1, 0, 1);
  98. res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",
  99. 1, 1, 1);
  100. res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",
  101. 1, 0, 1);
  102. res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData", 1, 1, 1);
  103. res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData", 1, 0, 1);
  104. return res;
  105. }