Opts: Make singleton; senseApi: check senseApiLibPath, get senseApiDescFn pointer.
* OptionsParser now has a singleton.
* We now use the cmdline opt -p <senseApiLibPath>, and search for
the specified library in:
* senseApiLibPath, then CWD, then the place where our executable
is running from, and then finally we let the hosting OS do
its own search.
* We now call dlsym() on dlopen()'d libs to to get the senseApiDescFn
pointer.
This commit is contained in:
@@ -16,6 +16,12 @@ public:
|
|||||||
void dumpOptions() const;
|
void dumpOptions() const;
|
||||||
std::string getUsage() const;
|
std::string getUsage() const;
|
||||||
|
|
||||||
|
static OptionParser &getOptions(void)
|
||||||
|
{
|
||||||
|
static OptionParser options;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string senseApiLibPath;
|
std::string senseApiLibPath;
|
||||||
std::vector<std::string> senseApiLibs;
|
std::vector<std::string> senseApiLibs;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
class SenseApiLib
|
class SenseApiLib
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef const CSenseApiDesc *(SenseApiDescGetterFn)(void);
|
typedef const CSenseApiDesc* (SenseApiDescGetterFn)(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SenseApiLib(const std::string& path)
|
SenseApiLib(const std::string& path)
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
* This getter function should be visible to dlsym() so that Harikoff can
|
* This getter function should be visible to dlsym() so that Harikoff can
|
||||||
* find it in the lib after loading it, and call it.
|
* find it in the lib after loading it, and call it.
|
||||||
*/
|
*/
|
||||||
SenseApiDescGetterFn *getSenseApiDescriptor;
|
std::function<SenseApiDescGetterFn> getSenseApiDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Harikoff will call the `getSenseApiDescriptor` getter function and
|
* @brief Harikoff will call the `getSenseApiDescriptor` getter function and
|
||||||
|
|||||||
@@ -1,19 +1,63 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <filesystem>
|
||||||
#include <senseApis/senseApiManager.h>
|
#include <senseApis/senseApiManager.h>
|
||||||
#include <senseApis/senseApiLib.h>
|
#include <senseApis/senseApiLib.h>
|
||||||
|
#include <opts.h>
|
||||||
|
#include <user/senseApiDesc.h>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace hk {
|
namespace hk {
|
||||||
namespace sense_api {
|
namespace sense_api {
|
||||||
|
|
||||||
|
static std::optional<std::string> findLibraryPath(
|
||||||
|
const std::string& libraryPath)
|
||||||
|
{
|
||||||
|
std::vector<std::string> searchPaths = {
|
||||||
|
OptionParser::getOptions().senseApiLibPath,
|
||||||
|
fs::current_path().string(),
|
||||||
|
fs::path("/proc/self/exe").parent_path().string()
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& path : searchPaths)
|
||||||
|
{
|
||||||
|
fs::path fullPath = fs::path(path) / libraryPath;
|
||||||
|
if (fs::exists(fullPath))
|
||||||
|
{
|
||||||
|
return fullPath.string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << std::string(__func__) + ": library '"
|
||||||
|
+ libraryPath + "' isn't in search bespoke search paths: ";
|
||||||
|
for (const auto& path : searchPaths)
|
||||||
|
{
|
||||||
|
std::cerr << path << " ";
|
||||||
|
}
|
||||||
|
std::cerr << std::endl;
|
||||||
|
std::cerr << "Trying to load " + libraryPath + " from system default search "
|
||||||
|
"paths\n";
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
||||||
{
|
{
|
||||||
auto lib = std::make_unique<SenseApiLib>(libraryPath);
|
std::optional<std::string> fullPath = findLibraryPath(libraryPath);
|
||||||
|
auto lib = std::make_unique<SenseApiLib>(fullPath.value_or(libraryPath));
|
||||||
|
|
||||||
// Clear any existing error
|
// Clear any existing error
|
||||||
dlerror();
|
dlerror();
|
||||||
lib->handle.reset(dlopen(libraryPath.c_str(), RTLD_LAZY));
|
lib->handle.reset(dlopen(lib->libraryPath.c_str(), RTLD_LAZY));
|
||||||
|
if (!lib->handle && fullPath.has_value())
|
||||||
|
{
|
||||||
|
// Fallback to using the supplied libraryPath
|
||||||
|
dlerror();
|
||||||
|
lib->handle.reset(dlopen(libraryPath.c_str(), RTLD_LAZY));
|
||||||
|
}
|
||||||
|
|
||||||
if (!lib->handle)
|
if (!lib->handle)
|
||||||
{
|
{
|
||||||
std::string error = dlerror()
|
std::string error = dlerror()
|
||||||
@@ -25,6 +69,18 @@ SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
|||||||
+ error);
|
+ error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize getSenseApiDescriptor
|
||||||
|
auto func = reinterpret_cast<SenseApiLib::SenseApiDescGetterFn*>(
|
||||||
|
dlsym(lib->handle.get(), HK_SENSE_API_DESC_GETTER_FN_NAME));
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string(__func__) + ": dlsym("
|
||||||
|
HK_SENSE_API_DESC_GETTER_FN_NAME ") failed for library '"
|
||||||
|
+ lib->libraryPath + "'");
|
||||||
|
}
|
||||||
|
lib->getSenseApiDescriptor = func;
|
||||||
|
|
||||||
senseApiLibs.push_back(std::move(lib));
|
senseApiLibs.push_back(std::move(lib));
|
||||||
return *senseApiLibs.back();
|
return *senseApiLibs.back();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
#include <mind.h>
|
#include <mind.h>
|
||||||
#include <deviceManager/deviceManager.h>
|
#include <deviceManager/deviceManager.h>
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
OptionParser options;
|
OptionParser &options = OptionParser::getOptions();
|
||||||
hk::Mind mind;
|
hk::Mind mind;
|
||||||
|
|
||||||
std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
|
std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user