root / host / lib / load_modules.cpp @ 38995223
History | View | Annotate | Download (4.48 KB)
| 1 | d66efda6 | Josh Blum | //
|
|---|---|---|---|
| 2 | // Copyright 2010 Ettus Research LLC
|
||
| 3 | //
|
||
| 4 | // This program is free software: you can redistribute it and/or modify
|
||
| 5 | // it under the terms of the GNU General Public License as published by
|
||
| 6 | // the Free Software Foundation, either version 3 of the License, or
|
||
| 7 | // (at your option) any later version.
|
||
| 8 | //
|
||
| 9 | // This program is distributed in the hope that it will be useful,
|
||
| 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 12 | // GNU General Public License for more details.
|
||
| 13 | //
|
||
| 14 | // You should have received a copy of the GNU General Public License
|
||
| 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
| 16 | //
|
||
| 17 | |||
| 18 | 52df9afd | Josh Blum | #include <uhd/utils/static.hpp> |
| 19 | d66efda6 | Josh Blum | #include <boost/format.hpp> |
| 20 | #include <boost/foreach.hpp> |
||
| 21 | #include <boost/algorithm/string.hpp> |
||
| 22 | #include <boost/filesystem.hpp> |
||
| 23 | 46699094 | Josh Blum | #include <boost/program_options.hpp> |
| 24 | d66efda6 | Josh Blum | #include <iostream> |
| 25 | #include <stdexcept> |
||
| 26 | |||
| 27 | 46699094 | Josh Blum | namespace po = boost::program_options;
|
| 28 | d66efda6 | Josh Blum | namespace fs = boost::filesystem;
|
| 29 | |||
| 30 | /***********************************************************************
|
||
| 31 | * Module Load Function
|
||
| 32 | **********************************************************************/
|
||
| 33 | #ifdef HAVE_DLFCN_H
|
||
| 34 | #include <dlfcn.h> |
||
| 35 | f4ccb204 | Josh Blum | static const std::string env_path_sep = ":"; |
| 36 | d66efda6 | Josh Blum | |
| 37 | static void load_module(const std::string &file_name){ |
||
| 38 | if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ |
||
| 39 | throw std::runtime_error(str(
|
||
| 40 | boost::format("dlopen failed to load \"%s\"") % file_name
|
||
| 41 | )); |
||
| 42 | } |
||
| 43 | } |
||
| 44 | |||
| 45 | 72927d98 | Josh Blum | #elif HAVE_WINDOWS_H
|
| 46 | ae02148f | Josh Blum | #include <windows.h> |
| 47 | f4ccb204 | Josh Blum | static const std::string env_path_sep = ";"; |
| 48 | d66efda6 | Josh Blum | |
| 49 | static void load_module(const std::string &file_name){ |
||
| 50 | if (LoadLibrary(file_name.c_str()) == NULL){ |
||
| 51 | throw std::runtime_error(str(
|
||
| 52 | boost::format("LoadLibrary failed to load \"%s\"") % file_name
|
||
| 53 | )); |
||
| 54 | } |
||
| 55 | } |
||
| 56 | |||
| 57 | #else
|
||
| 58 | f4ccb204 | Josh Blum | static const std::string env_path_sep = ":"; |
| 59 | d66efda6 | Josh Blum | |
| 60 | static void load_module(const std::string &file_name){ |
||
| 61 | throw std::runtime_error(str(
|
||
| 62 | boost::format("Module loading not supported: Cannot load \"%s\"") % file_name
|
||
| 63 | )); |
||
| 64 | } |
||
| 65 | |||
| 66 | #endif
|
||
| 67 | |||
| 68 | /***********************************************************************
|
||
| 69 | * Load Modules
|
||
| 70 | **********************************************************************/
|
||
| 71 | /*!
|
||
| 72 | * Load all modules in a given path.
|
||
| 73 | * This will recurse into sub-directories.
|
||
| 74 | * Does not throw, prints to std error.
|
||
| 75 | * \param path the filesystem path
|
||
| 76 | */
|
||
| 77 | static void load_path(const fs::path &path){ |
||
| 78 | if (not fs::exists(path)){ |
||
| 79 | std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl;
|
||
| 80 | return;
|
||
| 81 | } |
||
| 82 | |||
| 83 | //try to load the files in this path
|
||
| 84 | if (fs::is_directory(path)){
|
||
| 85 | for(
|
||
| 86 | fs::directory_iterator dir_itr(path); |
||
| 87 | dir_itr != fs::directory_iterator(); |
||
| 88 | ++dir_itr |
||
| 89 | ){
|
||
| 90 | load_path(dir_itr->path()); |
||
| 91 | } |
||
| 92 | return;
|
||
| 93 | } |
||
| 94 | |||
| 95 | //its not a directory, try to load it
|
||
| 96 | try{
|
||
| 97 | load_module(path.file_string()); |
||
| 98 | } |
||
| 99 | catch(const std::exception &err){ |
||
| 100 | std::cerr << boost::format("Error: %s") % err.what() << std::endl;
|
||
| 101 | } |
||
| 102 | } |
||
| 103 | |||
| 104 | 46699094 | Josh Blum | //! The string constant for the module path environment variable
|
| 105 | static const std::string MODULE_PATH_KEY = "UHD_MODULE_PATH"; |
||
| 106 | |||
| 107 | /*!
|
||
| 108 | * Name mapper function for the environment variable parser.
|
||
| 109 | * Map environment variable names (that we use) to option names.
|
||
| 110 | * \param the variable name
|
||
| 111 | * \return the option name or blank string
|
||
| 112 | */
|
||
| 113 | static std::string name_mapper(const std::string &var_name){ |
||
| 114 | if (var_name == MODULE_PATH_KEY) return var_name; |
||
| 115 | return ""; |
||
| 116 | } |
||
| 117 | |||
| 118 | d66efda6 | Josh Blum | /*!
|
| 119 | * Load all the modules given by the module path enviroment variable.
|
||
| 120 | * The path variable may be several paths split by path separators.
|
||
| 121 | */
|
||
| 122 | 52df9afd | Josh Blum | UHD_STATIC_BLOCK(load_modules){
|
| 123 | 46699094 | Josh Blum | //register the options
|
| 124 | std::string env_module_path;
|
||
| 125 | po::options_description desc("UHD Module Options");
|
||
| 126 | desc.add_options() |
||
| 127 | (MODULE_PATH_KEY.c_str(), po::value<std::string>(&env_module_path)->default_value("")) |
||
| 128 | ; |
||
| 129 | |||
| 130 | //parse environment variables
|
||
| 131 | po::variables_map vm; |
||
| 132 | po::store(po::parse_environment(desc, &name_mapper), vm); |
||
| 133 | po::notify(vm); |
||
| 134 | |||
| 135 | if (env_module_path == "") return; |
||
| 136 | //std::cout << "env_module_path: " << env_module_path << std::endl;
|
||
| 137 | d66efda6 | Josh Blum | |
| 138 | //split the path at the path separators
|
||
| 139 | std::vector<std::string> module_paths;
|
||
| 140 | f4ccb204 | Josh Blum | boost::split(module_paths, env_module_path, boost::is_any_of(env_path_sep)); |
| 141 | d66efda6 | Josh Blum | |
| 142 | //load modules in each path
|
||
| 143 | BOOST_FOREACH(const std::string &module_path, module_paths){ |
||
| 144 | load_path(fs::system_complete(fs::path(module_path))); |
||
| 145 | } |
||
| 146 | } |