[geos-devel] Is GEOS 3.11 C-API upward compatible with GEOS 3.9.0

Greg Troxel gdt at lexort.com
Mon Dec 6 06:36:29 PST 2021


"Regina Obe" <lr at pcorp.us> writes:

> It looks in the directory of the dependent executable first for dependencies
> and then looks in PATH for what it couldn't find in the direct path.
> I use the same trick (except export and $ signs)  on Debbie and Berrie (both
> Debian bots) and it works there too just overriding the 
> PATH
>
> Here is what Berrie64 build script looks like for example:
> https://git.osgeo.org/gitea/postgis/postgis/src/branch/master/ci/berrie64/cofigs.sh  #configuration where I flip the GEOS as needed
> https://git.osgeo.org/gitea/postgis/postgis/src/branch/master/ci/berrie64/pg_init_start.sh #postgresql startup script
>
> Though I think I had to set the LD_LIBRAY_PATH for building otherwise it
> would pick up the system installed GEOS and PostgreSQL  instead of my custom
> compiled one.

On UNIX/ELF, I don't think shared library resolution is affected by
PATH.  But LD_LIBRARY_PATH yes.

I'll simply accept that whatever env var setup you have on windows
causes shlib resolution to look in alternate places; that's pretty
clearly not the problem.

> All of these were compiled with CMake.  I haven't used libtool on GEOS since
> 3.6 or so..
> In GEOS 3.10.0 (and all cmake versions previous) -- the files in bin folder
> are just the way I like them:
> geos-config  geosop.exe  libgeos.dll  libgeos_c.dll

I am unfamiliar with Windows DLL naming culture.   Setting aside macOS
as mutant, ~all POSIX/ELF systems normally name shared libraries as

  libfoo.so.A.B.C
  A is major (or ABI breaks)
  B is minor (for new interfaces)
  C is micro (for bugfixes)

On my system, shp2pgsql has NEEDED libgeos_c.so.1" because that is the
ABI version it was built with.  And there is a symlink with that name

lrwxr-xr-x  1 root  wheel       14 Nov  3 17:53 /usr/pkg/lib/libgeos_c.so -> libgeos_c.so.1
lrwxr-xr-x  1 root  wheel       19 Nov  3 17:53 /usr/pkg/lib/libgeos_c.so.1 -> libgeos_c.so.1.16.0
-rwxr-xr-x  1 root  wheel   315936 Nov  3 17:53 /usr/pkg/lib/libgeos_c.so.1.16.0

This allows the older ABI to be still present (such as on base system
upgrades) and programs using the older ABI to find the version they need
and work.

It may be normal in windows not to do this, and I don't know if there if
the shlib version is internal and if it is chdcked when dynamic linking.
If it's not checked, this naming scheme is basically unsound.

> and ldd of libgeos_c.dll looks like:
> ldd /projects/geos/rel-3.10.0w64gcc81/bin/libgeos_c.dll
>         ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff968c30000)
>         KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff967c10000)
>         KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll
> (0x7ff9663f0000)
>         msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff968a70000)
>         libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x61440000)
>         libgeos.dll => /projects/geos/rel-3.10.0w64gcc81/bin/libgeos.dll
> (0x64c40000)
>         libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x6fc40000)
>         libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x64940000)
>         USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ff967a60000)
>         win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ff966770000)
>         GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ff966dd0000)
>         gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ff966950000)
>         msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ff966350000)
>         ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ff966af0000)
>         IMM32.DLL => /c/WINDOWS/System32/IMM32.DLL (0x7ff967560000)

So that finds the 3.10.0 you have pointed it to, and it's not clear
there is ABI version checking.

> In GEOS 3.10.1 (where things started sucking as far as file names go)
> geos-config  geosop.exe  libgeos-3.10.1.dll  libgeos_c-1.dll  
> (I do recall my libtool builds having the full name at least for the c++
> part and that libgeos_c-1.dll that is why I assumed it was to congeal the
> two systems). 

Ah, so now I get the -1.  Is this the normal way in windows to encode
the shared library version in the file?  In the C++ one, is "3.10.1" a
string which is the shared library major version?

(I am not 100% sure that there aren't ABI breaks in libgeos.3.9.0 to
libgeos-3.10.0, but as in theory nothing else loads that it doesn't matter.)

If this is the windows way to have the equivalent of libgeos_c.so.1,
then it seems like it is the right thing.  Someday, we might need to
have an ABI break in libgeos_c, even though it's been avoided so far,
and that would necessitate libgeos_c.so.2.

> $ ldd /projects/geos/rel-3.10.1w64gcc81/bin/libgeos_c-1.dll
>         ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff968c30000)
>         KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff967c10000)
>         KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll
> (0x7ff9663f0000)
>         msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff968a70000)
>         libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x61440000)
>         libgeos-3.10.1.dll =>
> /projects/geos/rel-3.10.1w64gcc81/bin/libgeos-3.10.1.dll (0x70200000)
>         libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x64940000)
>         libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x6fc40000)
>         USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ff967a60000)
>         win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ff966770000)
>         GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ff966dd0000)
>         gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ff966950000)
>         msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ff966350000)
>         ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ff966af0000)
>         IMM32.DLL => /c/WINDOWS/System32/IMM32.DLL (0x7ff967560000)
>
>  (symlinks don't work too well under windows so I'm doing a copy)
> cp libgeos_c-1.dll libgeos_c.dll

I'm having a Seventh Edition flashback :-) symlinks showed up in Eighth
Edition, and probably in 2.8BSD.  But if that's what you have to do,
seems like the thing to do.

>> > If it was to congeal the libtool / CMake worlds I guess I can learn to
>> > live with this ugliness.

I don't think it is about the libtool/cmake world, I think it is about
conforming to expectations for shared library major version naming on
Windows, to achieve some degree of soundness.

As I understand it, the only real change from libtool/cmake on POSIX was
to drop the libtool metadata files like libgeos.la.

>> Stepping way back and ignoring OS differences, we have two shared
>> libraries:
>> 
>>   libgeos_c which has a stable ABI and hence stable shlib version
>> 
>>   libgeos which has an unstable ABI, partially because C++ is so
>>   complicated that nobody can figgure out if there is an ABI change so
>>   C++ libraries tend to change their shlib major version every release.
>> 
> [Regina Obe] 
> When I built with libtool it did that.
> When I switched to CMAKE -- to my delight the C++ one never changed names
> Was just libgeos.dll

You are delighted but I am horrifed at the apparent lack of soundness.


> I know it probably sucks for most people, but for me it was great, cause it
> meant I don't have to deal with removing those
> Old 3.10.0, 3.9.0 etc when I build installers.

I would expect some packaging system that would remove them at
uninstall/replace time.

> Generally on windows people
> have a habit of installing multiple versions of 
> PostGIS in the same PostgreSQL instance, but they all have to share the same
> GEOS.  

I had not idea that could be done, and surely they must have
non-overlapping names?

> Those extra C++ were just a nuisance cause PostGIS uses the C-API and I'd
> have to remove them in uninstall or have them build up.

But with proper shlib versioning they just sit there.  It sounds like
you are doing things without a packaging system, that packaging systems
are intended to deal with.

> I would love to just statically link those two together and have just one
> library to contend with.

As soon as you do that it get really iffy about claiming new geos
versions do not have an ABI change.  Part of the point is that the C++
interface is not available to client programs.

And, that would seem to be a workaround for confusion within Windows
about shared library naming.


I wonder if someone can explain how windows dll versioning is supposed
to work?   I don't understand it (and I bet strk doesn't either).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 194 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/geos-devel/attachments/20211206/6aff6603/attachment.sig>


More information about the geos-devel mailing list