Patchwork [3/5] package.bbclass: add SHLIBSSEARCHDIRS to define where to search for shlib providers

login
register
mail settings
Submitter Martin Jansa
Date Jan. 18, 2014, 2:02 p.m.
Message ID <f689af01e81dd9a6387b8f424ddf55358f846024.1390052636.git.Martin.Jansa@gmail.com>
Download mbox | patch
Permalink /patch/65181/
State New
Headers show

Comments

Martin Jansa - Jan. 18, 2014, 2:02 p.m.
* when package contains some files matching "^.*\.so", but in directory
  not default linker search paths (e.g. /opt/package/bundled-lib/libfoo.so)
  don't register it as libfoo provider, because it's possible that there
  is different package providing libfoo.so in ${libdir} and that would
  be better shlib provider for other packages to depend on
* recipes providing libs intentionally in some other directory can
  define own SHLIBSSEARCHDIRS value

[YOCTO #4628]

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
---
 meta/classes/package.bbclass | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
Richard Purdie - Jan. 19, 2014, 5:13 p.m.
On Sat, 2014-01-18 at 15:02 +0100, Martin Jansa wrote:
> * when package contains some files matching "^.*\.so", but in directory
>   not default linker search paths (e.g. /opt/package/bundled-lib/libfoo.so)
>   don't register it as libfoo provider, because it's possible that there
>   is different package providing libfoo.so in ${libdir} and that would
>   be better shlib provider for other packages to depend on
> * recipes providing libs intentionally in some other directory can
>   define own SHLIBSSEARCHDIRS value
> 
> [YOCTO #4628]
> 
> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
> ---
>  meta/classes/package.bbclass | 26 +++++++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)

Doesn't this mean we lose automatic dependencies for libraries not in
the default system paths after this change?

We should really be respecting the libraries RPATH in this code and
searching the places it will look...

Cheers,

Richard
Martin Jansa - Jan. 19, 2014, 6:55 p.m.
On Sun, Jan 19, 2014 at 05:13:45PM +0000, Richard Purdie wrote:
> On Sat, 2014-01-18 at 15:02 +0100, Martin Jansa wrote:
> > * when package contains some files matching "^.*\.so", but in directory
> >   not default linker search paths (e.g. /opt/package/bundled-lib/libfoo.so)
> >   don't register it as libfoo provider, because it's possible that there
> >   is different package providing libfoo.so in ${libdir} and that would
> >   be better shlib provider for other packages to depend on
> > * recipes providing libs intentionally in some other directory can
> >   define own SHLIBSSEARCHDIRS value
> > 
> > [YOCTO #4628]
> > 
> > Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
> > ---
> >  meta/classes/package.bbclass | 26 +++++++++++++++++++++++---
> >  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> Doesn't this mean we lose automatic dependencies for libraries not in
> the default system paths after this change?

True, recipes with such libraries would need to append to
SHLIBSSEARCHDIRS

> We should really be respecting the libraries RPATH in this code and
> searching the places it will look...

I agree we should respect RPATH, but sometimes it is more complicated,
because your own binaries can have RPATH pointing to
/opt/package/bundled-lib/libfoo.so, but you don't want any other recipe
to find your libfoo.so, because there is preferred "system" /usr/lib/libfoo.so

So in ideal case we should respect combination of default search path,
ld.so.conf, RPATH and PRIVATE_LIBS :/.

I don't mind if you drop this one from patchset, it's the most controversial
one and can be work-arounded by carefully maintained PRIVATE_LIBS list.

Patch

diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass
index aa8156d..fe25a6b 100644
--- a/meta/classes/package.bbclass
+++ b/meta/classes/package.bbclass
@@ -1322,6 +1322,9 @@  python package_do_filedeps() {
 SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs"
 SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs"
 
+# default search path when searching for shlibs provided by package
+SHLIBSSEARCHDIRS ?= "${baselib} ${libdir}"
+
 python package_do_shlibs() {
     import re, pipes
 
@@ -1332,6 +1335,20 @@  python package_do_shlibs() {
 
     lib_re = re.compile("^.*\.so")
     libdir_re = re.compile(".*/%s$" % d.getVar('baselib', True))
+    
+    shlibs_search_dirs = d.getVar('SHLIBSSEARCHDIRS', True)
+    shlibs_search_dirs_re_txt = ""
+    for dir in shlibs_search_dirs.split(' '):
+        # strip leading and trailing slash, it's added in regexp
+        if dir.endswith("/"):
+            dir = dir[:-1]
+        if dir.startswith("/"):
+            dir = dir[1:]
+        if shlibs_search_dirs_re_txt:
+            shlibs_search_dirs_re_txt += "|"
+        shlibs_search_dirs_re_txt += "(^.*/%s/.*$)" % dir
+    shlibs_search_dirs_re = re.compile(shlibs_search_dirs_re_txt)
+    bb.debug(2, "will use following RE to search for provides sonames %s" % shlibs_search_dirs_re_txt)
 
     packages = d.getVar('PACKAGES', True)
     targetos = d.getVar('TARGET_OS', True)
@@ -1390,9 +1407,12 @@  python package_do_shlibs() {
             if m:
                 this_soname = m.group(1)
                 if not this_soname in sonames:
-                    # if library is private (only used by package) then do not build shlib for it
-                    if not private_libs or -1 == private_libs.find(this_soname):
-                        sonames.append(this_soname)
+                    if shlibs_search_dirs_re.match(file):
+                        # if library is private (only used by package) then do not build shlib for it
+                        if not private_libs or -1 == private_libs.find(this_soname):
+                            sonames.append(this_soname)
+                    else:
+                        bb.debug(2, "ignoring soname %s from %s, because path doesn't match %s" % (this_soname, file, shlibs_search_dirs_re_txt))
                 if libdir_re.match(os.path.dirname(file)):
                     needs_ldconfig = True
                 if snap_symlinks and (os.path.basename(file) != this_soname):