Switch to semantic versioning and improve dynamic library handling - libgrapheme - unicode string library
 (HTM) git clone git://git.suckless.org/libgrapheme
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit ed7ebdc7f7fa748f89372e034d6d983835db5d42
 (DIR) parent b583c3ab6855d491154f7be6d3bdb5c44380290c
 (HTM) Author: Laslo Hunhold <dev@frign.de>
       Date:   Wed,  5 Oct 2022 22:14:17 +0200
       
       Switch to semantic versioning and improve dynamic library handling
       
       After long consideration, I've made the decision to switch this project
       over to semantic versioning[0]. While it made sense for farbfeld in
       some way to use incremental versioning, for libraries it is almost
       canonical to make use of semantic versioning instead.
       
       Given there have been breaking API-changes since version 1 (which now
       corresponds to 1.0.0), the major version will naturally be bumped.
       Afterwards though, additions to the API will only trigger a minor bump,
       as is convention, while also making it possible to release
       patch-releases when there have been errors. Because, to be frank, if you
       only have full integers, you kind of get anxiety that a release is in
       fact correct, given you don't want to waste another whole integer-step
       on a simple bugfix.
       
       For farbfeld, which is very small and self-contained, it was okay, but
       libgrapheme has become complex enough to warrant this.
       
       Regarding dynamic library handling: I really read a lot about it and
       referred to some interesting articles like [1] to figure out what the
       best approach is to reflect versioning in the dynamic library.
       
       Doing this portably is quite difficult and the common approach to
       simply use the major version has some serious drawbacks, given a
       binary linked against the version 2.4 can falsely be linked against
       versions 2.3.x, 2.2.x, 2.1.x or 2.0.x at runtime, even though they
       lack functions added in 2.4 that might be used in the binary, something
       explicitly allowed in semantic versioning.
       
       A portable trick described in [1] is to set SONAME to contain
       MAJOR.MINOR and explicitly create symlinks from all "lower" MAJOR-MINOR-
       combinations with the same MAJOR-version to ensure forward-compatibility
       for all binaries linked against a certain MAJOR.MINOR-combination.
       
       This way, a library linked against libgrapheme-2.4 is properly linkable
       against libgrapheme-2.5 at runtime (given semantic versioning ensures
       forward compatibility), but at the same time, it will not allow linking
       against libgrapheme-2.2 (if that is installed), given it has no
       explicit symlink set from libgrapheme-2.2 at libgrapheme.2.5.
       
       [0]:https://semver.org/
       [1]:https://begriffs.com/posts/2021-07-04-shared-libraries.html
       
       Signed-off-by: Laslo Hunhold <dev@frign.de>
       
       Diffstat:
         M Makefile                            |      14 +++++++++-----
         M config.mk                           |       9 ++++++++-
       
       2 files changed, 17 insertions(+), 6 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       @@ -2,12 +2,10 @@
        # libgrapheme - unicode string library
        .POSIX:
        
       -VERSION = 1
       -MAN_DATE = 2022-09-07
       -UNICODE_VERSION = 15.0.0
       -
        include config.mk
        
       +VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
       +
        BENCHMARK =\
                benchmark/case\
                benchmark/character\
       @@ -277,7 +275,10 @@ install: all
                cp -f $(MAN3:=.3) "$(DESTDIR)$(MANPREFIX)/man3"
                cp -f $(MAN7:=.7) "$(DESTDIR)$(MANPREFIX)/man7"
                cp -f libgrapheme.a "$(DESTDIR)$(LIBPREFIX)"
       -        cp -f libgrapheme.so "$(DESTDIR)$(LIBPREFIX)"
       +        cp -f libgrapheme.so "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION)"
       +        i=0; while [ "$$i" -le $(VERSION_MINOR) ]; do ln -sf "libgrapheme.so.$(VERSION)" "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION_MAJOR).$$i"; i=$$((i+1)); done
       +        ln -sf "libgrapheme.so.$(VERSION)" "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION_MAJOR)"
       +        ln -sf "libgrapheme.so.$(VERSION)" "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so"
                cp -f grapheme.h "$(DESTDIR)$(INCPREFIX)"
                $(LDCONFIG)
        
       @@ -285,6 +286,9 @@ uninstall:
                for m in $(MAN3:=.3); do rm -f "$(DESTDIR)$(MANPREFIX)/man3/`basename $$m`"; done
                for m in $(MAN7:=.7); do rm -f "$(DESTDIR)$(MANPREFIX)/man7/`basename $$m`"; done
                rm -f "$(DESTDIR)$(LIBPREFIX)/libgrapheme.a"
       +        rm -f "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION)"
       +        i=0; while [ "$$i" -le $(VERSION_MINOR) ]; do rm -f "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION_MAJOR).$$i"; i=$$((i+1)); done
       +        rm -f "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so.$(VERSION_MAJOR)"
                rm -f "$(DESTDIR)$(LIBPREFIX)/libgrapheme.so"
                rm -f "$(DESTDIR)$(INCPREFIX)/grapheme.h"
                $(LDCONFIG)
 (DIR) diff --git a/config.mk b/config.mk
       @@ -1,3 +1,10 @@
       +# libgrapheme version
       +VERSION_MAJOR = 1
       +VERSION_MINOR = 0
       +VERSION_PATCH = 0
       +UNICODE_VERSION = 15.0.0
       +MAN_DATE = 2022-09-07
       +
        # Customize below to fit your system
        
        # paths
       @@ -16,7 +23,7 @@ BUILD_CFLAGS   = $(CFLAGS)
        BUILD_LDFLAGS  = $(LDFLAGS)
        
        SHFLAGS  = -fPIC -ffreestanding
       -SOFLAGS  = -shared -nostdlib -Wl,--soname=libgrapheme.so
       +SOFLAGS  = -shared -nostdlib -Wl,--soname=libgrapheme.so.$(VERSION_MAJOR).$(VERSION_MINOR)
        
        # tools
        CC       = cc