Files
poky/meta/classes/package_rpm.bbclass
Richard Purdie 68baef9065 package_rpm: Ensure we take the sstate shared lockfile in the place we write files
The point we need to take the lock is when the rpm files are written into the
deploy rpm directory. Since sstate makes the actual installation of the files,
that is the point we need to take the lock. This also stops the deploy/rpm
directory being accessed for a lock before it exists.

[YOCTO #797]
[YOCTO #925]

(From OE-Core rev: 833a1e970f087dfcb32967cee3e24540f041cde0)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2011-03-29 14:01:52 +01:00

817 lines
28 KiB
Plaintext

inherit package
IMAGE_PKGTYPE ?= "rpm"
RPM="rpm"
RPMBUILD="rpmbuild"
PKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms"
python package_rpm_fn () {
bb.data.setVar('PKGFN', bb.data.getVar('PKG',d), d)
}
python package_rpm_install () {
bb.fatal("package_rpm_install not implemented!")
}
RPMCONF_TARGET_BASE = "${DEPLOY_DIR_RPM}/solvedb"
RPMCONF_HOST_BASE = "${DEPLOY_DIR_RPM}/solvedb-sdk"
#
# Update the Packages depsolver db in ${DEPLOY_DIR_RPM}
#
package_update_index_rpm () {
rpmarchs="${PACKAGE_ARCHS}"
if [ ! -z "${DEPLOY_KEEP_PACKAGES}" ]; then
return
fi
packagedirs=""
packagedirs_sdk=""
for arch in $rpmarchs ; do
sdkarch=`echo $arch | sed -e 's/${HOST_ARCH}/${SDK_ARCH}/'`
extension="-nativesdk"
if [ "$sdkarch" = "all" -o "$sdkarch" = "any" -o "$sdkarch" = "noarch" ]; then
extension=""
fi
packagedirs="${DEPLOY_DIR_RPM}/$arch $packagedirs"
packagedirs_sdk="${DEPLOY_DIR_RPM}/$sdkarch$extension $packagedirs_sdk"
rm -rf ${DEPLOY_DIR_RPM}/$arch/solvedb
rm -rf ${DEPLOY_DIR_RPM}/$sdkarch$extension/solvedb
done
cat /dev/null > ${RPMCONF_TARGET_BASE}.conf
for pkgdir in $packagedirs; do
if [ -e $pkgdir/ ]; then
echo "Generating solve db for $pkgdir..."
echo $pkgdir/solvedb >> ${RPMCONF_TARGET_BASE}.conf
if [ -d $pkgdir/solvedb ]; then
# We've already processed this and it's a duplicate
continue
fi
mkdir -p $pkgdir/solvedb
echo "# Dynamically generated solve manifest" >> $pkgdir/solvedb/manifest
find $pkgdir -maxdepth 1 -type f >> $pkgdir/solvedb/manifest
${RPM} -i --replacepkgs --replacefiles --oldpackage \
-D "_dbpath $pkgdir/solvedb" --justdb \
--noaid --nodeps --noorder --noscripts --notriggers --noparentdirs --nolinktos --stats \
--ignoresize --nosignature --nodigest \
-D "__dbi_txn create nofsync" \
$pkgdir/solvedb/manifest
fi
done
cat /dev/null > ${RPMCONF_HOST_BASE}.conf
for pkgdir in $packagedirs_sdk; do
if [ -e $pkgdir/ ]; then
echo "Generating solve db for $pkgdir..."
echo $pkgdir/solvedb >> ${RPMCONF_HOST_BASE}.conf
if [ -d $pkgdir/solvedb ]; then
# We've already processed this and it's a duplicate
continue
fi
mkdir -p $pkgdir/solvedb
echo "# Dynamically generated solve manifest" >> $pkgdir/solvedb/manifest
find $pkgdir -maxdepth 1 -type f >> $pkgdir/solvedb/manifest
${RPM} -i --replacepkgs --replacefiles --oldpackage \
-D "_dbpath $pkgdir/solvedb" --justdb \
--noaid --nodeps --noorder --noscripts --notriggers --noparentdirs --nolinktos --stats \
--ignoresize --nosignature --nodigest \
-D "__dbi_txn create nofsync" \
$pkgdir/solvedb/manifest
fi
done
}
#
# Generate an rpm configuration suitable for use against the
# generated depsolver db's...
#
package_generate_rpm_conf () {
printf "_solve_dbpath " > ${RPMCONF_TARGET_BASE}.macro
colon=false
for each in `cat ${RPMCONF_TARGET_BASE}.conf` ; do
if [ "$colon" == true ]; then
printf ":" >> ${RPMCONF_TARGET_BASE}.macro
fi
printf "%s" $each >> ${RPMCONF_TARGET_BASE}.macro
colon=true
done
printf "\n" >> ${RPMCONF_TARGET_BASE}.macro
printf "_solve_dbpath " > ${RPMCONF_HOST_BASE}.macro
colon=false
for each in `cat ${RPMCONF_HOST_BASE}.conf` ; do
if [ "$colon" == true ]; then
printf ":" >> ${RPMCONF_HOST_BASE}.macro
fi
printf "%s" $each >> ${RPMCONF_HOST_BASE}.macro
colon=true
done
printf "\n" >> ${RPMCONF_HOST_BASE}.macro
}
rpm_log_check() {
target="$1"
lf_path="$2"
lf_txt="`cat $lf_path`"
for keyword_die in "Cannot find package" "exit 1" ERR Fail
do
if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1
then
echo "log_check: There were error messages in the logfile"
echo -e "log_check: Matched keyword: [$keyword_die]\n"
echo "$lf_txt" | grep -v log_check | grep -C 5 -i "$keyword_die"
echo ""
do_exit=1
fi
done
test "$do_exit" = 1 && exit 1
true
}
#
# Resolve package names to filepaths
# resolve_pacakge <pkgname> <solvdb conffile>
#
resolve_package_rpm () {
local pkg="$1"
local conffile="$2"
local pkg_name=""
for solve in `cat ${conffile}`; do
pkg_name=$(${RPM} -D "_dbpath $solve" -D "__dbi_txn create nofsync" -q --yaml $pkg | grep -i 'Packageorigin' | cut -d : -f 2)
if [ -n "$pkg_name" ]; then
break;
fi
done
echo $pkg_name
}
#
# install a bunch of packages using rpm
# the following shell variables needs to be set before calling this func:
# INSTALL_ROOTFS_RPM - install root dir
# INSTALL_PLATFORM_RPM - main platform
# INSTALL_PLATFORM_EXTRA_RPM - extra platform
# INSTALL_CONFBASE_RPM - configuration file base name
# INSTALL_PACKAGES_NORMAL_RPM - packages to be installed
# INSTALL_PACKAGES_ATTEMPTONLY_RPM - packages attemped to be installed only
# INSTALL_PACKAGES_LINGUAS_RPM - additional packages for uclibc
# INSTALL_PROVIDENAME_RPM - content for provide name
# INSTALL_TASK_RPM - task name
package_install_internal_rpm () {
local target_rootfs="${INSTALL_ROOTFS_RPM}"
local platform="${INSTALL_PLATFORM_RPM}"
local platform_extra="${INSTALL_PLATFORM_EXTRA_RPM}"
local confbase="${INSTALL_CONFBASE_RPM}"
local package_to_install="${INSTALL_PACKAGES_NORMAL_RPM}"
local package_attemptonly="${INSTALL_PACKAGES_ATTEMPTONLY_RPM}"
local package_lingusa="${INSTALL_PACKAGES_LINGUAS_RPM}"
local providename="${INSTALL_PROVIDENAME_RPM}"
local task="${INSTALL_TASK_RPM}"
# Setup base system configuration
mkdir -p ${target_rootfs}/etc/rpm/
echo "${platform}-poky-linux-gnu" > ${target_rootfs}/etc/rpm/platform
if [ ! -z "$platform_extra" ]; then
for pt in $platform_extra ; do
echo "$pt-.*-linux.*" >> ${target_rootfs}/etc/rpm/platform
done
fi
# Tell RPM that the "/" directory exist and is available
mkdir -p ${target_rootfs}/etc/rpm/sysinfo
echo "/" >${target_rootfs}/etc/rpm/sysinfo/Dirnames
if [ ! -z "$providename" ]; then
>>${target_rootfs}/etc/rpm/sysinfo/Providename
for provide in $providename ; do
echo $provide >> ${target_rootfs}/etc/rpm/sysinfo/Providename
done
fi
# Setup manifest of packages to install...
mkdir -p ${target_rootfs}/install
echo "# Install manifest" > ${target_rootfs}/install/install.manifest
# Uclibc builds don't provide this stuff...
if [ x${TARGET_OS} = "xlinux" ] || [ x${TARGET_OS} = "xlinux-gnueabi" ] ; then
if [ ! -z "${package_lingusa}" ]; then
for pkg in ${package_lingusa}; do
echo "Processing $pkg..."
pkg_name=$(resolve_package_rpm $pkg ${confbase}.conf)
if [ -z "$pkg_name" ]; then
echo "Unable to find package $pkg!"
exit 1
fi
echo $pkg_name >> ${IMAGE_ROOTFS}/install/install.manifest
done
fi
fi
if [ ! -z "${package_to_install}" ]; then
for pkg in ${package_to_install} ; do
echo "Processing $pkg..."
pkg_name=$(resolve_package_rpm $pkg ${confbase}.conf)
if [ -z "$pkg_name" ]; then
echo "Unable to find package $pkg!"
exit 1
fi
echo $pkg_name >> ${target_rootfs}/install/install.manifest
done
fi
# Generate an install solution by doing a --justdb install, then recreate it with
# an actual package install!
${RPM} --predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \
--predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \
-D "_dbpath ${target_rootfs}/install" -D "`cat ${confbase}.macro`" \
-D "__dbi_txn create nofsync" \
-U --justdb --noscripts --notriggers --noparentdirs --nolinktos --ignoresize \
${target_rootfs}/install/install.manifest
if [ ! -z "${package_attemptonly}" ]; then
echo "Adding attempt only packages..."
for pkg in ${package_attemptonly} ; do
echo "Processing $pkg..."
pkg_name=$(resolve_package_rpm $pkg ${confbase}.conf)
if [ -z "$pkg_name" ]; then
echo "Unable to find package $pkg!"
exit 1
fi
echo "Attempting $pkg_name..." >> "${WORKDIR}/temp/log.do_${task}_attemptonly.${PID}"
${RPM} --predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \
--predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \
-D "_dbpath ${target_rootfs}/install" -D "`cat ${confbase}.macro`" \
-D "__dbi_txn create nofsync private" \
-U --justdb --noscripts --notriggers --noparentdirs --nolinktos --ignoresize \
$pkg_name >> "${WORKDIR}/temp/log.do_${task}_attemptonly.${PID}" || true
done
fi
#### Note: 'Recommends' is an arbitrary tag that means _SUGGESTS_ in Poky..
# Add any recommended packages to the image
# RPM does not solve for recommended packages because they are optional...
# So we query them and tree them like the ATTEMPTONLY packages above...
# Change the loop to "1" to run this code...
loop=0
if [ $loop -eq 1 ]; then
echo "Processing recommended packages..."
cat /dev/null > ${target_rootfs}/install/recommend.list
while [ $loop -eq 1 ]; do
# Dump the full set of recommends...
${RPM} --predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \
--predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \
-D "_dbpath ${IMAGE_ROOTFS}/install" -D "`cat ${confbase}.macro`" \
-D "__dbi_txn create nofsync private" \
-qa --qf "[%{RECOMMENDS}\n]" | sort -u > ${target_rootfs}/install/recommend
# Did we add more to the list?
grep -v -x -F -f ${target_rootfs}/install/recommend.list ${target_rootfs}/install/recommend > ${target_rootfs}/install/recommend.new || true
# We don't want to loop unless there is a change to the list!
loop=0
cat ${target_rootfs}/install/recommend.new | \
while read pkg ; do
# Ohh there was a new one, we'll need to loop again...
loop=1
echo "Processing $pkg..."
pkg_name=$(resolve_package $pkg ${confbase}.conf)
if [ -z "$pkg_name" ]; then
echo "Unable to find package $pkg." >> "${WORKDIR}/temp/log.do_${task}_recommend.${PID}"
continue
fi
echo "Attempting $pkg_name..." >> "${WORKDIR}/temp/log.do_{task}_recommend.${PID}"
${RPM} --predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \
--predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \
-D "_dbpath ${target_rootfs}/install" -D "`cat ${confbase}.macro`" \
-D "__dbi_txn create nofsync private" \
-U --justdb --noscripts --notriggers --noparentdirs --nolinktos --ignoresize \
$pkg_name >> "${WORKDIR}/temp/log.do_${task}_recommend.${PID}" 2>&1 || true
done
cat ${target_rootfs}/install/recommend.list ${target_rootfs}/install/recommend.new | sort -u > ${target_rootfs}/install/recommend.new.list
mv -f ${target_rootfs}/install/recommend.new.list ${target_rootfs}/install/recommend.list
rm ${target_rootfs}/install/recommend ${target_rootfs}/install/recommend.new
done
fi
# Now that we have a solution, pull out a list of what to install...
echo "Manifest: ${target_rootfs}/install/install.manifest"
${RPM} -D "_dbpath ${target_rootfs}/install" -qa --yaml \
-D "__dbi_txn create nofsync private" \
| grep -i 'Packageorigin' | cut -d : -f 2 > ${target_rootfs}/install/install_solution.manifest
# Attempt install
${RPM} --root ${target_rootfs} \
--predefine "_rpmds_sysinfo_path ${target_rootfs}/etc/rpm/sysinfo" \
--predefine "_rpmrc_platform_path ${target_rootfs}/etc/rpm/platform" \
-D "_dbpath ${rpmlibdir}" \
--noscripts --notriggers --noparentdirs --nolinktos \
-D "__dbi_txn create nofsync private" \
-Uhv ${target_rootfs}/install/install_solution.manifest
}
python write_specfile () {
import textwrap
# We need to change '-' in a version field to '+'
# This needs to be done BEFORE the mapping_rename_hook
def translate_vers(varname, d):
depends = bb.data.getVar(varname, d, True)
if depends:
depends_dict = bb.utils.explode_dep_versions(depends)
newdeps_dict = {}
for dep in depends_dict:
ver = depends_dict[dep]
if dep and ver:
if '-' in ver:
subd = read_subpkgdata_dict(dep, d)
pv = subd['PV']
reppv = pv.replace('-', '+')
ver = ver.replace(pv, reppv)
newdeps_dict[dep] = ver
depends = bb.utils.join_deps(newdeps_dict)
bb.data.setVar(varname, depends.strip(), d)
# We need to change the style the dependency from BB to RPM
# This needs to happen AFTER the mapping_rename_hook
def print_deps(variable, tag, array, d):
depends = variable
if depends:
depends_dict = bb.utils.explode_dep_versions(depends)
for dep in depends_dict:
ver = depends_dict[dep]
if dep and ver:
ver = ver.replace('(', '')
ver = ver.replace(')', '')
array.append("%s: %s %s" % (tag, dep, ver))
else:
array.append("%s: %s" % (tag, dep))
def walk_files(walkpath, target, conffiles):
import os
for rootpath, dirs, files in os.walk(walkpath):
path = rootpath.replace(walkpath, "")
for dir in dirs:
# All packages own the directories their files are in...
target.append("%dir " + path + "/" + dir)
for file in files:
if conffiles.count(path + "/" + file):
target.append("%config " + path + "/" + file)
else:
target.append(path + "/" + file)
packages = bb.data.getVar('PACKAGES', d, True)
if not packages or packages == '':
bb.debug(1, "No packages; nothing to do")
return
pkgdest = bb.data.getVar('PKGDEST', d, True)
if not pkgdest:
bb.fatal("No PKGDEST")
return
outspecfile = bb.data.getVar('OUTSPECFILE', d, True)
if not outspecfile:
bb.fatal("No OUTSPECFILE")
return
# Construct the SPEC file...
srcname = bb.data.getVar('PN', d, True)
srcsummary = (bb.data.getVar('SUMMARY', d, True) or bb.data.getVar('DESCRIPTION', d, True) or ".")
srcversion = bb.data.getVar('PV', d, True).replace('-', '+')
srcrelease = bb.data.getVar('PR', d, True)
srcepoch = (bb.data.getVar('PE', d, True) or "")
srclicense = bb.data.getVar('LICENSE', d, True)
srcsection = bb.data.getVar('SECTION', d, True)
srcmaintainer = bb.data.getVar('MAINTAINER', d, True)
srchomepage = bb.data.getVar('HOMEPAGE', d, True)
srcdescription = bb.data.getVar('DESCRIPTION', d, True) or "."
srcdepends = bb.data.getVar('DEPENDS', d, True)
srcrdepends = []
srcrrecommends = []
srcrsuggests = []
srcrprovides = []
srcrreplaces = []
srcrconflicts = []
srcrobsoletes = []
srcpreinst = []
srcpostinst = []
srcprerm = []
srcpostrm = []
spec_preamble_top = []
spec_preamble_bottom = []
spec_scriptlets_top = []
spec_scriptlets_bottom = []
spec_files_top = []
spec_files_bottom = []
for pkg in packages.split():
localdata = bb.data.createCopy(d)
root = "%s/%s" % (pkgdest, pkg)
lf = bb.utils.lockfile(root + ".lock")
bb.data.setVar('ROOT', '', localdata)
bb.data.setVar('ROOT_%s' % pkg, root, localdata)
pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1)
if not pkgname:
pkgname = pkg
bb.data.setVar('PKG', pkgname, localdata)
bb.data.setVar('OVERRIDES', pkg, localdata)
bb.data.update_data(localdata)
conffiles = (bb.data.getVar('CONFFILES', localdata, True) or "").split()
splitname = pkgname
splitsummary = (bb.data.getVar('SUMMARY', localdata, True) or bb.data.getVar('DESCRIPTION', localdata, True) or ".")
splitversion = (bb.data.getVar('PV', localdata, True) or "").replace('-', '+')
splitrelease = (bb.data.getVar('PR', localdata, True) or "")
splitepoch = (bb.data.getVar('PE', localdata, True) or "")
splitlicense = (bb.data.getVar('LICENSE', localdata, True) or "")
splitsection = (bb.data.getVar('SECTION', localdata, True) or "")
splitdescription = (bb.data.getVar('DESCRIPTION', localdata, True) or ".")
translate_vers('RDEPENDS', localdata)
translate_vers('RRECOMMENDS', localdata)
translate_vers('RSUGGESTS', localdata)
translate_vers('RPROVIDES', localdata)
translate_vers('RREPLACES', localdata)
translate_vers('RCONFLICTS', localdata)
# Map the dependencies into their final form
bb.build.exec_func("mapping_rename_hook", localdata)
splitrdepends = bb.data.getVar('RDEPENDS', localdata, True) or ""
splitrrecommends = bb.data.getVar('RRECOMMENDS', localdata, True) or ""
splitrsuggests = bb.data.getVar('RSUGGESTS', localdata, True) or ""
splitrprovides = bb.data.getVar('RPROVIDES', localdata, True) or ""
splitrreplaces = bb.data.getVar('RREPLACES', localdata, True) or ""
splitrconflicts = bb.data.getVar('RCONFLICTS', localdata, True) or ""
splitrobsoletes = []
# Gather special src/first package data
if srcname == splitname:
srcrdepends = splitrdepends
srcrrecommends = splitrrecommends
srcrsuggests = splitrsuggests
srcrprovides = splitrprovides
srcrreplaces = splitrreplaces
srcrconflicts = splitrconflicts
srcpreinst = bb.data.getVar('pkg_preinst', localdata, True)
srcpostinst = bb.data.getVar('pkg_postinst', localdata, True)
srcprerm = bb.data.getVar('pkg_prerm', localdata, True)
srcpostrm = bb.data.getVar('pkg_postrm', localdata, True)
file_list = []
walk_files(root, file_list, conffiles)
if not file_list and bb.data.getVar('ALLOW_EMPTY', localdata) != "1":
bb.note("Not creating empty RPM package for %s" % splitname)
else:
bb.note("Creating RPM package for %s" % splitname)
spec_files_top.append('%files')
if file_list:
spec_files_top.extend(file_list)
spec_files_top.append('')
bb.utils.unlockfile(lf)
continue
# Process subpackage data
spec_preamble_bottom.append('%%package -n %s' % splitname)
spec_preamble_bottom.append('Summary: %s' % splitsummary)
if srcversion != splitversion:
spec_preamble_bottom.append('Version: %s' % splitversion)
if srcrelease != splitrelease:
spec_preamble_bottom.append('Release: %s' % splitrelease)
if srcepoch != splitepoch:
spec_preamble_bottom.append('Epoch: %s' % splitepoch)
if srclicense != splitlicense:
spec_preamble_bottom.append('License: %s' % splitlicense)
spec_preamble_bottom.append('Group: %s' % splitsection)
# Replaces == Obsoletes && Provides
if splitrreplaces and splitrreplaces.strip() != "":
for dep in splitrreplaces.split(','):
if splitrprovides:
splitrprovides = splitrprovides + ", " + dep
else:
splitrprovides = dep
if splitrobsoletes:
splitrobsoletes = splitrobsoletes + ", " + dep
else:
splitrobsoletes = dep
print_deps(splitrdepends, "Requires", spec_preamble_bottom, d)
# Suggests in RPM are like recommends in Poky!
print_deps(splitrrecommends, "Suggests", spec_preamble_bottom, d)
# While there is no analog for suggests... (So call them recommends for now)
print_deps(splitrsuggests, "Recommends", spec_preamble_bottom, d)
print_deps(splitrprovides, "Provides", spec_preamble_bottom, d)
print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d)
# conflicts can not be in a provide! We will need to filter it.
if splitrconflicts:
depends_dict = bb.utils.explode_dep_versions(splitrconflicts)
newdeps_dict = {}
for dep in depends_dict:
if dep not in splitrprovides:
newdeps_dict[dep] = depends_dict[dep]
if newdeps_dict:
splitrconflicts = bb.utils.join_deps(newdeps_dict)
else:
splitrconflicts = ""
print_deps(splitrconflicts, "Conflicts", spec_preamble_bottom, d)
spec_preamble_bottom.append('')
spec_preamble_bottom.append('%%description -n %s' % splitname)
dedent_text = textwrap.dedent(splitdescription).strip()
spec_preamble_bottom.append('%s' % textwrap.fill(dedent_text, width=75))
spec_preamble_bottom.append('')
# Now process scriptlets
for script in ["preinst", "postinst", "prerm", "postrm"]:
scriptvar = bb.data.getVar('pkg_%s' % script, localdata, True)
if not scriptvar:
continue
if script == 'preinst':
spec_scriptlets_bottom.append('%%pre -n %s' % splitname)
elif script == 'postinst':
spec_scriptlets_bottom.append('%%post -n %s' % splitname)
elif script == 'prerm':
spec_scriptlets_bottom.append('%%preun -n %s' % splitname)
elif script == 'postrm':
spec_scriptlets_bottom.append('%%postun -n %s' % splitname)
spec_scriptlets_bottom.append(scriptvar)
spec_scriptlets_bottom.append('')
# Now process files
file_list = []
walk_files(root, file_list, conffiles)
if not file_list and bb.data.getVar('ALLOW_EMPTY', localdata) != "1":
bb.note("Not creating empty RPM package for %s" % splitname)
else:
bb.note("Creating RPM package for %s" % splitname)
spec_files_bottom.append('%%files -n %s' % splitname)
if file_list:
spec_files_bottom.extend(file_list)
spec_files_bottom.append('')
del localdata
bb.utils.unlockfile(lf)
spec_preamble_top.append('Summary: %s' % srcsummary)
spec_preamble_top.append('Name: %s' % srcname)
spec_preamble_top.append('Version: %s' % srcversion)
spec_preamble_top.append('Release: %s' % srcrelease)
if srcepoch and srcepoch.strip() != "":
spec_preamble_top.append('Epoch: %s' % srcepoch)
spec_preamble_top.append('License: %s' % srclicense)
spec_preamble_top.append('Group: %s' % srcsection)
spec_preamble_top.append('Packager: %s' % srcmaintainer)
spec_preamble_top.append('URL: %s' % srchomepage)
# Replaces == Obsoletes && Provides
if srcrreplaces and srcrreplaces.strip() != "":
for dep in srcrreplaces.split(','):
if srcrprovides:
srcrprovides = srcrprovides + ", " + dep
else:
srcrprovides = dep
if srcrobsoletes:
srcrobsoletes = srcrobsoletes + ", " + dep
else:
srcrobsoletes = dep
print_deps(srcdepends, "BuildRequires", spec_preamble_top, d)
print_deps(srcrdepends, "Requires", spec_preamble_top, d)
# Suggests in RPM are like recommends in Poky!
print_deps(srcrrecommends, "Suggests", spec_preamble_top, d)
# While there is no analog for suggests... (So call them recommends for now)
print_deps(srcrsuggests, "Recommends", spec_preamble_top, d)
print_deps(srcrprovides, "Provides", spec_preamble_top, d)
print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d)
# conflicts can not be in a provide! We will need to filter it.
if srcrconflicts:
depends_dict = bb.utils.explode_dep_versions(srcrconflicts)
newdeps_dict = {}
for dep in depends_dict:
if dep not in srcrprovides:
newdeps_dict[dep] = depends_dict[dep]
if newdeps_dict:
srcrconflicts = bb.utils.join_deps(newdeps_dict)
else:
srcrconflicts = ""
print_deps(srcrconflicts, "Conflicts", spec_preamble_top, d)
spec_preamble_top.append('')
spec_preamble_top.append('%description')
dedent_text = textwrap.dedent(srcdescription).strip()
spec_preamble_top.append('%s' % textwrap.fill(dedent_text, width=75))
spec_preamble_top.append('')
if srcpreinst:
spec_scriptlets_top.append('%pre')
spec_scriptlets_top.append(srcpreinst)
spec_scriptlets_top.append('')
if srcpostinst:
spec_scriptlets_top.append('%post')
spec_scriptlets_top.append(srcpostinst)
spec_scriptlets_top.append('')
if srcprerm:
spec_scriptlets_top.append('%preun')
spec_scriptlets_top.append(srcprerm)
spec_scriptlets_top.append('')
if srcpostrm:
spec_scriptlets_top.append('%postun')
spec_scriptlets_top.append(srcpostrm)
spec_scriptlets_top.append('')
# Write the SPEC file
try:
from __builtin__ import file
specfile = file(outspecfile, 'w')
except OSError:
raise bb.build.FuncFailed("unable to open spec file for writing.")
for line in spec_preamble_top:
specfile.write(line + "\n")
for line in spec_preamble_bottom:
specfile.write(line + "\n")
for line in spec_scriptlets_top:
specfile.write(line + "\n")
for line in spec_scriptlets_bottom:
specfile.write(line + "\n")
for line in spec_files_top:
specfile.write(line + "\n")
for line in spec_files_bottom:
specfile.write(line + "\n")
specfile.close()
}
python do_package_rpm () {
import os
workdir = bb.data.getVar('WORKDIR', d, True)
outdir = bb.data.getVar('DEPLOY_DIR_IPK', d, True)
tmpdir = bb.data.getVar('TMPDIR', d, True)
pkgd = bb.data.getVar('PKGD', d, True)
pkgdest = bb.data.getVar('PKGDEST', d, True)
if not workdir or not outdir or not pkgd or not tmpdir:
bb.error("Variables incorrectly set, unable to package")
return
packages = bb.data.getVar('PACKAGES', d, True)
if not packages or packages == '':
bb.debug(1, "No packages; nothing to do")
return
# Construct the spec file...
srcname = bb.data.getVar('PN', d, True)
outspecfile = workdir + "/" + srcname + ".spec"
bb.data.setVar('OUTSPECFILE', outspecfile, d)
bb.build.exec_func('write_specfile', d)
# Construct per file dependencies file
def dump_filerdeps(varname, outfile, d):
outfile.write("#!/bin/sh\n")
outfile.write("\n# Dependency table\n")
for pkg in packages.split():
dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg
dependsflist = (bb.data.getVar(dependsflist_key, d, True) or "")
for dfile in dependsflist.split():
key = "FILE" + varname + "_" + dfile + "_" + pkg
depends_dict = bb.utils.explode_dep_versions(bb.data.getVar(key, d, True) or "")
file = dfile.replace("@underscore@", "_")
file = file.replace("@closebrace@", "]")
file = file.replace("@openbrace@", "[")
file = file.replace("@tab@", "\t")
file = file.replace("@space@", " ")
file = file.replace("@at@", "@")
outfile.write("#" + pkgd + file + "\t")
for dep in depends_dict:
ver = depends_dict[dep]
if dep and ver:
ver = ver.replace("(","")
ver = ver.replace(")","")
outfile.write(dep + " " + ver + " ")
else:
outfile.write(dep + " ")
outfile.write("\n")
outfile.write("\n\nwhile read file_name ; do\n")
outfile.write("\tlength=$(echo \"#${file_name}\t\" | wc -c )\n")
outfile.write("\tline=$(grep \"^#${file_name}\t\" $0 | cut -c ${length}- )\n")
outfile.write("\tprintf \"%s\\n\" ${line}\n")
outfile.write("done\n")
# Poky dependencies a.k.a. RPM requires
outdepends = workdir + "/" + srcname + ".requires"
try:
from __builtin__ import file
dependsfile = file(outdepends, 'w')
except OSError:
raise bb.build.FuncFailed("unable to open spec file for writing.")
dump_filerdeps('RDEPENDS', dependsfile, d)
dependsfile.close()
os.chmod(outdepends, 0755)
# Poky / RPM Provides
outprovides = workdir + "/" + srcname + ".requires"
try:
from __builtin__ import file
providesfile = file(outprovides, 'w')
except OSError:
raise bb.build.FuncFailed("unable to open spec file for writing.")
dump_filerdeps('RPROVIDES', providesfile, d)
providesfile.close()
os.chmod(outprovides, 0755)
# Setup the rpmbuild arguments...
rpmbuild = bb.data.getVar('RPMBUILD', d, True)
targetsys = bb.data.getVar('TARGET_SYS', d, True)
pkgwritedir = bb.data.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH}', d)
pkgarch = bb.data.expand('${PACKAGE_ARCH}', d)
bb.mkdirhier(pkgwritedir)
os.chmod(pkgwritedir, 0755)
cmd = rpmbuild
cmd = cmd + " --nodeps --short-circuit --target " + pkgarch + "-poky-linux-gnu --buildroot " + pkgd
cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'"
cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'"
cmd = cmd + " --define '_use_internal_dependency_generator 0'"
cmd = cmd + " --define '__find_requires " + outdepends + "'"
cmd = cmd + " --define '__find_provides " + outprovides + "'"
cmd = cmd + " --define '_unpackaged_files_terminate_build 0'"
cmd = cmd + " --define 'debug_package %{nil}'"
cmd = cmd + " -bb " + outspecfile
# Build the rpm package!
bb.data.setVar('BUILDSPEC', cmd + "\n", d)
bb.data.setVarFlag('BUILDSPEC', 'func', '1', d)
bb.build.exec_func('BUILDSPEC', d)
}
python () {
if bb.data.getVar('PACKAGES', d, True) != '':
deps = (bb.data.getVarFlag('do_package_write_rpm', 'depends', d) or "").split()
deps.append('rpm-native:do_populate_sysroot')
deps.append('virtual/fakeroot-native:do_populate_sysroot')
bb.data.setVarFlag('do_package_write_rpm', 'depends', " ".join(deps), d)
bb.data.setVarFlag('do_package_write_rpm', 'fakeroot', 1, d)
bb.data.setVarFlag('do_package_write_rpm_setscene', 'fakeroot', 1, d)
}
SSTATETASKS += "do_package_write_rpm"
do_package_write_rpm[sstate-name] = "deploy-rpm"
do_package_write_rpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}"
do_package_write_rpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}"
# Take a shared lock, we can write multiple packages at the same time...
# but we need to stop the rootfs/solver from running while we do...
do_package_write_rpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock"
python do_package_write_rpm_setscene () {
sstate_setscene(d)
}
addtask do_package_write_rpm_setscene
python do_package_write_rpm () {
bb.build.exec_func("read_subpackage_metadata", d)
bb.build.exec_func("do_package_rpm", d)
}
do_package_write_rpm[dirs] = "${PKGWRITEDIRRPM}"
addtask package_write_rpm before do_package_write after do_package