On 11/13/13, 4:33 AM, Paul Eggleton wrote:
Hi Mark,

On Tuesday 12 November 2013 19:59:20 Mark Hatle wrote:
In the translate oe to smart function, we only translated package names.
However, it's allowed that people can put in a dependency name in the
IMAGE_INSTALL.  So on a failure to translate a package name, we fall back
and attempt to resolve based on a package's provide.

Note: it may be possible to generate an unsolvable install solution.  If the
dependency is provided by one or more things that conflict with something
else set to be installed.  We can't determine this until smart is run.

If this occurs, file a bug and we'll have to identify a way to deal with the
RCONFLICTS and RREPLACES.  As a workaround replace the conflict REQUIRES
with actual package names.

Signed-off-by: Mark Hatle <[email protected]>
---
  meta/classes/package_rpm.bbclass | 79
++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+),
4 deletions(-)

diff --git a/meta/classes/package_rpm.bbclass
b/meta/classes/package_rpm.bbclass index 31265d9..9fe0e6c 100644
--- a/meta/classes/package_rpm.bbclass
+++ b/meta/classes/package_rpm.bbclass
@@ -166,6 +166,7 @@ translate_oe_to_smart() {
        [ ! -e ${target_rootfs}/install/tmp/fullpkglist.query ] && smart
--data-dir=${target_rootfs}/var/lib/smart query --output
${target_rootfs}/install/tmp/fullpkglist.query

        pkgs_to_install=""
+       not_found=""
        for pkg in "$@" ; do
                new_pkg="$pkg"
                if [ -z "$sdk_mode" ]; then
@@ -184,7 +185,6 @@ translate_oe_to_smart() {
                                fi
                                subst=${pkg#${mlib}-}
                                if [ "$subst" != "$pkg" ]; then
-                                       feeds=$@
                                        while [ -n "$1" ]; do
                                                arch="$1"
                                                arch=`echo "$arch" | tr - _`
@@ -197,6 +197,76 @@ translate_oe_to_smart() {
                                        done
                                        if [ "$pkg" = "$new_pkg" ]; then
                                                # Failed to translate, package 
not found!

Just to be clear the following diff is rather confusing.. there are two one line changes (the error to the no_found line below) in the existing code, and then the new chunk of code after both to process the not_found entries, which are presumed to be dependencies.)

If you apply this, or look at it in context it's easier to see..

+                                               not_found="$not_found $pkg"
+                                               continue
+                                       fi
+                               fi
+                       done
+               fi
+               # Apparently not a multilib package...
+               if [ "$pkg" = "$new_pkg" ]; then
+                       default_archs_fixed=`echo "$default_archs" | tr - _`
+                       for arch in $default_archs_fixed ; do
+                               if grep -q '^'$pkg'-[^-]*-[^-]*@'$arch'$'
${target_rootfs}/install/tmp/fullpkglist.query ; then
+                                       new_pkg="$pkg@$arch"
+                                       # First found is best match
+                                       break
+                               fi
+                       done
+                       if [ "$pkg" = "$new_pkg" ]; then
+                               # Failed to translate, package not found!
+                               not_found="$not_found $pkg"
+                               continue
+                       fi
+               fi
+               #echo "$pkg -> $new_pkg" >&2
+               pkgs_to_install="${pkgs_to_install} ${new_pkg}"
+       done
+
+       # Parse the not_found items and see if they were dependencies 
(RPROVIDES)
+       # Follow the parsing example above...
+       for pkg in $not_found ; do
+               new_pkg="$pkg"
+               smart --data-dir=${target_rootfs}/var/lib/smart query 
--provides=$pkg
--output ${target_rootfs}/install/tmp/provide.query +           grep '^[^@
]*@[^@]*$' ${target_rootfs}/install/tmp/provide.query | sed -e
's,\(.*\)-[^-]*-[^-]*\(@[^@]*\)$,\1\2,' >
${target_rootfs}/install/tmp/provide.query.list || : +          prov=`echo
$pkgs_to_install | xargs -n 1 echo | grep -f
${target_rootfs}/install/tmp/provide.query.list || :` +         if [ -n "$prov"
];
then
+                       # Nothing to do, already in the list
+                       #echo "Skipping $pkg -> $prov, already in install set" 
>&2
+                       continue
+               fi
+               if [ -z "$sdk_mode" ]; then
+                       for i in ${MULTILIB_PREFIX_LIST} ; do
+                               old_IFS="$IFS"
+                               IFS=":"
+                               set $i
+                               IFS="$old_IFS"
+                               mlib="$1"
+                               shift
+                               if [ "$mlib" = "default" ]; then
+                                       if [ -z "$default_archs" ]; then
+                                               default_archs=$@
+                                       fi
+                                       continue
+                               fi
+                               subst=${pkg#${mlib}-}
+                               if [ "$subst" != "$pkg" ]; then
+                                       feeds=$@
+                                       smart 
--data-dir=${target_rootfs}/var/lib/smart query
--provides=$subst --output ${target_rootfs}/install/tmp/provide.query
+                                       grep '^[^@ ]*@[^@]*$'
${target_rootfs}/install/tmp/provide.query |
sed -e 's,\(.*\)-[^-]*-[^-]*\(@[^@]*\)$,\1\2,' >
${target_rootfs}/install/tmp/provide.query.list || : +                          
        while [
-n "$1"
]; do
+                                               arch="$1"
+                                               arch=`echo "$arch" | tr - _`
+                                               shift
+                                               # Select first found, we don't 
know if one is better then
another...
+                                               prov=`grep '^[^@ ]*@'$arch'$'
${target_rootfs}/install/tmp/provide.query.list | head -n 1` +                  
                        
if [ -n
"$prov" ]; then
+                                                       new_pkg=$prov
+                                                       break
+                                               fi
+                                       done
+                                       if [ "$pkg" = "$new_pkg" ]; then
+                                               # Failed to translate, package 
not found!
                                                echo "$attemptonly: $pkg not 
found in the $mlib feeds
($feeds)." >&2
                                                if [ "$attemptonly" = "Error" 
]; then
                                                        exit 1
@@ -210,9 +280,10 @@ translate_oe_to_smart() {
                if [ "$pkg" = "$new_pkg" ]; then
                        default_archs_fixed=`echo "$default_archs" | tr - _`
                        for arch in $default_archs_fixed ; do
-                               if grep -q '^'$pkg'-[^-]*-[^-]*@'$arch'$'
${target_rootfs}/install/tmp/fullpkglist.query ; then
-                                       new_pkg="$pkg@$arch"
-                                       # First found is best match
+                               # Select first found, we don't know if one is 
better then
another...
+                               prov=`grep '^[^@ ]*@'$arch'$'
${target_rootfs}/install/tmp/provide.query.list | head -n 1` +                  
        if
[ -n
"$prov" ]; then
+                                       new_pkg=$prov
                                        break
                                fi
                        done

Sigh... this code is getting ridiculously complicated. Shouldn't Smart be
doing more of the heavy lifting here?

This function translate_oe_to_smart (and the corresponding translate_smart_to_oe) are used to switch from one name space to another. Remember in the RPM world, we don't use prefixes like "lib32-" on our package names, instead we use specific arch's that refer to specific ABI and processor tunings.

This is what enables the seamless multilib install on RPM.

What this code does is allows for dependencies to be added to the mix. If we didn't have multilibs then none of this code would be needed, but since we do -- the name space of both the package and dependencies need to be translate, not just packages as we'd done before.

Generally what this function does:

for each multilib prefx:
   if PN starts w/ a known multilib prefix:
      we translate it to: BPN@arch
      check if the package exists
         if it does add to pkg_list
         else add to "not_found"
anything remaining is translated to the default arch
   check if the package exists
       if it does add to pkg_list
       else add to "not_found"

if there are any "not_found", we assume they must be provides:
   for each multilib prefix:
      if the DEPENDENCY starts w/ a known multilib prefix:
         we translate it without the prefix
         ask smart what provides that dependency
         check if something already in the pkg_list is there, if so skip it
         else use priority ordering to select the best provider -- add to 
pkg_list
   for anything w/o a multilib prefix, follow the same steps

The reverse smart_to_oe function doesn't ever need to pay attention to dependencies so that is not an issue, and the translation is significantly more straight forward.

If we had unique namespaces in oe, and didn't use the lib* markers on multilibs.. then none of this would be necessary.. (but then of course dpkg and opkg wouldn't work properly.) So the translation is a necessary evil.

Could it be done differently, most likely. Perhaps identifying a way to do it in python would be quicker.. but it's actually pretty fast sine the majority of translations happen via a static list and a single grep. It's only the (hopefully) small number of dependencies that happen via individual calls to smart which impose a time penalty.

--Mark

Cheers,
Paul


_______________________________________________
Openembedded-core mailing list
[email protected]
http://lists.openembedded.org/mailman/listinfo/openembedded-core

Reply via email to