commit
06e629112d
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',
|
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
|
||||||
'png':'PNG C library | configure with PNG_LIBS & PNG_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/',
|
'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/',
|
'z':'Z compression library | more info: http://www.zlib.net/',
|
||||||
'm':'Basic math library, part of C++ stlib',
|
'm':'Basic math library, part of C++ stlib',
|
||||||
'pkg-config':'pkg-config tool | more info: http://pkg-config.freedesktop.org',
|
'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),
|
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',
|
('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc',
|
||||||
PathVariable.PathAccept),
|
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'),
|
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_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),
|
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
|
# Adding the required prerequisite library directories to the include path for
|
||||||
# compiling and the library path for linking, respectively.
|
# 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]
|
inc_path = env['%s_INCLUDES' % required]
|
||||||
lib_path = env['%s_LIBS' % required]
|
lib_path = env['%s_LIBS' % required]
|
||||||
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
|
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
|
||||||
|
@ -1140,7 +1137,6 @@ if not preconfigured:
|
||||||
|
|
||||||
LIBSHEADERS = [
|
LIBSHEADERS = [
|
||||||
['z', 'zlib.h', True,'C'],
|
['z', 'zlib.h', True,'C'],
|
||||||
['ltdl', 'ltdl.h', True,'C'],
|
|
||||||
[env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'],
|
[env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
// stl
|
// stl
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
struct lt__handle;
|
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
class PluginInfo;
|
class PluginInfo;
|
||||||
|
@ -57,7 +55,6 @@ private:
|
||||||
~datasource_cache();
|
~datasource_cache();
|
||||||
std::map<std::string,boost::shared_ptr<PluginInfo> > plugins_;
|
std::map<std::string,boost::shared_ptr<PluginInfo> > plugins_;
|
||||||
bool registered_;
|
bool registered_;
|
||||||
bool insert(std::string const& name,lt__handle * const module);
|
|
||||||
std::vector<std::string> plugin_directories_;
|
std::vector<std::string> plugin_directories_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,21 +29,29 @@
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// ltdl
|
|
||||||
#include <ltdl.h>
|
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Opaque structure for handle
|
||||||
|
typedef struct _mapnik_lib_t mapnik_lib_t;
|
||||||
|
|
||||||
class PluginInfo : mapnik::noncopyable
|
class PluginInfo : mapnik::noncopyable
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
lt_dlhandle module_;
|
|
||||||
public:
|
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();
|
~PluginInfo();
|
||||||
std::string const& name() const;
|
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']
|
system = 'boost_system%s' % env['BOOST_APPEND']
|
||||||
|
|
||||||
# clear out and re-set libs for this env
|
# 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']:
|
if env['PROJ']:
|
||||||
lib_env['LIBS'].append('proj')
|
lib_env['LIBS'].append('proj')
|
||||||
|
|
|
@ -32,12 +32,8 @@
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem/operations.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
// ltdl
|
|
||||||
#include <ltdl.h>
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
@ -49,12 +45,12 @@ bool is_input_plugin(std::string const& filename)
|
||||||
|
|
||||||
datasource_cache::datasource_cache()
|
datasource_cache::datasource_cache()
|
||||||
{
|
{
|
||||||
if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
|
PluginInfo::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource_cache::~datasource_cache()
|
datasource_cache::~datasource_cache()
|
||||||
{
|
{
|
||||||
lt_dlexit();
|
PluginInfo::exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource_ptr datasource_cache::create(parameters const& params)
|
datasource_ptr datasource_cache::create(parameters const& params)
|
||||||
|
@ -87,23 +83,22 @@ datasource_ptr datasource_cache::create(parameters const& params)
|
||||||
throw config_error(s);
|
throw config_error(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!itr->second->handle())
|
if (!itr->second->valid())
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Cannot load library: ") +
|
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
|
// http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__extension__
|
__extension__
|
||||||
#endif
|
#endif
|
||||||
create_ds* create_datasource =
|
create_ds* create_datasource = reinterpret_cast<create_ds*>(itr->second->get_symbol("create"));
|
||||||
reinterpret_cast<create_ds*>(lt_dlsym(itr->second->handle(), "create"));
|
|
||||||
|
|
||||||
if (!create_datasource)
|
if (!create_datasource)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Cannot load symbols: ") +
|
throw std::runtime_error(std::string("Cannot load symbols: ") +
|
||||||
lt_dlerror());
|
itr->second->get_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAPNIK_LOG
|
#ifdef MAPNIK_LOG
|
||||||
|
@ -129,12 +124,6 @@ datasource_ptr datasource_cache::create(parameters const& params)
|
||||||
return ds;
|
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()
|
std::string datasource_cache::plugin_directories()
|
||||||
{
|
{
|
||||||
return boost::algorithm::join(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;
|
bool success = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lt_dlhandle module = lt_dlopen(str.c_str());
|
boost::shared_ptr<PluginInfo> plugin = boost::make_shared<PluginInfo>(filename,"datasource_name");
|
||||||
if (module)
|
if (plugin->valid())
|
||||||
{
|
{
|
||||||
// http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
|
if (plugin->name().empty())
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_ERROR(datasource_cache)
|
MAPNIK_LOG_ERROR(datasource_cache)
|
||||||
<< "Problem loading plugin library '"
|
<< "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
|
else
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_ERROR(datasource_cache)
|
MAPNIK_LOG_ERROR(datasource_cache)
|
||||||
<< "Problem loading plugin library: "
|
<< "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)
|
catch (std::exception const& ex)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_ERROR(datasource_cache)
|
MAPNIK_LOG_ERROR(datasource_cache)
|
||||||
<< "Exception caught while loading plugin library: "
|
<< "Exception caught while loading plugin library: "
|
||||||
<< str << " (" << ex.what() << ")";
|
<< filename << " (" << ex.what() << ")";
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,30 +21,86 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/plugin.hpp>
|
#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
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
PluginInfo::PluginInfo (std::string const& name,const lt_dlhandle module)
|
struct _mapnik_lib_t {
|
||||||
:name_(name),module_(module) {}
|
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()
|
PluginInfo::~PluginInfo()
|
||||||
{
|
{
|
||||||
if (module_)
|
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
|
std::string const& PluginInfo::name() const
|
||||||
{
|
{
|
||||||
return name_;
|
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