blob: e84c354c2739fcdc452d7da5c848b49bed3b2ed6 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -08002/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
Brian Silverman41cdd3e2019-01-19 19:48:58 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "hal/Extensions.h"
9
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080010#include <wpi/Path.h>
Brian Silverman41cdd3e2019-01-19 19:48:58 -080011#include <wpi/SmallString.h>
12#include <wpi/StringRef.h>
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080013#include <wpi/raw_ostream.h>
Brian Silverman41cdd3e2019-01-19 19:48:58 -080014
15#include "hal/HAL.h"
16
17#if defined(WIN32) || defined(_WIN32)
18#include <windows.h>
19#else
20#include <dlfcn.h>
21#endif
22
23#if defined(WIN32) || defined(_WIN32)
24#define DELIM ';'
25#define HTYPE HMODULE
26#define DLOPEN(a) LoadLibrary(a)
27#define DLSYM GetProcAddress
28#define DLCLOSE FreeLibrary
29#else
30#define DELIM ':'
31#define HTYPE void*
32#define PREFIX "lib"
33#define DLOPEN(a) dlopen(a, RTLD_LAZY)
34#define DLSYM dlsym
35#define DLCLOSE dlclose
36#endif
37
38namespace hal {
39namespace init {
40void InitializeExtensions() {}
41} // namespace init
42} // namespace hal
43
44extern "C" {
45
46int HAL_LoadOneExtension(const char* library) {
47 int rc = 1; // It is expected and reasonable not to find an extra simulation
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080048 wpi::outs() << "HAL Extensions: Attempting to load: "
49 << wpi::sys::path::stem(library) << "\n";
50 wpi::outs().flush();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080051 HTYPE handle = DLOPEN(library);
52#if !defined(WIN32) && !defined(_WIN32)
53 if (!handle) {
54 wpi::SmallString<128> libraryName("lib");
55 libraryName += library;
56#if defined(__APPLE__)
57 libraryName += ".dylib";
58#else
59 libraryName += ".so";
60#endif
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080061 wpi::outs() << "HAL Extensions: Trying modified name: "
62 << wpi::sys::path::stem(libraryName);
63 wpi::outs().flush();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080064 handle = DLOPEN(libraryName.c_str());
65 }
66#endif
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080067 if (!handle) {
68 wpi::outs() << "HAL Extensions: Failed to load library\n";
69 wpi::outs().flush();
70 return rc;
71 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -080072
73 auto init = reinterpret_cast<halsim_extension_init_func_t*>(
74 DLSYM(handle, "HALSIM_InitExtension"));
75
76 if (init) rc = (*init)();
77
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080078 if (rc != 0) {
79 wpi::outs() << "HAL Extensions: Failed to load extension\n";
80 wpi::outs().flush();
81 DLCLOSE(handle);
82 } else {
83 wpi::outs() << "HAL Extensions: Successfully loaded extension\n";
84 wpi::outs().flush();
85 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -080086 return rc;
87}
88
89int HAL_LoadExtensions(void) {
90 int rc = 1;
91 wpi::SmallVector<wpi::StringRef, 2> libraries;
92 const char* e = std::getenv("HALSIM_EXTENSIONS");
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080093 if (!e) {
94 wpi::outs() << "HAL Extensions: No extensions found\n";
95 wpi::outs().flush();
96 return rc;
97 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -080098 wpi::StringRef env{e};
99 env.split(libraries, DELIM, -1, false);
100 for (auto& libref : libraries) {
101 wpi::SmallString<128> library(libref);
102 rc = HAL_LoadOneExtension(library.c_str());
103 if (rc < 0) break;
104 }
105 return rc;
106}
107
108} // extern "C"