testDynamicLoader.cxx 3.69 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
3 4 5 6
#include "kwsysPrivate.h"

#include KWSYS_HEADER(DynamicLoader.hxx)

7
#if defined(__BEOS__) || defined(__HAIKU__)
8
#include <be/kernel/OS.h> /* disable_debugger() API. */
9 10
#endif

11 12 13
// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
14
#include "DynamicLoader.hxx.in"
15 16
#endif

17
#include <iostream>
18
#include <string>
19

20 21 22
// Include with <> instead of "" to avoid getting any in-source copy
// left on disk.
#include <testSystemTools.h>
23

Brad King's avatar
Brad King committed
24
static std::string GetLibName(const char* lname)
25 26
{
  // Construct proper name of lib
Brad King's avatar
Brad King committed
27
  std::string slname;
28 29
  slname = EXECUTABLE_OUTPUT_PATH;
#ifdef CMAKE_INTDIR
30
  slname += "/";
31 32
  slname += CMAKE_INTDIR;
#endif
33 34
  slname += "/";
  slname += kwsys::DynamicLoader::LibPrefix();
35 36 37 38 39 40 41
  slname += lname;
  slname += kwsys::DynamicLoader::LibExtension();

  return slname;
}

/* libname = Library name (proper prefix, proper extension)
42 43 44 45 46
 * System  = symbol to lookup in libname
 * r1: should OpenLibrary succeed ?
 * r2: should GetSymbolAddress succeed ?
 * r3: should CloseLibrary succeed ?
 */
47 48
static int TestDynamicLoader(const char* libname, const char* symbol, int r1,
                             int r2, int r3)
49
{
50
  std::cerr << "Testing: " << libname << std::endl;
51 52
  kwsys::DynamicLoader::LibraryHandle l =
    kwsys::DynamicLoader::OpenLibrary(libname);
53
  // If result is incompatible with expectation just fails (xor):
54 55
  if ((r1 && !l) || (!r1 && l)) {
    std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
56
    return 1;
57 58 59 60 61
  }
  kwsys::DynamicLoader::SymbolPointer f =
    kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
  if ((r2 && !f) || (!r2 && f)) {
    std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
62
    return 1;
63
  }
64
#ifndef __APPLE__
65
  int s = kwsys::DynamicLoader::CloseLibrary(l);
66 67
  if ((r3 && !s) || (!r3 && s)) {
    std::cerr << kwsys::DynamicLoader::LastError() << std::endl;
68
    return 1;
69
  }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
70 71
#else
  (void)r3;
72
#endif
73 74 75
  return 0;
}

76
int testDynamicLoader(int argc, char* argv[])
77
{
78 79
#if defined(_WIN32)
  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
Bill Hoffman's avatar
Bill Hoffman committed
80
#elif defined(__BEOS__) || defined(__HAIKU__)
81
  disable_debugger(1);
82
#endif
83
  int res = 0;
84
  if (argc == 3) {
85
    // User specify a libname and symbol to check.
86
    res = TestDynamicLoader(argv[1], argv[2], 1, 1, 1);
87
    return res;
88
  }
89 90 91

// dlopen() on Syllable before 11/22/2007 doesn't return 0 on error
#ifndef __SYLLABLE__
92
  // Make sure that inexistent lib is giving correct result
93
  res += TestDynamicLoader("azerty_", "foo_bar", 0, 0, 0);
94
  // Make sure that random binary file cannot be assimilated as dylib
95 96
  res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin",
                           "wp", 0, 0, 0);
97 98
#endif

99
#ifdef __linux__
100 101 102 103 104
  // This one is actually fun to test, since dlopen is by default
  // loaded...wonder why :)
  res += TestDynamicLoader("foobar.lib", "dlopen", 0, 1, 0);
  res += TestDynamicLoader("libdl.so", "dlopen", 1, 1, 1);
  res += TestDynamicLoader("libdl.so", "TestDynamicLoader", 1, 0, 1);
105
#endif
106
  // Now try on the generated library
Brad King's avatar
Brad King committed
107
  std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
108 109 110 111 112 113 114
  res += TestDynamicLoader(libname.c_str(), "dummy", 1, 0, 1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",
                           1, 1, 1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",
                           1, 0, 1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData", 1, 1, 1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData", 1, 0, 1);
115 116 117

  return res;
}