remove ltdl to reduce dependencies and because calling dlopen/LoadLibrary is easy
This commit is contained in:
parent
a8e2ef7cc7
commit
79a216f349
6 changed files with 101 additions and 61 deletions
|
@ -68,7 +68,6 @@ pretty_dep_names = {
|
|||
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
|
||||
'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES',
|
||||
'icuuc':'ICU C++ library | configure with ICU_LIBS & ICU_INCLUDES or use ICU_LIB_NAME to specify custom lib name | more info: http://site.icu-project.org/',
|
||||
'ltdl':'GNU Libtool | more info: http://www.gnu.org/software/libtool',
|
||||
'z':'Z compression library | more info: http://www.zlib.net/',
|
||||
'm':'Basic math library, part of C++ stlib',
|
||||
'pkg-config':'pkg-config tool | more info: http://pkg-config.freedesktop.org',
|
||||
|
@ -309,8 +308,6 @@ opts.AddVariables(
|
|||
PathVariable('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
|
||||
('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc',
|
||||
PathVariable.PathAccept),
|
||||
PathVariable('LTDL_INCLUDES', 'Search path for libltdl (part of libtool) include files', '/usr/include', PathVariable.PathAccept),
|
||||
PathVariable('LTDL_LIBS','Search path for libltdl (ltdl.h) library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
|
||||
BoolVariable('PNG', 'Build Mapnik with PNG read and write support', 'True'),
|
||||
PathVariable('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include', PathVariable.PathAccept),
|
||||
PathVariable('PNG_LIBS','Search path for libpng library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
|
||||
|
@ -1115,7 +1112,7 @@ if not preconfigured:
|
|||
|
||||
# Adding the required prerequisite library directories to the include path for
|
||||
# compiling and the library path for linking, respectively.
|
||||
for required in ('ICU', 'SQLITE', 'LTDL'):
|
||||
for required in ('ICU', 'SQLITE'):
|
||||
inc_path = env['%s_INCLUDES' % required]
|
||||
lib_path = env['%s_LIBS' % required]
|
||||
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
|
||||
|
@ -1140,7 +1137,6 @@ if not preconfigured:
|
|||
|
||||
LIBSHEADERS = [
|
||||
['z', 'zlib.h', True,'C'],
|
||||
['ltdl', 'ltdl.h', True,'C'],
|
||||
[env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'],
|
||||
]
|
||||
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
// stl
|
||||
#include <map>
|
||||
|
||||
struct lt__handle;
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class PluginInfo;
|
||||
|
@ -57,7 +55,6 @@ private:
|
|||
~datasource_cache();
|
||||
std::map<std::string,boost::shared_ptr<PluginInfo> > plugins_;
|
||||
bool registered_;
|
||||
bool insert(std::string const& name,lt__handle * const module);
|
||||
std::vector<std::string> plugin_directories_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,21 +29,29 @@
|
|||
// stl
|
||||
#include <string>
|
||||
|
||||
// ltdl
|
||||
#include <ltdl.h>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
// Opaque structure for handle
|
||||
typedef struct _mapnik_lib_t mapnik_lib_t;
|
||||
|
||||
class PluginInfo : mapnik::noncopyable
|
||||
{
|
||||
private:
|
||||
std::string name_;
|
||||
lt_dlhandle module_;
|
||||
public:
|
||||
PluginInfo (std::string const& name,const lt_dlhandle module);
|
||||
typedef const char * name_func();
|
||||
PluginInfo (std::string const& filename,
|
||||
std::string const& library_name);
|
||||
~PluginInfo();
|
||||
std::string const& name() const;
|
||||
lt_dlhandle handle() const;
|
||||
bool valid() const;
|
||||
std::string get_error() const;
|
||||
void * get_symbol(std::string const& sym_name) const;
|
||||
static void init();
|
||||
static void exit();
|
||||
private:
|
||||
std::string filename_;
|
||||
std::string name_;
|
||||
mapnik_lib_t * module_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ regex = 'boost_regex%s' % env['BOOST_APPEND']
|
|||
system = 'boost_system%s' % env['BOOST_APPEND']
|
||||
|
||||
# clear out and re-set libs for this env
|
||||
lib_env['LIBS'] = ['freetype','ltdl','z',env['ICU_LIB_NAME'],filesystem,system,regex]
|
||||
lib_env['LIBS'] = ['freetype','z',env['ICU_LIB_NAME'],filesystem,system,regex]
|
||||
|
||||
if env['PROJ']:
|
||||
lib_env['LIBS'].append('proj')
|
||||
|
|
|
@ -32,12 +32,8 @@
|
|||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
// ltdl
|
||||
#include <ltdl.h>
|
||||
|
||||
// stl
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
|
||||
namespace mapnik {
|
||||
|
@ -49,12 +45,12 @@ bool is_input_plugin(std::string const& filename)
|
|||
|
||||
datasource_cache::datasource_cache()
|
||||
{
|
||||
if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
|
||||
PluginInfo::init();
|
||||
}
|
||||
|
||||
datasource_cache::~datasource_cache()
|
||||
{
|
||||
lt_dlexit();
|
||||
PluginInfo::exit();
|
||||
}
|
||||
|
||||
datasource_ptr datasource_cache::create(parameters const& params)
|
||||
|
@ -87,23 +83,22 @@ datasource_ptr datasource_cache::create(parameters const& params)
|
|||
throw config_error(s);
|
||||
}
|
||||
|
||||
if (!itr->second->handle())
|
||||
if (!itr->second->valid())
|
||||
{
|
||||
throw std::runtime_error(std::string("Cannot load library: ") +
|
||||
lt_dlerror());
|
||||
itr->second->get_error());
|
||||
}
|
||||
|
||||
// http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
|
||||
#ifdef __GNUC__
|
||||
__extension__
|
||||
#endif
|
||||
create_ds* create_datasource =
|
||||
reinterpret_cast<create_ds*>(lt_dlsym(itr->second->handle(), "create"));
|
||||
create_ds* create_datasource = reinterpret_cast<create_ds*>(itr->second->get_symbol("create"));
|
||||
|
||||
if (!create_datasource)
|
||||
{
|
||||
throw std::runtime_error(std::string("Cannot load symbols: ") +
|
||||
lt_dlerror());
|
||||
itr->second->get_error());
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_LOG
|
||||
|
@ -129,12 +124,6 @@ datasource_ptr datasource_cache::create(parameters const& params)
|
|||
return ds;
|
||||
}
|
||||
|
||||
bool datasource_cache::insert(std::string const& type,const lt_dlhandle module)
|
||||
{
|
||||
return plugins_.insert(std::make_pair(type,boost::make_shared<PluginInfo>
|
||||
(type,module))).second;
|
||||
}
|
||||
|
||||
std::string datasource_cache::plugin_directories()
|
||||
{
|
||||
return boost::algorithm::join(plugin_directories_,", ");
|
||||
|
@ -185,47 +174,41 @@ void datasource_cache::register_datasources(std::string const& str)
|
|||
}
|
||||
}
|
||||
|
||||
bool datasource_cache::register_datasource(std::string const& str)
|
||||
bool datasource_cache::register_datasource(std::string const& filename)
|
||||
{
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
lt_dlhandle module = lt_dlopen(str.c_str());
|
||||
if (module)
|
||||
boost::shared_ptr<PluginInfo> plugin = boost::make_shared<PluginInfo>(filename,"datasource_name");
|
||||
if (plugin->valid())
|
||||
{
|
||||
// http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
|
||||
#ifdef __GNUC__
|
||||
__extension__
|
||||
#endif
|
||||
datasource_name* ds_name =
|
||||
reinterpret_cast<datasource_name*>(lt_dlsym(module, "datasource_name"));
|
||||
if (ds_name && insert(ds_name(),module))
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(datasource_cache)
|
||||
<< "datasource_cache: Registered="
|
||||
<< ds_name();
|
||||
|
||||
success = true;
|
||||
}
|
||||
else if (!ds_name)
|
||||
if (plugin->name().empty())
|
||||
{
|
||||
MAPNIK_LOG_ERROR(datasource_cache)
|
||||
<< "Problem loading plugin library '"
|
||||
<< str << "' (plugin is lacking compatible interface)";
|
||||
<< filename << "' (plugin is lacking compatible interface)";
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins_.insert(std::make_pair(plugin->name(),plugin));
|
||||
MAPNIK_LOG_DEBUG(datasource_cache)
|
||||
<< "datasource_cache: Registered="
|
||||
<< plugin->name();
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_ERROR(datasource_cache)
|
||||
<< "Problem loading plugin library: "
|
||||
<< str << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)";
|
||||
<< filename << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)";
|
||||
}
|
||||
}
|
||||
catch (std::exception const& ex)
|
||||
{
|
||||
MAPNIK_LOG_ERROR(datasource_cache)
|
||||
<< "Exception caught while loading plugin library: "
|
||||
<< str << " (" << ex.what() << ")";
|
||||
<< filename << " (" << ex.what() << ")";
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -21,30 +21,86 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/plugin.hpp>
|
||||
#include <ltdl.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#define handle HMODULE
|
||||
#define dlsym GetProcAddress
|
||||
#define dlclose FreeLibrary
|
||||
#define dlerror GetLastError
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define handle void *
|
||||
#endif
|
||||
|
||||
// TODO - handle/report dlerror
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
PluginInfo::PluginInfo (std::string const& name,const lt_dlhandle module)
|
||||
:name_(name),module_(module) {}
|
||||
struct _mapnik_lib_t {
|
||||
handle dl;
|
||||
};
|
||||
|
||||
PluginInfo::PluginInfo(std::string const& filename,
|
||||
std::string const& library_name)
|
||||
: filename_(filename),
|
||||
name_(),
|
||||
module_(new mapnik_lib_t)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
if (module_) module_->dl = LoadLibraryA(filename.c_str());
|
||||
#else
|
||||
if (module_) module_->dl = dlopen(filename.c_str(),RTLD_LAZY);
|
||||
#endif
|
||||
if (module_ && module_->dl)
|
||||
{
|
||||
name_func* name = reinterpret_cast<name_func*>(dlsym(module_->dl, library_name.c_str()));
|
||||
if (name) name_ = name();
|
||||
}
|
||||
}
|
||||
|
||||
PluginInfo::~PluginInfo()
|
||||
{
|
||||
if (module_)
|
||||
{
|
||||
lt_dlclose(module_),module_=0;
|
||||
if (module_->dl) dlclose(module_->dl),module_->dl=0;
|
||||
delete module_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void * PluginInfo::get_symbol(std::string const& sym_name) const
|
||||
{
|
||||
return dlsym(module_->dl, sym_name.c_str());
|
||||
}
|
||||
|
||||
std::string const& PluginInfo::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
lt_dlhandle PluginInfo::handle() const
|
||||
bool PluginInfo::valid() const
|
||||
{
|
||||
return module_;
|
||||
if (module_ && module_->dl && !name_.empty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string PluginInfo::get_error() const
|
||||
{
|
||||
return std::string("could not open: '") + name_ + "'";
|
||||
}
|
||||
|
||||
void PluginInfo::init()
|
||||
{
|
||||
// do any initialization needed
|
||||
}
|
||||
|
||||
void PluginInfo::exit()
|
||||
{
|
||||
// do any shutdown needed
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue