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>
diff --git a/Makefile b/Makefile index d325c1b..1f9edc7 100644 --- 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 @@ 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 @@ 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)
diff --git a/config.mk b/config.mk index 14aedd3..f8bd40f 100644 --- 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_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