Bug 7136

Summary: Packaging non-versioned libraries is non-trivial
Product: [Documentation] Development Manual Reporter: Henry Bruce <henry.bruce>
Component: developmentAssignee: Michael Opdenacker <michael.opdenacker>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: Medium CC: henry.bruce, meta.mr.watcher, meta.watcher, michael.opdenacker, poky.bs.watcher, poky.watcher, randy.macleod, ross.burton
Version: 2.0   
Target Milestone: 4.0 M4   
Hardware: x86   
OS: Multiple   
Whiteboard:
OS type for building Yocto: --- Type of Regression: ---
Verified: Documentation change: Don't know

Description Henry Bruce 2015-01-13 18:58:29 UTC
When creating a recipe to package a pre-built closed source shared library the default package was not created.

Basis of libfoo_0.1.bb looked like this.

SRC_URI = "file://libfoo.so"
FILES_${PN} = "${libdir}/libfoo.so"
do_install () {
   install -m 0755 -d ${D}${libdir}
   install -m 0644 ${WORKDIR}/libfoo.so ${D}${libdir}
}

"bitbake libfoo" ran just fine but libfoo_0.1_arch.ipk was not created. 
libfoo.so was in images, package and sysroot-destdir folders 
but was not in packages-split/libfoo and had not been selected for packaging. 
No errors or warning could be found in any logs.

I worked around the issue by adding the following line
PACKAGES = "${PN} ${PN}-dbg ${PN}-dev"
Comment 1 Richard Purdie 2015-01-15 15:10:07 UTC
This is due to the fact that these prebuilt libraries you have don't follow the standard naming practices for Linux shared libraries. For example on my Ubuntu system:

lrwxrwxrwx 1 root root     35 May 13  2013 /usr/lib/x86_64-linux-gnu/libz.so -> /lib/x86_64-linux-gnu/libz.so.1.2.8
lrwxrwxrwx 1 root root     13 May 13  2013 /lib/x86_64-linux-gnu/libz.so.1 -> libz.so.1.2.8
-rw-r--r-- 1 root root 100728 May 13  2013 /lib/x86_64-linux-gnu/libz.so.1.2.8

So there is a .so file symlinked to a .so.<majorversion> which in turn links to a .so.<minorversion>.<pointversion>

Our default patterns for library packaging match this format, not the one your closed source shared libs are using. This isn't really something we'd want to change the defaults for.

Note that your lib would have been packaged, its just the .so file would have been placed into libfoo-dev_0.1_arch.ipk since the system would (incorrectly) think it was a development file.
Comment 2 Henry Bruce 2015-01-15 19:23:43 UTC
Richard - thanks for taking the time to look a this.

I tried installing as per standard shared library naming practices, but .so file is still omitted from ipk. Snippet from intuvision_6.3.1.bb below installs libintuVision.so.6.3.1 and libintuVision.so.6 but not libintuVision.so

libiv = "libintuVision.so"
do_install () {
   PV_MAJOR=`echo ${PV} | cut -d '.' -f 1`
   install -m 0755 -d ${D}${libdir}
   install -m 0644 ${WORKDIR}/${MACHINE_ARCH}/${libiv}.${PV} ${D}${libdir}
   ln -sf ${D}${libdir}/${libiv}.${PV} ${D}${libdir}/${libiv}.${PV_MAJOR}
   ln -sf ${D}${libdir}/${libiv}.${PV} ${D}${libdir}/${libiv}  
}

Feedback on do_install is welcome!
Comment 3 Richard Purdie 2015-01-15 21:06:25 UTC
(In reply to comment #2)
> Richard - thanks for taking the time to look a this.
> 
> I tried installing as per standard shared library naming practices, but .so
> file is still omitted from ipk. Snippet from intuvision_6.3.1.bb below
> installs libintuVision.so.6.3.1 and libintuVision.so.6 but not
> libintuVision.so
> 
> libiv = "libintuVision.so"
> do_install () {
>    PV_MAJOR=`echo ${PV} | cut -d '.' -f 1`
>    install -m 0755 -d ${D}${libdir}
>    install -m 0644 ${WORKDIR}/${MACHINE_ARCH}/${libiv}.${PV} ${D}${libdir}
>    ln -sf ${D}${libdir}/${libiv}.${PV} ${D}${libdir}/${libiv}.${PV_MAJOR}
>    ln -sf ${D}${libdir}/${libiv}.${PV} ${D}${libdir}/${libiv}  
> }
> 
> Feedback on do_install is welcome!

When you did this, did you remember to remove the FILES and PACKAGES changes you'd made? This should work...
Comment 4 Richard Purdie 2015-01-15 21:08:50 UTC
I'd also add that there are the oe_soinstall and oe_libinstall functions (see meta/classes/utils.bbclass) which can handle some of this for you.
Comment 5 Ross Burton 2015-01-16 16:41:13 UTC
If the binary comes as a .so I wouldn't bother making symlinks as they'll never be used.  The solution here is to just set FILES_${PN} = "${libdir]/*.so"

Some form of additional sanity test to identify this happening would be useful as many people don't know how library versioning is meant to work - I find myself answering this for someone in bugzilla/irc/mailing list once every few weeks.  Something along the lines of "if PN is empty and PN-dev contains a .so that isn't a symlink, warn".
Comment 6 Henry Bruce 2015-01-19 23:28:36 UTC
Ross: I agree with your comments. They would certainly improve ease of use with pre-built binaries. I set FILES_${PN} = "${libdir}/*.so" , but no change in behavior. .so is still not packaged.

Richard: My 'intuvision' example used default FILES and PACKAGES values but .so is still not packaged. Thanks for heads up on oe_soinstall. This caused a 'too much recursion' python exception at split_and_strip_files line 222. Further investigation showed that vendor's so did not have an ELF 'soname' tag and oe_soinstall does not test for its absence. Maybe this is the root cause. I'll get vendor to add the tag and report back.
Comment 7 Ross Burton 2015-01-19 23:34:24 UTC
Sorry, you'll need to unset FILES_${PN}-dev, which will be taking the files before ${PN} can.
Comment 8 Henry Bruce 2015-01-20 00:06:09 UTC
Ross: I also need to package include files so my app can use this library. Unsetting FILES_${PN}-dev causes an "installed but not shipped" error.
Comment 9 Ross Burton 2015-01-20 11:25:05 UTC
So you'll need something like this:

FILES_${PN} = "${libdir}/*.so"
FILES_${PN}-dev = "${includedir}/*.h"

Fix the paths as appropriate.
Comment 10 Henry Bruce 2015-02-18 18:01:14 UTC
I received .so from vendor with SONAME tag and oe_soinstall now works as expected, creating valid package.

do_install () {
   install -m 0755 -d ${D}${libdir}
   oe_soinstall ${WORKDIR}/${MACHINE_ARCH}/libintuVision.so.${PV} ${D}${libdir}
   oe_soinstall ${WORKDIR}/${MACHINE_ARCH}/libDigitalVideo.so.${PV} ${D}${libdir}
   install -m 0755 -d ${D}${includedir}
   install -m 0755 ${WORKDIR}/include/* ${D}${includedir}
}

Ross: If I had time to fiddle about with recipe I may have been able to generate a package with .so that didn't have SONAME tag, but I didn't think it was worth the effort.

Going forward I recommend three steps
1. Document process of adding prebuilt libraries. Is there a place I can do this so that Scott can edit content and transfer to public docs?
2. Open a new issue for oe_soinstall throwing an exception if .so doesn't have SONAME tag
3. Don't silently fail to package a library if that is obviously the intent of the recipe. Not so sure how to fix this.

I'll do (1) and (2). Maybe this bug stays open to flag (3). I'll attempt to fix (2) and send a patch to mailing list.
Comment 11 Ross Burton 2015-03-21 21:15:14 UTC
Henry, did filing new bugs for (1) and (2) happen?

I'm not sure what could be done about (3), maybe sanity-checking that libfoo.so in the -dev package is a symlink?  I wonder if that would have too many false-positives.
Comment 12 Ross Burton 2016-07-26 16:43:25 UTC
For future reference I think the neatest way to package a non-versioned library would be to:

# This says that the real library is .so
SOLIBS=".so"
# This clears the dev library names so they don't get packaged into PN-dev
FILES_SOLIBSDEV=""
Comment 13 Henry Bruce 2016-08-15 21:57:57 UTC
Sorry, I dropped the ball on this.

(1). Thanks to Ross for addressing this in https://wiki.yoctoproject.org/wiki/TipsAndTricks/PackagingNonversionedLibrary
(2) I created bug 10146.
(3) I'll go with Ross's recommendation and drop the request as this doesn't seem to be an issue for anyone else.
Comment 14 Ross Burton 2016-09-14 15:58:17 UTC
(2) is now integrated so this bug is now about getting (1) into the actual documentation.
Comment 15 Ross Burton 2016-09-20 15:20:04 UTC
Scott, can you massage the documentation I wrote at https://wiki.yoctoproject.org/wiki/TipsAndTricks/PackagingNonversionedLibrary into the manual?  Under the development manual seems sensible, maybe a subsection under Writing A New Recipe?
Comment 16 Ross Burton 2020-01-29 16:49:11 UTC
Assigning to Mark.

Mark, see comment #15.  I wrote a wiki page with an overview for packaging non-versioned libraries which needs to be integrated somewhere into the proper documentation.
Comment 17 Michael Opdenacker 2022-02-03 16:15:44 UTC
Now closed in "master"
https://git.yoctoproject.org/yocto-docs/commit/?id=5e46cad9e4b4ab03e33f4d5aea34e56f6b15fe27