shlibs providers improvements
v3 cover shlibs providers improvements
v2->v3
changed the order of commits so that controversial SHLIBSSEARCHDIRS is last fixed typo prividers -> providrs
The following changes since commit 091d395e43836575587112ee1696a18c401505bb:
lib/oeqa: sshcontrol: Allow alternate port for SSHControl (2014-01-28 00:48:29 +0000)
are available in the git repository at:
git://git.openembedded.org/openembedded-core-contrib jansa/shlib-providers
http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=jansa/shlib-providers
Martin Jansa (3):
package.bbclass: Don't search for providers of PRIVATE_LIBS package.bbclass: Show which files require given dependency in debug
output
package.bbclass: add SHLIBSSEARCHDIRS to define where to search for
shlib providers
meta/classes/package.bbclass | 49 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-)
Signature · 1 line
1.8.5.3
PATCH v3 1/3 package.bbclass: Don't search for providers of PRIVATE_LIBS
* split PRIVATE_LIBS and don't use find(), so that libfoo cannot be found in PRIVATE_LIBS = "libfoobar"
--- meta/classes/package.bbclass | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
meta/classes/package.bbclass +11 -2
@@ -1402,7 +1402,7 @@ python package_do_shlibs() { 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): + if not private_libs or this_soname not in private_libs: sonames.append(this_soname) if libdir_re.match(os.path.dirname(file)): needs_ldconfig = True
@@ -1486,7 +1486,8 @@ python package_do_shlibs() { read_shlib_providers() for pkg in packages.split(): - private_libs = d.getVar('PRIVATE_LIBS_' + pkg, True) or d.getVar('PRIVATE_LIBS', True) + private_libs = d.getVar('PRIVATE_LIBS_' + pkg, True) or d.getVar('PRIVATE_LIBS', True) or "" + private_libs = private_libs.split() needs_ldconfig = False bb.debug(2, "calculating shlib provides for %s" % pkg)
@@ -1556,6 +1557,14 @@ python package_do_shlibs() { deps = list() for n in needed[pkg]: + # if n is in private libraries, don't try to search provider for it + # this could cause problem in case some abc.bb provides private + # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1 + # but skipping it is still better alternative than providing own + # version and then adding runtime dependency for the same system library + if private_libs and n in private_libs: + bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n)) + continue if n in shlib_provider.keys(): (dep_pkg, ver_needed) = shlib_provider[n]
Signature · 1 line
1.8.5.3
PATCH v3 2/3 package.bbclass: Show which files require given dependency in debug output
In reply to Martin Jansa* when log.do_package shows some unexpected dependency, people usually need to grep package directory to find which binary was creating that dependency, show it directly in the debug output
--- meta/classes/package.bbclass | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
meta/classes/package.bbclass +10 -2
@@ -1397,6 +1397,9 @@ python package_do_shlibs() { if m: if m.group(1) not in needed[pkg]: needed[pkg].append(m.group(1)) + if m.group(1) not in needed_from: + needed_from[m.group(1)] = [] + needed_from[m.group(1)].append(file) m = re.match("\s+SONAME\s+([^\s]*)", l) if m: this_soname = m.group(1)
@@ -1469,6 +1472,10 @@ python package_do_shlibs() { needed[pkg] = [] if name and name not in needed[pkg]: needed[pkg].append(name) + if name not in needed_from: + needed_from[name] = [] + if lafile and lafile not in needed_from[name]: + needed_from[name].append(lafile) #bb.note("Adding %s for %s" % (name, pkg)) if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS', True) == "1":
@@ -1482,6 +1489,7 @@ python package_do_shlibs() { use_ldconfig = False needed = {} + needed_from = {} shlib_provider = {} read_shlib_providers()
@@ -1568,7 +1576,7 @@ python package_do_shlibs() { if n in shlib_provider.keys(): (dep_pkg, ver_needed) = shlib_provider[n] - bb.debug(2, '%s: Dependency %s requires package %s' % (pkg, n, dep_pkg)) + bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n, dep_pkg, needed_from[n])) if dep_pkg == pkg: continue
@@ -1580,7 +1588,7 @@ python package_do_shlibs() { if not dep in deps: deps.append(dep) else: - bb.note("Couldn't find shared library provider for %s" % n) + bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n, needed_from[n])) deps_file = os.path.join(pkgdest, pkg + ".shlibdeps") if os.path.exists(deps_file):
Signature · 1 line
1.8.5.3
PATCH v3 3/3 package.bbclass: add SHLIBSSEARCHDIRS to define where to search for shlib providers
In reply to Martin Jansa* 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]
--- meta/classes/package.bbclass | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
meta/classes/package.bbclass +23 -3
@@ -1333,6 +1333,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
@@ -1343,6 +1346,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)
@@ -1404,9 +1421,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 this_soname not in private_libs: - 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 this_soname not in private_libs: + 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):
Signature · 1 line
1.8.5.3