<div dir="ltr"><div><div><div><div><div>Hi and Happy New Year, all.<br><br></div>I found time recently to make notes on a frustrating issue that I'm having with GEOS in the Shapely binary wheels for OS X that I'm publishing on PyPI. I'm not certain whether there's a GEOS bug, a dynamic loader bug, a ctypes bug, misuse of computers on my part, or all four. I'd really appreciate a bit of advice from anyone with more C++ and Mach-O wisdom that would rule out a few of these possibilities.<br><br></div>Here's the gist of it: Shapely uses dlopen (via Python's ctypes) to load libgeos_c.dylib at run time. The GEOS C++ library (libgeos-3.6.2.dylib, for example) is a dependent library of libgeos_c.dylib. I have been distributing the GEOS libs with my Shapely binaries for convenience of users, but Shapely also works with GEOS installed to the standard places on your system. I've never experienced or seen report of a problem with Shapely's loading of the GEOS libraries *in isolation* that hasn't been fixed.<br><br></div>My Fiona package for Python also depends on libgeos_c.dylib, but in the more familiar way: it's a dependent library of GDAL, which is loaded when Fiona's C extension modules are loaded in Python.<br><br></div>If we import fiona in a Python script and then import shapely from a binary wheel that includes GEOS libraries, the script will abort in either AbstractSTRtree::query or AbstractSTRtree::itemsTree because the dynamic casts yield null pointers. As far as I can tell, loading two copies of the C++ GEOS library is where the trouble starts. Is the trouble in the loader, the library code, or my builds? I do not know.<br><br></div>There's no problem on Linux. The Linux library loader may be more foolproof or the library code might be compiled more correctly in a way that I don't yet see. I'm using the following flags in my builds – the dual architecture build is the only thing that seems unusual to me.<br><pre>environment =
    MACOSX_DEPLOYMENT_TARGET=10.9
configure-options = 
    CFLAGS="-arch i386 -arch x86_64 -O2 -Wl,-S -Wall -Wstrict-prototypes"
    CXXFLAGS="-arch i386 -arch x86_64 -O2 -Wl,-S -Wall -Wstrict-prototypes"
    LDFLAGS="-arch i386 -arch x86_64"</pre><div><div><div><div><div><div><div>The thing that makes me suspect that there is a localized bug in GEOS is that loading the library twice doesn't lead to failures in computing areas, lengths, predicates, or WKT serializations. Only in the AbstractSTRtree module as far as I can tell.</div></div><div><br></div><div>I've made a ticket at <a href="https://trac.osgeo.org/geos/ticket/848">https://trac.osgeo.org/geos/ticket/848</a> and have attached a script that reproduces the problem as well as demonstrating that other GEOS modules are unaffected.</div><div><br></div><div>It's interesting, but mostly baffling and humbling to go so deep into the weeds of dynamic library loading. I'm over my head here and super grateful for insights and discussion.</div><div><br></div><div><div>-- <br><div class="gmail_signature">Sean Gillies</div>
</div></div></div></div></div></div></div></div>