Subject: pkg/5485: Annoying hacks to dynamically create PLISTs for shared libs
To: None <gnats-bugs@gnats.netbsd.org>
From: Johnny C. Lam <lamj@stat.cmu.edu>
List: netbsd-bugs
Date: 05/22/1998 20:25:46
>Number:         5485
>Category:       pkg
>Synopsis:       Annoying hacks to dynamically create PLISTs for shared libs
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri May 22 17:35:00 1998
>Last-Modified:
>Originator:     Johnny C. Lam
>Organization:
>Release:        1.3E
>Environment:
System: NetBSD kasparov 1.3E NetBSD 1.3E (KASPAROV) #0: Tue May 12 15:39:07 EDT 1998 toor@kasparov:/usr/src/sys/arch/alpha/compile/KASPAROV alpha

>Description:
	For a.out platforms, all that needs to be installed for shared
libs is:

	libshared.so.N.M

but for ELF platforms, you must install:

	libshared.so.N.M
	libshared.so.N	--> libshared.so.N.M
	libshared.so    --> libshared.so.N.M

There are currently kludges to dynamically create a correct PLIST at
install time, but they must be repeated for each library package you
wish to make.

This gets annoying after a while.

>How-To-Repeat:
	Build libg++ or rsaref.

>Fix:
	For the pkg PLISTs, we should either include the extra
symbolic links for all platforms, or provide a way to add ELF-specific
lines to the PLIST and have them removed on non-ELF platforms.

	I've implemented a solution for the latter.  PLISTs can now
look like:

	include/foo.h
	lib/libfoo.a
	lib/libfoo.so.1.0
	@so-elf @exec	ln -sf libfoo.so.1.0 %D/lib/libfoo.so.1
	@so-elf @exec	ln -sf libfoo.so.1.0 %D/lib/libfoo.so
	@so-elf @unexec	rm -f %D/lib/libfoo.so.1
	@so-elf @unexec	rm -f %D/lib/libfoo.so
	man/man3/foo.3

For ELF platforms, "@so-elf" gets stripped from the lines.
For non-ELF platforms, the "@so-elf" lines are removed.

For completeness, there is also a @so-aout directive to do the same
thing for a.out-specific lines.

Now it's easy to write a single PLIST file for all platforms without
having to add hacks to every packages' Makefile.

As an afterthought, and also because it was really easy to do in the
new framework, I added an architecture-dependent directive
"@md-${MACHINE_ARCH}" to be used in the same way, so alpha-specific
lines start with "@md-alpha".  I don't see an immediate use for this
feature yet, but it could be used to do platform-specific tweaking of
the package installation.

The patch follows:

--- /usr/pkgsrc/mk/bsd.pkg.mk	Fri May 15 07:30:34 1998
+++ bsd.pkg.mk	Fri May 22 20:20:56 1998
@@ -2001,12 +2001,7 @@
 tags:
 .endif
 
-
-# generate ${PLIST} from ${PLIST_SRC} by:
-#  - fixing list of man-pages according to MANCOMPRESSED/MANZ
-#    (we don't regard MANCOMPRESSED as many ports seem to have .gz pages in
-#     PLIST even when they install manpages without compressing them)
-#  - substituting machine architecture (uname -m) for <$ARCH>
+# Generate ${PLIST} from ${PLIST_SRC} by filtering through ${GEN_PLIST}.
 .if !defined(PLIST_SRC)
 .if exists(${PKGDIR}/PLIST)
 PLIST_SRC=	${PKGDIR}/PLIST
@@ -2026,31 +2021,59 @@
 .endif  # ${PKGDIR}/PLIST
 .endif  # !PLIST_SRC
 
+GEN_PLIST?= ${CAT}
+
+# Machine-dependent lines have the header "@md-${MACHINE_ARCH}".
+# Remove the header if this is the right machine architecture, otherwise,
+# filter out those lines for other architectures.
+#
+# The shared object format header is ${OBJECT_FMT} lowercased, stripped
+# of spaces and dots, and prepended with @so-
+#    e.g.  ELF --> @so-elf, a.out --> @so-aout
+# Remove the header if this is the platform's shared object format,
+# otherwise, filter out those lines for other shared object formats.
+PLIST_SO_FMT!=	echo ${OBJECT_FMT} | ${TR} [A-Z] [a-z] | ${SED} 's/[ .]*//g'
+GEN_PLIST+=	| ${AWK} '{ \
+				if ( $$1 ~ "@md-" ) { \
+					if ( $$1 == sprintf("@md-%s",arch) ) print; \
+				} \
+				else if ( $$1 ~ "@so-" ) { \
+					if ( $$1 == sprintf("@so-%s",obj_fmt) ) print; \
+				} \
+				else print; \
+			}' \
+			arch=${MACHINE_ARCH} \
+			obj_fmt=${PLIST_SO_FMT}
+GEN_PLIST+=	| ${SED} \
+				-e 's/^@md-'${MACHINE_ARCH}'[^[:graph:]]*//' \
+				-e 's/^@so-'${PLIST_SO_FMT}'[^[:graph:]]*//'
+
+# Substitute machine model (uname -m) for <$ARCH>.
+# Substitute for ${MACHINE_ARCH}.
+GEN_PLIST+=	| ${SED} \
+				-e 's/<\$$ARCH>/'${ARCH}'/g' \
+				-e 's/\$${MACHINE_ARCH}/'${MACHINE_ARCH}'/g'
+
+# Fix list of man-pages according to MANCOMPRESSED/MANZ
+# (we don't regard MANCOMPRESSED as many ports seem to have .gz pages in
+# PLIST even when they install manpages without compressing them)
+.if defined(MANZ)
+GEN_PLIST+=	-e '/man\/man.*[^g][^z]$$/s/$$/.gz/' \
+			-e '/man\/cat.*[^g][^z]$$/s/$$/.gz/' \
+			-e '/man\/${MANLANG}\/man.*[^g][^z]$$/s/$$/.gz/' \
+			-e '/man\/${MANLANG}\/cat.*[^g][^z]$$/s/$$/.gz/'
+.else	# !MANZ
+GEN_PLIST+=	-e '/man\/man/s/\.gz$$//' \
+			-e '/man\/cat/s/\.gz$$//' \
+			-e '/man\/${MANLANG}\/man/s/\.gz$$//' \
+			-e '/man\/${MANLANG}\/cat/s/\.gz$$//'
+.endif
+
 ${PLIST}: ${PLIST_SRC}
 	@if [ -z "${PLIST_SRC}" ] ; then \
 		${ECHO} "No ${PKGDIR}/PLIST, and no ${PKGDIR}/PLIST-{mi,md.shared,md.static}" ; \
 		${ECHO} "Package must care for making ${PLIST} by setting PLIST_SRC!" ; \
 	fi
-.if defined(MANZ)
-	@if [ ! -z "${PLIST_SRC}" ] ; then \
-		${CAT} ${PLIST_SRC} | ${SED} \
-			-e '/man\/man.*[^g][^z]$$/s/$$/.gz/' \
-			-e '/man\/cat.*[^g][^z]$$/s/$$/.gz/' \
-			-e '/man\/${MANLANG}\/man.*[^g][^z]$$/s/$$/.gz/' \
-			-e '/man\/${MANLANG}\/cat.*[^g][^z]$$/s/$$/.gz/' \
-			-e 's/<\$$ARCH>/'${ARCH}'/g' \
-			-e 's/\$${MACHINE_ARCH}/'${MACHINE_ARCH}'/g' \
-			>${PLIST} ; \
-	fi
-.else   # !MANZ
 	@if [ ! -z "${PLIST_SRC}" ] ; then \
-		${CAT} ${PLIST_SRC} | ${SED} \
-			-e '/man\/man/s/\.gz$$//' \
-			-e '/man\/cat/s/\.gz$$//' \
-			-e '/man\/${MANLANG}\/man/s/\.gz$$//' \
-			-e '/man\/${MANLANG}\/cat/s/\.gz$$//' \
-			-e 's/<\$$ARCH>/'${ARCH}'/g' \
-			-e 's/\$${MACHINE_ARCH}/'${MACHINE_ARCH}'/g' \
-			>${PLIST} ; \
+		${CAT} ${PLIST_SRC} | ${GEN_PLIST} > ${PLIST}; \
 	fi
-.endif  # MANZ
>Audit-Trail:
>Unformatted: