#!/bin/sh
#(c) Copyright 2014 Barry Kauler.
#141213 first version.
#150924 fix for path of db file in woofQ.
#170515 converted (trom T2) to OE.
#170516 ignore pkgs named packagegroup-*
#170517 strip the files.
#170601 tmp-glibc/work/${ACAT}-oe-linux in buildQ, -oe-linux-gnueabi in buildPi. 170602
#171019 allow stripping for WOOF_TARGETARCH='amd64x32' WOOF_HOSTARCH='amd64'
#171021 fix path.
#180608 some tests.
#180701 path depth cutting was wrong.
#180715 find dependencies.
#180723 support cross-build strip.
#180724 calc size of a package after stripping.

export LANG=C #faster.
. ./DISTRO_SPECS
[ ! "$DISTRO_DB_SUBNAME" ] && DISTRO_DB_SUBNAME="$DISTRO_COMPAT_VERSION" #121102 fallback if DISTRO_DB_SUBNAME not defined in file DISTRO_SPECS.
. ./DISTRO_COMPAT_REPOS-oe-${DISTRO_COMPAT_VERSION} #has PKG_DOCS_DISTRO_COMPAT
. ./DISTRO_PKGS_SPECS-oe-${DISTRO_COMPAT_VERSION}
ONE_PKGLISTS_COMPAT="`echo "$PKG_DOCS_DISTRO_COMPAT" | tr ' ' '\n' | cut -f 3 -d '|' | head -n 1`"
#...ex: Packages-oe-${DISTRO_COMPAT_VERSION}-official, which is Packages-oe-pyro-official
FIND_CAT="./support/find_cat"

PKGLISTS_COMPAT="`echo "$PKG_DOCS_DISTRO_COMPAT" | tr ' ' '\n' | cut -f 3 -d '|' | head -n 1`" #see file DISTRO_PKGS_SPECS-oe-pyro
#...ex: Packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}-official, which is Packages-oe-pyro-official

if [ ! -f WOOFMERGEVARS ];then
 echo
 echo "ERROR: file WOOFMERGEVARS is created by merge2out. not there"
 exit
fi
. ./WOOFMERGEVARS #has WOOF_TARGETARCH

echo
echo "Script '0pre-oe' has to run beforehand, once."
echo "Script '0pre-oe-add' is for extracting one (or more) binary package(s) from OE"
echo "and add it/them to woofQ. A db-entry will be created for the new package."
echo "The scenario is where you have compiled an extra package in OE, after"
echo "the main compile, and want to add that package to woofQ target build."
echo "This script will also detect, and offer to delete, old packages."

if [ ! -f status/OE_SUPPORT ];then
 echo
 echo "A previous run of '0pre-oe' will have created status/OE_SUPPORT"
 echo "This does not exist, aborting."
 exit
fi

. ./status/OE_SUPPORT #OEPATH, OEPROFILE
OEOK=0
[ ! "$OEPATH" ] && OEOK=1
[ ! "$OEPROFILE" ] && OEOK=1
[ ! -d ${OEPATH}/${OEPROFILE} ] && OEOK=1
if [ $OEOK -eq 1 ];then
 echo
 echo "ERROR: OE path wrong."
 exit
fi

yPWD=`pwd`
#180723 find the cross-build strip executable in oe... (for aarch64 build it will be aarch64-oe-linux-strip)
if [ ! -f support/cross-strip ];then
 CROSS_STRIP_FND="$(find ${OEPATH}/${OEPROFILE}/tmp-glibc/sysroots-components -type f -name '*-strip' | grep '/binutils\-cross\-' | head -n 1)"
 if [ "$CROSS_STRIP_FND" ];then
  cp -a -f ${CROSS_STRIP_FND} support/cross-strip
 else
  echo 'ERROR: unable to find the cross-strip executable in OE, aborting'
  exit 2
 fi
fi

#get list of all binary pkgs already in woofQ target:
CURRBINS="$(find packages-oe-${DISTRO_COMPAT_VERSION}/ -mindepth 1 -maxdepth 1 -type f -name '*.xz' | rev | cut -f 1 -d '/' | rev | sort)"
echo "$CURRBINS" > /tmp/0pre-add1-currbins

#get list of binary pkgs in oe:
echo 'please wait, scanning...'
echo -n '' > /tmp/0pre-oe-add-nameverarch
echo -n '' > /tmp/0pre-oe-add-fullpkgs
OEIMAGES="$(find ${OEPATH}/${OEPROFILE}/tmp-glibc/work/*-oe-linux*/*/*/ -mindepth 1 -maxdepth 1 -type d -name image)"
#ex:  /mnt/sda2/oe/oe-quirky/buildQ/tmp-glibc/work/pcx86_64-oe-linux/xserver-xf86-config/0.1-r33/image
#ex: /mnt/sdb1/projects/oe/oe-quirky/buildPC/tmp-glibc/work/nocona-64-oe-linux/zlib/1.2.11-r0/image

#180701 fix cutting depth...
DEPTHoe=`echo -n "${OEPATH}/${OEPROFILE}/" | sed -e 's%[^/]%%g' | wc -m` #8
DEPTHarch=$((DEPTHoe+3))
DEPTHname=$(($DEPTHoe+4))
DEPTHver=$(($DEPTHoe+5))

for AIMAGE in $OEIMAGES
do
 [ ! "$AIMAGE" ] && continue
 #180701...
 ANAME="$(echo -n "$AIMAGE" | cut -f ${DEPTHname} -d '/')"
 [ "$(echo -n "$ANAME" | cut -f 1 -d '-')" == "packagegroup" ] && continue #170516 ignore pkgs named packagegroup-*
 AVER="$(echo -n "$AIMAGE" | cut -f ${DEPTHver} -d '/')"
 AARCH="$(echo -n "$AIMAGE" | cut -f ${DEPTHarch} -d '/' | sed -e 's%\-oe\-linux.*%%')"
 [[ $ANAME == *-native ]] && continue
 [[ $ANAME == *-cross ]] && continue
 echo "${ANAME}-${AVER}-${AARCH}.tar.xz ${ANAME} ${AVER} ${AARCH}" >> /tmp/0pre-oe-add-nameverarch
 echo "${ANAME}-${AVER}-${AARCH}.tar.xz" >> /tmp/0pre-oe-add-fullpkgs
done
OEBINS="$(sort /tmp/0pre-oe-add-fullpkgs)"

echo "$OEBINS" > /tmp/0pre-add1-oebins

OECOMPARE="$(diff /tmp/0pre-add1-currbins /tmp/0pre-add1-oebins)"

OEDUMPED="$(echo "$OECOMPARE" | grep '^< ' | cut -f 2 -d ' ')"
OENEW="$(echo "$OECOMPARE" | grep '^> ' | cut -f 2 -d ' ')"

if [ "$OEDUMPED" ];then
 echo
 echo "These local binary packages, in folder packages-oe-${DISTRO_COMPAT_VERSION}"
 echo "are no longer in the OE build:"
 echo "$OEDUMPED"
 echo
 echo "Suggest they be deleted."
 echo -n "Press ENTER only to delete them, any other key to keep:"
 read oldoekeep
 if [ "$oldoekeep" = "" ];then
  for aoldoe in `echo "$OEDUMPED" | tr '\n' ' '`
  do
   echo "Removing ${aoldoe}"
   rm -f packages-oe-${DISTRO_COMPAT_VERSION}/${aoldoe}
   aPTN="|${aoldoe}|"
   grep -v "$aPTN" ${ONE_PKGLISTS_COMPAT} > /tmp/0pre-add1-dbrem #ex: remove entry from Packages-oe-pyro-official
   mv -f /tmp/0pre-add1-dbrem ${ONE_PKGLISTS_COMPAT}
  done
  if [ -d ../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION} ];then
  
   #150924...
   WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}"
   [ ! -f ${WOOFQMASTERPATH}/${ONE_PKGLISTS_COMPAT} ] && WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}"
   [ ! -f ${WOOFQMASTERPATH}/${ONE_PKGLISTS_COMPAT} ] && WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}"
   
   echo
   echo "Suggest also update the master woofQ (Quirky build system) pkg-db:"
   echo "${WOOFQMASTERPATH}/${ONE_PKGLISTS_COMPAT}"
   #ex: ../../quirky/woof-distro/x86/oe/pyro/Packages-oe-pyro-official
   echo -n "Press ENTER only to update this file:"
   read oeupdate
   [ "$oeupdate" == "" ] && cp -a -f ${ONE_PKGLISTS_COMPAT} ${WOOFQMASTERPATH}/ #150924
  fi
 fi
fi

if [ "$OENEW" ];then
 echo
 echo "These OE packages are not in local folder packages-oe-${DISTRO_COMPAT_VERSION}:"
 echo "$OENEW"
 echo
 echo "Suggest they be added."
 echo -n "Press ENTER only to add them, any other key to not:"
 read oldoekeep
 if [ "$oldoekeep" = "" ];then
  for aoldoe in `echo "$OENEW" | tr '\n' ' '`
  do
   echo "Adding ${aoldoe}" #ex: aoldoe=cairo-1.14.8-r0-core2-64.tar.xz
   ANAME="$(grep "^${aoldoe} " /tmp/0pre-oe-add-nameverarch | cut -f 2 -d ' ')"
   AVER="$(grep "^${aoldoe} " /tmp/0pre-oe-add-nameverarch | cut -f 3 -d ' ')"
   AARCH="$(grep "^${aoldoe} " /tmp/0pre-oe-add-nameverarch | cut -f 4 -d ' ')"
   AIMG="$(find ${OEPATH}/${OEPROFILE}/tmp-glibc/work/${AARCH}-oe-linux*/${ANAME}/${AVER}/ -mindepth 1 -maxdepth 1 -type d -name image)" #170601
   [ ! "$AIMG" ] && continue #precaution
   echo "Found path: ${AIMG}" #180608
   #have full path to the 'image' folder. now create db-entry, then tarball...
   
   DB_pkgname="${ANAME}-${AVER}"
   DB_nameonly="${ANAME}"
   DB_version="${AVER}"
   DB_fullfilename="${ANAME}-${AVER}-${AARCH}.tar.xz"
   DB_path="${DISTRO_COMPAT_VERSION}"
   
   #can find description by looking in the recipe...
   #ARECIPE="$(grep '^"'"${DB_nameonly}"'" \[label="' ${OEPATH}/${OEPROFILE}/recipe-depends.dot | grep -o "${OEPATH}/.*" | cut -f 1 -d '"')"
   ARECIPE="$(grep "^\"${DB_nameonly}\".*label=" ${OEPATH}/${OEPROFILE}/recipe-depends.dot  | grep -o "${OEPATH}/.*" | cut -f 1 -d '"')" #180608
   if [ ! "$ARECIPE" ];then #180608
    #continue #precaution
    echo "Error: the .bb recipe file was not found."
    echo "Most likely did a build in OE with drivename different from now."
    echo "Looked in this file:
  ${OEPATH}/${OEPROFILE}/recipe-depends.dot"
    echo "Aborting"
    exit
   fi
   echo "Found recipe: ${ARECIPE}"
   DB_description="$(grep "^SUMMARY = " $ARECIPE | cut -f 2 -d '"' | sed -e 's%[^a-zA-Z0-9_. -]%%g')"
   
   #180715 find dependencies...
   DB_dependencies=''; DEPENDS0=''
   if [ -f ${OEPATH}/${OEPROFILE}/recipe-depends.dot ];then
    PTNdot='^"'"${DB_nameonly}"'" -'
    DEPENDSx="$(grep "${PTNdot}" ${OEPATH}/${OEPROFILE}/recipe-depends.dot | cut -f 4 -d '"' | grep -v '\-native$' | grep -v '\-cross' | grep -v 'packagegroup\-')"
    if [ "$DEPENDSx" ];then
     DEPENDS0="$(echo "$DEPENDSx" | tr '\n' ' ' | sed -e 's% $%%')"
    else
     echo "ERROR: You forgot to regenerate ${OEPATH}/${OEPROFILE}/recipe-depends.dot"
     echo "       It does not have entry for '${DB_nameonly}'"
     echo "       Go back to OE and run 'bitbake -g <buildname>'"
    fi
   fi
   [ "$DEPENDS0" ] && DB_dependencies="$(echo -n "$DEPENDS0" | sed -e 's%^%+%' -e 's% %,+%g' -e 's%,$%%' | sed -e 's% %%g' -e 's%,$%%' -e 's%+$%%')"
   
   xDB_description="$DB_description"
   [ "$DB_description" = "" ] && xDB_description="nothing"
   DB_category="$(${FIND_CAT} $DB_nameonly "$xDB_description")" #see updated find_cat

   DB_homepage="$(grep "^HOMEPAGE = " $ARECIPE | cut -f 2 -d '"')"
   [ "$DB_homepage" ] && echo "${DB_nameonly} ${DB_homepage}" >> PKGS_HOMEPAGES
   
   #170517 strip the files... 180723 now support cross-build strip...
   echo "Stripping files..."
   [ -d ${AIMG}XXX ] && rm -rf ${AIMG}XXX
   cp -a ${AIMG} ${AIMG}XXX
   ##171019 allow WOOF_TARGETARCH='amd64x32' WOOF_HOSTARCH='amd64' ...
   #if [[ ${WOOF_TARGETARCH} == ${WOOF_HOSTARCH}* ]] ;then #strip will not work for cross-build.
    find ${AIMG}XXX/bin ${AIMG}XXX/sbin ${AIMG}XXX/usr/bin ${AIMG}/sbin -type f 2>/dev/null |
    while read ONEFILE
    do
     [ "$ONEFILE" == "" ] && continue
     ONEBASE="`basename "$ONEFILE"`"
     [ "$ONEBASE" == "e3" ] && continue #cannot be stripped.
     [ "$ONEBASE" == "QtWeb" ] && continue #cannot be stripped.
     if [ "`file "$ONEFILE" | grep 'ELF' | grep 'executable'`" != "" ];then
      echo -n "."
      ${yPWD}/support/cross-strip --strip-unneeded "$ONEFILE" #180723
     fi
    done
    echo
    find ${AIMG}XXX/lib ${AIMG}XXX/usr/lib -type f -name \*.so* 2>/dev/null |
    while read ONEFILE
    do
     [ "$ONEFILE" == "" ] && continue
     ONEBASE="`basename "$ONEFILE"`"
     if [ "`file "$ONEFILE" | grep 'ELF' | grep 'shared object'`" != "" ];then
      echo -n "."
      ${yPWD}/support/cross-strip --strip-unneeded "$ONEFILE" #180723
     fi
    done
   #fi
   
   #180724 this has to be done after stripping...
   DB_size="$(du -s -k ${AIMG}XXX | cut -f 1)K"
   DBENTRY="$DB_pkgname|$DB_nameonly|$DB_version|$DB_pkgrelease|$DB_category|${DB_size}|$DB_path|$DB_fullfilename|$DB_dependencies|$DB_description|$DISTRO_BINARY_COMPAT|$DISTRO_COMPAT_VERSION||"
   echo "$DBENTRY" >> $PKGLISTS_COMPAT
  
   sync
   echo ; echo '...done'
  
   #import the package...
   echo "${DBENTRY}${AARCH}|${DB_homepage}|" > ${AIMG}XXX/pkg.specs #maybe useful to have in the pkg.
   cd ${AIMG}XXX
   tar -c -f  ${yPWD}/packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}/${DB_pkgname}-${AARCH}.tar *
   cd "$yPWD"
   cd packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}
   xz ${DB_pkgname}-${AARCH}.tar
   cd ..
   sync
   rm -f ${AIMG}/pkg.specs
   
  done
  #sort db entries...
  sort --key=1,1 --field-separator='|' $PKGLISTS_COMPAT > /tmp/0pre-$PKGLISTS_COMPAT
  mv -f /tmp/0pre-$PKGLISTS_COMPAT $PKGLISTS_COMPAT
  
  if [ -d ../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION} ];then

   #150924...
   WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}"
   [ ! -f ${WOOFQMASTERPATH}/${ONE_PKGLISTS_COMPAT} ] && WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}"
   [ ! -f ${WOOFQMASTERPATH}/${ONE_PKGLISTS_COMPAT} ] && WOOFQMASTERPATH="../../quirky/woof-distro/${WOOF_TARGETARCH}"
   
   echo
   echo "Suggest also update the master woofQ (Quirky build system) pkg-db:"
   echo "${WOOFQMASTERPATH}/${PKGLISTS_COMPAT}"
   #ex: ../../quirky/woof-distro/x86/oe/pyro/Packages-oe-pyro-official
   echo -n "Press ENTER only to update this file:"
   read oeupdate
   [ "$oeupdate" == "" ] && cp -a -f ${PKGLISTS_COMPAT} ${WOOFQMASTERPATH}/
  fi
 fi
fi

echo
echo '...finished'
