and self-referencing symlinks
To: None <tech-toolchain@netbsd.org>
From: Oliver Gould <ogould@olix0r.net>
List: tech-toolchain
Date: 08/16/2007 17:42:38
On 2007-08-16 18:36 +0200, Quentin Garnier wrote:
> On Thu, Aug 16, 2007 at 12:16:46PM -0400, Oliver Gould wrote:
> > ...
> > libnvpair.so.1 -> libnvpair.so.1
> > libnvpair.so -> libnvpair.so.1
> > ...
> >
> > Clearly the shared lib files are useless. I didn't notice any obvious
> > difference with other lib Makefiles.
I noticed I was missing an include to <bsd.own.mk>. This doesn't change
anything, though.
> What am I missing?
>
> A shlib_version file?
That is apparently it; but only after a lot more digging...
This is what was happening:
# build libnvpair/libnvpair.so.1
rm -f libnvpair.so.1
cc -Wl,-x -shared -Wl,-soname,libnvpair.so.1 -o libnvpair.so.1
-Wl,-rpath-link,/lib:/usr/lib -R/lib -L/lib -Wl,--whole-archive
libnvpair_pic.a -Wl,--no-whole-archive
* ln -sf libnvpair.so.1 libnvpair.so.1.tmp
* mv -f libnvpair.so.1.tmp libnvpair.so.1
ln -sf libnvpair.so.1 libnvpair.so.tmp
mv -f libnvpair.so.tmp libnvpair.so
This occurs in <bsd.lib.mk>:
.if ${OBJECT_FMT} == "ELF"
# We don't use INSTALL_SYMLINK here because this is just
# happening inside the build directory/objdir. XXX Why does
# this spend so much effort on libraries that aren't live??? XXX
* ${HOST_LN} -sf lib${LIB}.so.${SHLIB_FULLVERSION} \
lib${LIB}.so.${SHLIB_MAJOR}.tmp
* mv -f lib${LIB}.so.${SHLIB_MAJOR}.tmp lib${LIB}.so.${SHLIB_MAJOR}
${HOST_LN} -sf lib${LIB}.so.${SHLIB_FULLVERSION} lib${LIB}.so.tmp
mv -f lib${LIB}.so.tmp lib${LIB}.so
.endif
Which is broken when SHLIB_FULLVERSION == SHLIB_MAJOR. Yet, earlier in
this file, SHLIB_FULLVERSION can be set to SHLIB_MAJOR:
.if defined(SHLIB_MAJOR) && !empty(SHLIB_MAJOR) # {
.if defined(SHLIB_MINOR) && !empty(SHLIB_MINOR)
.if defined(SHLIB_TEENY) && !empty(SHLIB_TEENY)
SHLIB_FULLVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR}.${SHLIB_TEENY}
.else
SHLIB_FULLVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR}
.endif
.else
* SHLIB_FULLVERSION=${SHLIB_MAJOR}
.endif
.endif # }
When I set SHLIB_MINOR=0 manually in the Makefile, though, everything
operates as expected:
libnvpair.so -> libnvpair.so.1.0
libnvpair.so.1 -> libnvpair.so.1.0
libnvpair.so.1.0
So, apparently, shlib_version is not read:
(isla)$ cat shlib_version
# $NetBSD: shlib_version,v 1.3 2005/04/17 07:20:00 provos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=2
minor=0
(isla)$ make print-shlib-major
1
(isla)$ make print-shlib-minor
*** Error code 1
Stop.
make: stopped in /mnt/src/zfs/src/cddl/lib/libnvpair
This is because cddl/lib/Makefile.inc (included from bsd.own.mk, I
believe) defines SHLIB_MAJOR=1, and therefore SHLIB_{MINOR,TEENY} are
not read in from shlib_version:
.if !defined(SHLIB_MAJOR) && exists(${SHLIB_VERSION_FILE}) # {
SHLIB_MAJOR != . ${SHLIB_VERSION_FILE} ; echo $$major
SHLIB_MINOR != . ${SHLIB_VERSION_FILE} ; echo $$minor
SHLIB_TEENY != . ${SHLIB_VERSION_FILE} ; echo $$teeny
...
.endif # }
I am not authoritative, but I believe that at least one of the following
fixes should be made:
o Do not set SHLIB_FULLVERSION to SHLIB_MAJOR. If no SHLIB_MINOR is
set, append ".0" to SHLIB_MAJOR.
o Read SHLIB_{MINOR,TEENY} from SHLIB_VERSION_FILE if they are
undefined, regardless of whether SHLIB_MAJOR is defiend.
o Change the symlink directives so that libs can be created in the
case that SHLIB_FULLVERSION == SHLIB_MAJOR.
I have not made patches to do any of these, as my make-foo is weak (and
I have some more time sensitive work to do now that I have found a
workaround ;)
Thanks for the pointer, Quentin!
- Oliver