blob: 951ad10426e85bbc34bd7c5dccda3a29e377d36e [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
James Kuszmaul4b81d302019-12-14 20:53:14 -080044static bool& GetShowNotFoundMessage() {
45 static bool showMsg = true;
46 return showMsg;
47}
48
Brian Silverman41cdd3e2019-01-19 19:48:58 -080049extern "C" {
50
51int HAL_LoadOneExtension(const char* library) {
52 int rc = 1; // It is expected and reasonable not to find an extra simulation
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080053 wpi::outs() << "HAL Extensions: Attempting to load: "
54 << wpi::sys::path::stem(library) << "\n";
55 wpi::outs().flush();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080056 HTYPE handle = DLOPEN(library);
57#if !defined(WIN32) && !defined(_WIN32)
58 if (!handle) {
59 wpi::SmallString<128> libraryName("lib");
60 libraryName += library;
61#if defined(__APPLE__)
62 libraryName += ".dylib";
63#else
64 libraryName += ".so";
65#endif
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080066 wpi::outs() << "HAL Extensions: Trying modified name: "
67 << wpi::sys::path::stem(libraryName);
68 wpi::outs().flush();
Brian Silverman41cdd3e2019-01-19 19:48:58 -080069 handle = DLOPEN(libraryName.c_str());
70 }
71#endif
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080072 if (!handle) {
73 wpi::outs() << "HAL Extensions: Failed to load library\n";
74 wpi::outs().flush();
75 return rc;
76 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -080077
78 auto init = reinterpret_cast<halsim_extension_init_func_t*>(
79 DLSYM(handle, "HALSIM_InitExtension"));
80
81 if (init) rc = (*init)();
82
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080083 if (rc != 0) {
84 wpi::outs() << "HAL Extensions: Failed to load extension\n";
85 wpi::outs().flush();
86 DLCLOSE(handle);
87 } else {
88 wpi::outs() << "HAL Extensions: Successfully loaded extension\n";
89 wpi::outs().flush();
90 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -080091 return rc;
92}
93
94int HAL_LoadExtensions(void) {
95 int rc = 1;
96 wpi::SmallVector<wpi::StringRef, 2> libraries;
97 const char* e = std::getenv("HALSIM_EXTENSIONS");
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080098 if (!e) {
James Kuszmaul4b81d302019-12-14 20:53:14 -080099 if (GetShowNotFoundMessage()) {
100 wpi::outs() << "HAL Extensions: No extensions found\n";
101 wpi::outs().flush();
102 }
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800103 return rc;
104 }
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800105 wpi::StringRef env{e};
106 env.split(libraries, DELIM, -1, false);
107 for (auto& libref : libraries) {
108 wpi::SmallString<128> library(libref);
109 rc = HAL_LoadOneExtension(library.c_str());
110 if (rc < 0) break;
111 }
112 return rc;
113}
114
James Kuszmaul4b81d302019-12-14 20:53:14 -0800115void HAL_SetShowExtensionsNotFoundMessages(HAL_Bool showMessage) {
116 GetShowNotFoundMessage() = showMessage;
117}
118
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800119} // extern "C"