diff --git a/SConstruct b/SConstruct index bae36b787..03f8ee76a 100644 --- a/SConstruct +++ b/SConstruct @@ -443,6 +443,7 @@ pickle_store = [# Scons internal variables 'PYTHON_SYS_PREFIX', 'COLOR_PRINT', 'HAS_CAIRO', + 'MAPNIK_HAS_DLFCN', 'HAS_PYCAIRO', 'HAS_LIBXML2', 'PYTHON_IS_64BIT', @@ -829,6 +830,24 @@ int main() rm_path(item,'CPPPATH',context.env) return ret +def CheckHasDlfcn(context, silent=False): + if not silent: + context.Message('Checking for dlfcn.h support ... ') + ret = context.TryCompile(""" + +#include + +int main() +{ + return 0; +} + +""", '.cpp') + if silent: + context.did_show_result=1 + context.Result(ret) + return ret + def GetBoostLibVersion(context): ret = context.TryRun(""" @@ -989,6 +1008,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths, 'FindBoost' : FindBoost, 'CheckBoost' : CheckBoost, 'CheckCairoHasFreetype' : CheckCairoHasFreetype, + 'CheckHasDlfcn' : CheckHasDlfcn, 'GetBoostLibVersion' : GetBoostLibVersion, 'parse_config' : parse_config, 'parse_pg_config' : parse_pg_config, @@ -1199,6 +1219,11 @@ if not preconfigured: ['harfbuzz', 'harfbuzz/hb.h',True,'C++'] ] + if conf.CheckHasDlfcn(): + env.Append(CPPDEFINES = '-DMAPNIK_HAS_DLCFN') + else: + env['SKIPPED_DEPS'].extend(['dlfcn']) + OPTIONAL_LIBSHEADERS = [] if env['JPEG']: diff --git a/src/plugin.cpp b/src/plugin.cpp index c905f3135..0e751c161 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -31,7 +31,9 @@ #define dlclose FreeLibrary #define dlerror GetLastError #else - #include + #ifdef MAPNIK_HAS_DLCFN + #include + #endif #define handle void * #endif @@ -52,29 +54,44 @@ PluginInfo::PluginInfo(std::string const& filename, { #ifdef _WINDOWS if (module_) module_->dl = LoadLibraryA(filename.c_str()); + if (module_ && module_->dl) + { + name_func* name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); + if (name) name_ = name(); + } #else + #ifdef MAPNIK_HAS_DLCFN if (module_) module_->dl = dlopen(filename.c_str(),RTLD_LAZY); -#endif if (module_ && module_->dl) { name_func name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); if (name) name_ = name(); } + #else + throw std::runtime_error("no support for loading dynamic objects (Mapnik not compiled with -DMAPNIK_HAS_DLCFN)"); + #endif +#endif } PluginInfo::~PluginInfo() { if (module_) { +#ifdef MAPNIK_HAS_DLCFN if (module_->dl) dlclose(module_->dl),module_->dl=0; delete module_; +#endif } } void * PluginInfo::get_symbol(std::string const& sym_name) const { +#ifdef MAPNIK_HAS_DLCFN return static_cast(dlsym(module_->dl, sym_name.c_str())); +#else + return NULL; +#endif } std::string const& PluginInfo::name() const