/*----------------------------------------------------------------------------*/ /* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #include "hal/Extensions.h" #include #include #include #include #include "hal/HAL.h" #if defined(WIN32) || defined(_WIN32) #include #else #include #endif #if defined(WIN32) || defined(_WIN32) #define DELIM ';' #define HTYPE HMODULE #define DLOPEN(a) LoadLibrary(a) #define DLSYM GetProcAddress #define DLCLOSE FreeLibrary #else #define DELIM ':' #define HTYPE void* #define PREFIX "lib" #define DLOPEN(a) dlopen(a, RTLD_LAZY) #define DLSYM dlsym #define DLCLOSE dlclose #endif namespace hal { namespace init { void InitializeExtensions() {} } // namespace init } // namespace hal extern "C" { int HAL_LoadOneExtension(const char* library) { int rc = 1; // It is expected and reasonable not to find an extra simulation wpi::outs() << "HAL Extensions: Attempting to load: " << wpi::sys::path::stem(library) << "\n"; wpi::outs().flush(); HTYPE handle = DLOPEN(library); #if !defined(WIN32) && !defined(_WIN32) if (!handle) { wpi::SmallString<128> libraryName("lib"); libraryName += library; #if defined(__APPLE__) libraryName += ".dylib"; #else libraryName += ".so"; #endif wpi::outs() << "HAL Extensions: Trying modified name: " << wpi::sys::path::stem(libraryName); wpi::outs().flush(); handle = DLOPEN(libraryName.c_str()); } #endif if (!handle) { wpi::outs() << "HAL Extensions: Failed to load library\n"; wpi::outs().flush(); return rc; } auto init = reinterpret_cast( DLSYM(handle, "HALSIM_InitExtension")); if (init) rc = (*init)(); if (rc != 0) { wpi::outs() << "HAL Extensions: Failed to load extension\n"; wpi::outs().flush(); DLCLOSE(handle); } else { wpi::outs() << "HAL Extensions: Successfully loaded extension\n"; wpi::outs().flush(); } return rc; } int HAL_LoadExtensions(void) { int rc = 1; wpi::SmallVector libraries; const char* e = std::getenv("HALSIM_EXTENSIONS"); if (!e) { wpi::outs() << "HAL Extensions: No extensions found\n"; wpi::outs().flush(); return rc; } wpi::StringRef env{e}; env.split(libraries, DELIM, -1, false); for (auto& libref : libraries) { wpi::SmallString<128> library(libref); rc = HAL_LoadOneExtension(library.c_str()); if (rc < 0) break; } return rc; } } // extern "C"