cross-platform shlibs, sans libtool

From: Amitai Schleier <schmonz-lists-djb-skarnet_at_schmonz.com>
Date: 19 May 2025 20:18:25 -0400

For pkgsrc we'd like to be building, installing, and linking skaware
with/as shared libraries by default.

As a packager dealing with random build systems, the most expedient way
to get them to produce sufficiently portable shared libraries is usually
libtool. (macOS is a popular pkgsrc platform, and there are less popular
weird ones too.)

I libtoolized pkgsrc skalibs some years back, but it's been less than
expedient every time skalibs is updated, so I haven't wanted to
proliferate that approach to the rest of the stack. And also whereas
most of those other libtoolizations were drive-bys, skaware feels (as it
does to everyone here, I'm sure) worth more investment on my part.

So I've invested enough to post a new patch that:

- Produces pretty much unchanged results on NetBSD (and probably Linux)

- Produces shlibs on macOS (the latest Sequoia/aarch64 and also
Tiger/powerpc) that look to my eyes like what libtool would make

- Doesn't use libtool

- Trades away some GNU Make declarative expressiveness in exchange for
zeal, but maybe leaves enough hints to restore the expressiveness

On NetBSD I've verified that skalibs can be dynamically linked by
s6-dns. I ran out of steam getting s6-dns to build macOS dylibs, but I
bet it'd work if someone did (and am, of course, happy to test).

Hoping this is enough to go on, and all those README.macos can go away
soon :-)

- Amitai

From 4b6b867969dd44188b8de2e1461cead282256cbc Mon Sep 17 00:00:00 2001
From: Amitai Schleier <schmonz-web-git_at_schmonz.com>
Date: Fri, 16 May 2025 23:48:42 -0400
Subject: [PATCH] Install shlibs like libtool would, even on macOS.

NetBSD with libtool and with this change:

:; ls -l $(pkg_info -L skalibs | grep /lib/lib) work.*/.destdir/opt/pkg/lib/libskarnet.*
-rw-r--r-- 1 root wheel 1276180 May 13 07:03 /opt/pkg/lib/libskarnet.a
-rwxr-xr-x 1 root wheel 963 May 13 07:03 /opt/pkg/lib/libskarnet.la
lrwxr-xr-x 1 root wheel 20 May 13 07:03 /opt/pkg/lib/libskarnet.so -> libskarnet.so.2.14.4
lrwxr-xr-x 1 root wheel 20 May 13 07:03 /opt/pkg/lib/libskarnet.so.2 -> libskarnet.so.2.14.4
-rwxr-xr-x 1 root wheel 318624 May 13 07:03 /opt/pkg/lib/libskarnet.so.2.14.4
-rw-r--r-- 1 schmonz users 1277994 May 19 15:36 work.netbsd10-arm64/.destdir/opt/pkg/lib/libskarnet.a
lrwx------ 1 schmonz users 18 May 19 15:36 work.netbsd10-arm64/.destdir/opt/pkg/lib/libskarnet.so -> libskarnet.so.2.14
lrwx------ 1 schmonz users 18 May 19 15:36 work.netbsd10-arm64/.destdir/opt/pkg/lib/libskarnet.so.2 -> libskarnet.so.2.14
lrwx------ 1 schmonz users 22 May 19 15:36 work.netbsd10-arm64/.destdir/opt/pkg/lib/libskarnet.so.2.14 -> libskarnet.so.2.14.4.0
-rwxr-xr-x 1 schmonz users 318624 May 19 15:36 work.netbsd10-arm64/.destdir/opt/pkg/lib/libskarnet.so.2.14.4.0

macOS with libtool and with this change:

:; ls -l $(pkg_info -L skalibs | grep /lib/lib) work.*/.destdir/opt/pkg/lib/libskarnet.*
-rwxr-xr-x 1 root wheel 216544 May 16 13:11 /opt/pkg/lib/libskarnet.2.dylib
-rw-r--r-- 1 root wheel 632232 May 16 13:11 /opt/pkg/lib/libskarnet.a
lrwxr-xr-x 1 root wheel 18 May 16 13:11 /opt/pkg/lib/libskarnet.dylib -> libskarnet.2.dylib
-rwxr-xr-x 1 root wheel 966 May 16 13:11 /opt/pkg/lib/libskarnet.la
-rwxr-xr-x 1 schmonz staff 216096 May 19 16:43 work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.2.14.4.0.dylib
lrwx------ 1 schmonz staff 25 May 19 16:43 work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.2.14.dylib -> libskarnet.2.14.4.0.dylib
lrwx------ 1 schmonz staff 21 May 19 16:43 work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.2.dylib -> libskarnet.2.14.dylib
-rw-r--r-- 1 schmonz staff 633240 May 19 16:43 work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.a
lrwx------ 1 schmonz staff 21 May 19 16:43 work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.dylib -> libskarnet.2.14.dylib

:; otool -L /opt/pkg/lib/libskarnet.2.dylib work.*/.destdir/opt/pkg/lib/libskarnet.2.dylib
/opt/pkg/lib/libskarnet.2.dylib:
        /opt/pkg/lib/libskarnet.2.dylib (compatibility version 17.0.0, current version 17.4.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
work.magnetic-babysitter/.destdir/opt/pkg/lib/libskarnet.2.dylib:
        /opt/pkg/lib/libskarnet.2.dylib (compatibility version 2.0.0, current version 2.14.4)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)

(Ignore version inflation in the former. Merely a problem for me to deal
with in pkgsrc. Since this'll be your first time shipping macOS shlibs,
no version-sort-order concerns here.)
---
 Makefile     | 29 ++++++++++++++++++++++-------
 README.macos |  3 ---
 configure    |  9 ++++++---
 3 files changed, 28 insertions(+), 13 deletions(-)
 delete mode 100644 README.macos
diff --git a/Makefile b/Makefile
index eda3dda..bb0c5a5 100644
--- a/Makefile
+++ b/Makefile
_at__at_ -83,7 +83,22 _at__at_ endif
 install: install-sysconf install-sysdeps install-dynlib install-lib install-include install-pkgconfig
 install-sysconf: $(ALL_DATA:src/etc/%=$(DESTDIR)$(sysconfdir)/%)
 install-sysdeps: $(ALL_SYSDEPS:$(sysdeps)/%=$(DESTDIR)$(sysdepdir)/%)
-install-dynlib: $(SHARED_LIBS:lib%.so.xyzzy=$(DESTDIR)$(dynlibdir)/lib%.so)
+install-dynlib:
+ifeq ($(SHLIB_EXT),dylib)
+	$(INSTALL) -D -m 755 libskarnet.dylib.xyzzy $(DESTDIR)$(dynlibdir)/libskarnet.$(version).dylib
+	$(INSTALL) -l libskarnet.$(version).dylib $(DESTDIR)$(dynlibdir)/libskarnet.$(version_M).dylib
+	$(INSTALL) -l libskarnet.$(version_M).dylib $(DESTDIR)$(dynlibdir)/libskarnet.dylib
+
+	# Mach-O expects a filename containing a major version number
+	$(INSTALL) -l libskarnet.$(version_M).dylib $(DESTDIR)$(dynlibdir)/libskarnet.$(version_l).dylib
+else
+	$(INSTALL) -D -m 755 libskarnet.so.xyzzy $(DESTDIR)$(dynlibdir)/libskarnet.so.$(version)
+	$(INSTALL) -l libskarnet.so.$(version) $(DESTDIR)$(dynlibdir)/libskarnet.so.$(version_M)
+	$(INSTALL) -l libskarnet.so.$(version_M) $(DESTDIR)$(dynlibdir)/libskarnet.so
+
+	# ELF probably wants *not* to have this link, but for now let's be kinda like Mach-O
+	$(INSTALL) -l libskarnet.so.$(version_M) $(DESTDIR)$(dynlibdir)/libskarnet.so.$(version_l)
+endif
 install-lib: $(STATIC_LIBS:lib%.a.xyzzy=$(DESTDIR)$(libdir)/lib%.a)
 install-include: $(ALL_INCLUDES:src/include/$(package)/%.h=$(DESTDIR)$(includedir)/$(package)/%.h)
 install-pkgconfig: $(PC_TARGETS:%=$(DESTDIR)$(pkgconfdir)/%)
_at__at_ -110,11 +125,6 _at__at_ $(DESTDIR)$(sysconfdir)/%: src/etc/%
 $(DESTDIR)$(sysdepdir)/%: $(sysdeps)/%
 	exec $(INSTALL) -D -m 644 $< $_at_
 
-$(DESTDIR)$(dynlibdir)/lib%.so $(DESTDIR)$(dynlibdir)/lib%.so.$(version_M): lib%.so.xyzzy
-	$(INSTALL) -D -m 755 $< $_at_.$(version) && \
-	$(INSTALL) -l $(_at_F).$(version) $_at_.$(version_M) && \
-	exec $(INSTALL) -l $(_at_F).$(version_M) $_at_
-
 $(DESTDIR)$(libdir)/lib%.a: lib%.a.xyzzy
 	exec $(INSTALL) -D -m 644 $< $_at_
 
_at__at_ -134,8 +144,13 _at__at_ libskarnet.a.xyzzy: $(ALL_SOBJS)
 	exec $(AR) rc $_at_ $^
 	exec $(RANLIB) $_at_
 
+LDFLAGS_SHARED_SO=-Wl,-soname,libskarnet.so.$(version_M) -Wl,-rpath=$(dynlibdir)
 libskarnet.so.xyzzy: $(ALL_DOBJS)
-	exec $(CC) -o $_at_ $(CFLAGS_ALL) $(CFLAGS_SHARED) $(LDFLAGS_ALL) $(LDFLAGS_SHARED) -Wl,-soname,libskarnet.so.$(version_M) -Wl,-rpath=$(dynlibdir) $^ $(SOCKET_LIB) $(SPAWN_LIB) $(SYSCLOCK_LIB) $(TAINNOW_LIB) $(TIMER_LIB) $(UTIL_LIB)
+	exec $(CC) -o $_at_ $(CFLAGS_ALL) $(CFLAGS_SHARED) $(LDFLAGS_ALL) $(LDFLAGS_SHARED) $(LDFLAGS_SHARED_SO) $^ $(SOCKET_LIB) $(SPAWN_LIB) $(SYSCLOCK_LIB) $(TAINNOW_LIB) $(TIMER_LIB) $(UTIL_LIB)
+
+LDFLAGS_SHARED_DYLIB=-Wl,-dylib_install_name,$(DESTDIR)$(dynlibdir)/libskarnet.$(version_l).dylib -Wl,-dylib_compatibility_version,$(version_l) -Wl,-dylib_current_version,$(version)
+libskarnet.dylib.xyzzy: $(ALL_DOBJS)
+	exec $(CC) -o $_at_ $(CFLAGS_ALL) $(CFLAGS_SHARED) $(LDFLAGS_ALL) $(LDFLAGS_SHARED) $(LDFLAGS_SHARED_DYLIB) $^ $(SOCKET_LIB) $(SPAWN_LIB) $(SYSCLOCK_LIB) $(TAINNOW_LIB) $(TIMER_LIB) $(UTIL_LIB)
 
 libskarnet.pc:
 	exec env \
diff --git a/README.macos b/README.macos
deleted file mode 100644
index 8b01f7a..0000000
--- a/README.macos
+++ /dev/null
_at__at_ -1,3 +0,0 _at__at_
- This package will compile on Darwin (MacOS), but the building of
-shared libraries is not supported.
- Make sure you use the --disable-shared option to configure.
diff --git a/configure b/configure
index 5bc0b41..8a8b8a7 100755
--- a/configure
+++ b/configure
_at__at_ -400,6 +400,7 _at__at_ pkgconfdir='$prefix/lib/pkgconfig'
 sysdepdir='$prefix/lib/$package/sysdeps'
 sysdeplist=
 shared=true
+shlibext=so; if [ "$(uname -s)" = Darwin ]; then shlibext=dylib; fi
 static=true
 allpic=true
 slashpackage=false
_at__at_ -499,7 +500,7 _at__at_ if $slashpackage ; then
   sysdepdir=${home}/sysdeps
   binprefix=${home}/command
   extbinprefix=${exthome}/command
-  dynlibdir=${home}/library.so
+  dynlibdir=${home}/library.${shlibext}
   libdir=${home}/library
   includedir=${home}/include
   pkgconfdir=${home}/pkgconfig
_at__at_ -763,7 +764,7 _at__at_ if test -n "$vpaths" ; then
   echo "vpath lib%a$vpaths"
 fi
 if test -n "$vpathd" ; then
-  echo "vpath lib%.so$vpathd"
+  echo "vpath lib%.${shlibext}$vpathd"
 fi
 
 if $static ; then
_at__at_ -772,9 +773,11 _at__at_ else
   echo "STATIC_LIBS :="
 fi
 if $shared ; then
-  echo "SHARED_LIBS := libskarnet.so.xyzzy"
+  echo "SHARED_LIBS := libskarnet.${shlibext}.xyzzy"
+  echo "SHLIB_EXT := ${shlibext}"
 else
   echo "SHARED_LIBS :="
+  echo "SHLIB_EXT :="
 fi
 if $pcw ; then
   echo "DO_PKGCONFIG := 1"
-- 
2.49.0
Received on Tue May 20 2025 - 02:18:25 CEST

This archive was generated by hypermail 2.4.0 : Tue May 20 2025 - 02:18:59 CEST