diff options
| -rw-r--r-- | host/lib/CMakeLists.txt | 21 | ||||
| -rw-r--r-- | host/lib/load_modules.cpp | 117 | ||||
| -rw-r--r-- | host/lib/simple_device.cpp | 1 | ||||
| -rw-r--r-- | host/test/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | host/test/module_test.cpp | 26 | 
5 files changed, 171 insertions, 5 deletions
| diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 563ffb340..22fbde265 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -22,6 +22,7 @@ SET(libuhd_sources      device.cpp      device_addr.cpp      gain_handler.cpp +    load_modules.cpp      metadata.cpp      simple_device.cpp      time_spec.cpp @@ -56,11 +57,29 @@ LIST(APPEND libuhd_sources  )  ######################################################################## +# Setup defines for module loading +######################################################################## +INCLUDE(CheckIncludeFileCXX) + +CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) +CHECK_INCLUDE_FILE_CXX(Winbase.h HAVE_WINBASE_H) + +IF(HAVE_DLFCN_H) +    MESSAGE(STATUS "Module loading supported through dlopen...") +    ADD_DEFINITIONS(-DHAVE_DLFCN_H) +ELSEIF(HAVE_WINBASE_H) +    MESSAGE(STATUS "Module loading supported through LoadLibrary...") +    ADD_DEFINITIONS(-DHAVE_WINBASE_H) +ELSE(HAVE_DLFCN_H) +    MESSAGE(STATUS "Module loading not supported...") +ENDIF(HAVE_DLFCN_H) + +########################################################################  # Setup libuhd library  ########################################################################  ADD_LIBRARY(uhd SHARED ${libuhd_sources}) -TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES} ${CMAKE_DL_LIBS})  SET_TARGET_PROPERTIES(uhd PROPERTIES DEFINE_SYMBOL "UHD_DLL_EXPORTS") diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp new file mode 100644 index 000000000..700afcd3f --- /dev/null +++ b/host/lib/load_modules.cpp @@ -0,0 +1,117 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils.hpp> +#include <boost/format.hpp> +#include <boost/foreach.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <iostream> +#include <stdexcept> +#include <cstdlib> + +namespace fs = boost::filesystem; + +/*********************************************************************** + * Module Load Function + **********************************************************************/ +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> + +static void load_module(const std::string &file_name){ +    if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ +        throw std::runtime_error(str( +            boost::format("dlopen failed to load \"%s\"") % file_name +        )); +    } +} + +#elif HAVE_WINBASE_H +#include <Winbase.h> + +static void load_module(const std::string &file_name){ +    if (LoadLibrary(file_name.c_str()) == NULL){ +        throw std::runtime_error(str( +            boost::format("LoadLibrary failed to load \"%s\"") % file_name +        )); +    } +} + +#else + +static void load_module(const std::string &file_name){ +    throw std::runtime_error(str( +        boost::format("Module loading not supported: Cannot load \"%s\"") % file_name +    )); +} + +#endif + +/*********************************************************************** + * Load Modules + **********************************************************************/ +/*! + * Load all modules in a given path. + * This will recurse into sub-directories. + * Does not throw, prints to std error. + * \param path the filesystem path + */ +static void load_path(const fs::path &path){ +    if (not fs::exists(path)){ +        std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl; +        return; +    } + +    //try to load the files in this path +    if (fs::is_directory(path)){ +        for( +            fs::directory_iterator dir_itr(path); +            dir_itr != fs::directory_iterator(); +            ++dir_itr +        ){ +            load_path(dir_itr->path()); +        } +        return; +    } + +    //its not a directory, try to load it +    try{ +        load_module(path.file_string()); +    } +    catch(const std::exception &err){ +        std::cerr << boost::format("Error: %s") % err.what() << std::endl; +    } +} + +/*! + * Load all the modules given by the module path enviroment variable. + * The path variable may be several paths split by path separators. + */ +STATIC_BLOCK(load_modules){ +    //get the environment variable module path +    char *env_module_path = std::getenv("UHD_MODULE_PATH"); +    if (env_module_path == NULL) return; + +    //split the path at the path separators +    std::vector<std::string> module_paths; +    boost::split(module_paths, env_module_path, boost::is_any_of(":;")); + +    //load modules in each path +    BOOST_FOREACH(const std::string &module_path, module_paths){ +        load_path(fs::system_complete(fs::path(module_path))); +    } +} diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index 045318c6b..ba1966e0d 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -21,7 +21,6 @@  #include <uhd/props.hpp>  #include <uhd/types.hpp>  #include <boost/algorithm/string.hpp> -#include <boost/algorithm/string/trim.hpp>  #include <boost/foreach.hpp>  #include <boost/format.hpp>  #include <stdexcept> diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index b1d5924c7..1791d9082 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -15,7 +15,9 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # - +######################################################################## +# unit test suite +########################################################################  ADD_EXECUTABLE(main_test      main_test.cpp      addr_test.cpp @@ -23,7 +25,10 @@ ADD_EXECUTABLE(main_test      vrt_test.cpp      wax_test.cpp  ) -  TARGET_LINK_LIBRARIES(main_test uhd) -  ADD_TEST(test main_test) + +######################################################################## +# demo of a loadable module +######################################################################## +ADD_LIBRARY(module_test MODULE module_test.cpp) diff --git a/host/test/module_test.cpp b/host/test/module_test.cpp new file mode 100644 index 000000000..71721ef90 --- /dev/null +++ b/host/test/module_test.cpp @@ -0,0 +1,26 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils.hpp> +#include <iostream> + +STATIC_BLOCK(module_test){ +    std::cout << "---------------------------------------" << std::endl; +    std::cout << "-- Good news, everyone!" << std::endl; +    std::cout << "-- The test module has been loaded." << std::endl; +    std::cout << "---------------------------------------" << std::endl; +} | 
